[med-svn] [gnumed-server] 01/06: New upstream version 21.15

Andreas Tille tille at debian.org
Mon Nov 13 12:47:16 UTC 2017


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository gnumed-server.

commit 4fa7477690a21d938b30f2a130a015740d5e1c26
Author: Andreas Tille <tille at debian.org>
Date:   Mon Nov 13 13:01:56 2017 +0100

    New upstream version 21.15
---
 server/bootstrap/bootstrap-latest-console.log.bak  | 1097 ++++++++++++++++++++
 server/bootstrap/bootstrap-latest.conf             |    2 +
 server/bootstrap/bootstrap-latest.sh               |    6 +-
 server/bootstrap/bootstrap_gm_db_system.py         |  464 +++++----
 server/bootstrap/fixup_db-v21.conf                 |    4 +
 server/bootstrap/update_db-v20_v21.conf            |    4 +
 server/doc/schema/gnumed-entire_schema.html        |    2 +-
 server/gm-adjust_db_settings.sh                    |   15 +-
 server/pycommon/gmMimeLib.py                       |   18 +-
 server/pycommon/gmPG2.py                           |   81 +-
 server/pycommon/gmPsql.py                          |  154 ++-
 server/sql/gmAudit-dynamic.sql                     |    4 +-
 server/sql/gmI18N-dynamic.sql                      |   97 +-
 server/sql/gmI18N.sql                              |   84 --
 .../v10-v11/dynamic/v11-i18n-force_curr_lang.sql   |    4 +-
 .../dynamic/v15-clin-v_pat_substance_intake.sql    |   16 +-
 .../v15-v16/dynamic/v16-db-default_settings.sql    |    7 +-
 .../dynamic/v17-clin-v_pat_substance_intake.sql    |   16 +-
 .../sql/v16-v17/fixups/v17-blobs-doc_obj-fixup.sql |    8 +-
 .../fixups/v17-clin-v_waiting_list-fixup.sql       |    3 -
 .../dynamic/v18-i18n-fr_FR_translations.sql        |    2 +-
 .../dynamic/v18-i18n-ru_RU_translations.sql        |    2 +-
 .../dynamic/v19-clin-v_substance_intakes.sql       |   16 +-
 .../dynamic/v21-clin-v_substance_intakes.sql       |   18 +-
 .../v20-v21/dynamic/v21-release_notes-dynamic.sql  |   39 +-
 .../fixups/v21-audit-add_table_for_audit-fixup.sql |   62 ++
 .../fixups/v21-clin-v_substance_intakes-fixup.sql  |  144 +++
 .../fixups/v21-db-sql_inheritance-fixup.sql}       |   16 +-
 .../v20-v21/fixups/v21-i18n-lang_funcs-fixup.sql   |   52 +
 29 files changed, 1809 insertions(+), 628 deletions(-)

diff --git a/server/bootstrap/bootstrap-latest-console.log.bak b/server/bootstrap/bootstrap-latest-console.log.bak
new file mode 100644
index 0000000..47b1bdd
--- /dev/null
+++ b/server/bootstrap/bootstrap-latest-console.log.bak
@@ -0,0 +1,1097 @@
+Script started on 2017-10-16 22:44:21+0200
+ncq at hermes:~/Projekte/gm-git/gnumed/gnumed/server/bootstrap$ sudo ./bootstrap-latest.sh
+[sudo] Passwort für ncq: 
+===========================================================
+Bootstrapping latest GNUmed database.
+
+This will set up a GNUmed database of version v21
+with the name "gnumed_v21".
+
+------------------------------------------------
+The database "gnumed_v2" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v3" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v4" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v5" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v6" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v7" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v8" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v9" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v10" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v11" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v12" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v13" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v14" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v15" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v16" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v17" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v18" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v19" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v20" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+
+------------------------------------------------
+The database "gnumed_v21" already exists.
+Note that during bootstrapping this
+database will be OVERWRITTEN !
+
+Do you really intend to bootstrap or did you
+rather want to *upgrade* from v20 to v21 ?
+
+(For upgrading you should run the
+ upgrade script instead.)
+
+Continue bootstrapping (deletes databases) ? 
+
+[yes / NO]: yes
+Adjusting PYTHONPATH ...
+=======================================
+Bootstrapping GNUmed database system...
+=======================================
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "config" in <gnumed_v2> (or overridden) on <>
+bundle "reference" in <gnumed_v2> (or overridden) on <>
+bundle "demographics" in <gnumed_v2> (or overridden) on <>
+bundle "clinical" in <gnumed_v2> (or overridden) on <>
+bundle "documents" in <gnumed_v2> (or overridden) on <>
+bundle "office" in <gnumed_v2> (or overridden) on <>
+-------------------------------------------------------
+This will set up a monolithic GNUmed backend with all bundles
+in one database named [gnumed]. It will contain the core schema
+without country or language-specific components. Those will
+have to be added by using one of the bootstrap-XX.conf file
+where XX represents the ISO country code.
+
+Currently this file will also import the test accounts which
+MUST be removed prior to real use.
+
+==> bootstrapping "config" ...
+==> dropping pre-existing target database [gnumed_v2] ...
+==> cloning [template1] (7997 kB) as target database [gnumed_v2] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+    ... skipped (unconfigured)
+==> bootstrapping "reference" ...
+==> bootstrapping "demographics" ...
+==> bootstrapping "clinical" ...
+==> bootstrapping "documents" ...
+==> bootstrapping "office" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "demographics-de" in <gnumed_v2> (or overridden) on <>
+bundle "clinical-de" in <gnumed_v2> (or overridden) on <>
+bundle "reference-de" in <gnumed_v2> (or overridden) on <>
+bundle "Uebersetzung" in <gnumed_v2> (or overridden) on <>
+-------------------------------------------------------
+Dieses Skript installiert Daten in ein GNUmed-Datenbanksystem,
+mit denen GNUmed fuer Deutschland angepasst wird.
+
+Die Datenbankstruktur muss bereits in einer GNUmed-Datenbank
+installiert sein, ebenso muss mindestens der Nutzer gm-dbo
+bereits existieren.
+==> bootstrapping "demographics-de" ...
+==> bootstrapping "clinical-de" ...
+==> bootstrapping "reference-de" ...
+==> bootstrapping "Uebersetzung" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "demographics-es" in <gnumed_v2> (or overridden) on <>
+-------------------------------------------------------
+
+Este script instala en la base de datos de GNUmed las informaciones
+especificas para su uso en Espana (provincias).
+
+Como requisitos, el esquema debe haber sido previamente instalado
+en la base de datos "gnumed" y, al menos, el usuario "gm-dbo" debe
+haber sido creado.
+
+==> bootstrapping "demographics-es" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "demographics-ca" in <gnumed_v2> (or overridden) on <>
+-------------------------------------------------------
+This script installs data into a GNUmed database system in
+order to localise GNUmed for Canada.
+
+The core database schema must have been imported into a database
+"gnumed" already. Also, the user gm-dbo must exist.
+
+==> bootstrapping "demographics-ca" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "au-locale" in <gnumed_v2> (or overridden) on <>
+-------------------------------------------------------
+This script installs data into a GNUmed database system in
+order to localise GNUmed for Australia.
+
+The core database schema must have been imported into a database
+"gnumed" already. Also, the user gm-dbo must exist.
+
+==> bootstrapping "au-locale" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "test data" in <gnumed_v2> (or overridden) on <>
+-------------------------------------------------------
+This script installs test data into an existing GNUmed database
+named "gnumed". Also, the database owner "gm-dbo" must exist
+already.
+==> bootstrapping "test data" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v2-v3-static" in <gnumed_v3> (or overridden) on <>
+bundle "v2-v3-dynamic" in <gnumed_v3> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 2
+database to the version 3 schema. It does not do
+any harm to the data contained within.
+
+The existing database is cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v2-v3-static" ...
+==> dropping pre-existing target database [gnumed_v3] ...
+==> cloning [gnumed_v2] (21 MB) as target database [gnumed_v3] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+    ... skipped (unconfigured)
+==> bootstrapping "v2-v3-dynamic" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v3-v4-static" in <gnumed_v4> (or overridden) on <>
+bundle "v3-v4-dynamic" in <gnumed_v4> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 3
+database to the version 4 schema. It does not do
+any harm to the data contained within.
+
+The existing database is cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v3-v4-static" ...
+==> dropping pre-existing target database [gnumed_v4] ...
+==> cloning [gnumed_v3] (21 MB) as target database [gnumed_v4] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+    ... skipped (unconfigured)
+==> bootstrapping "v3-v4-dynamic" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v4-v5-static" in <gnumed_v5> (or overridden) on <>
+bundle "v4-v5-dynamic" in <gnumed_v5> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 4
+database to the version 5 schema. It does not do
+any harm to the data contained within.
+
+The existing database is cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v4-v5-static" ...
+==> dropping pre-existing target database [gnumed_v5] ...
+==> cloning [gnumed_v4] (21 MB) as target database [gnumed_v5] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+    ... skipped (unconfigured)
+==> bootstrapping "v4-v5-dynamic" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v5-v6-static" in <gnumed_v6> (or overridden) on <>
+bundle "v5-v6-dynamic" in <gnumed_v6> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 5
+database to the version 6 schema. It does not do
+any harm to the data contained within.
+
+The existing database is cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v5-v6-static" ...
+==> dropping pre-existing target database [gnumed_v6] ...
+==> cloning [gnumed_v5] (21 MB) as target database [gnumed_v6] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v5-v6-dynamic" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v6-v7-static" in <gnumed_v7> (or overridden) on <>
+bundle "v6-v7-dynamic" in <gnumed_v7> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 6
+database to the version 7 schema. It does not do
+any harm to the data contained within.
+
+The existing database is cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v6-v7-static" ...
+==> dropping pre-existing target database [gnumed_v7] ...
+==> cloning [gnumed_v6] (21 MB) as target database [gnumed_v7] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v6-v7-dynamic" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v7-v8-static" in <gnumed_v8> (or overridden) on <>
+bundle "v7-v8-dynamic" in <gnumed_v8> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 7
+database to the version 8 schema. It does not do
+any harm to the data contained within.
+
+The existing database is cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v7-v8-static" ...
+==> dropping pre-existing target database [gnumed_v8] ...
+==> cloning [gnumed_v7] (21 MB) as target database [gnumed_v8] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v7-v8-dynamic" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v8-v9-static" in <gnumed_v9> (or overridden) on <>
+bundle "v8-v9-dynamic" in <gnumed_v9> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 8
+database to the version 9 schema. It does not do
+any harm to the data contained within.
+
+The existing database is cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v8-v9-static" ...
+==> dropping pre-existing target database [gnumed_v9] ...
+==> cloning [gnumed_v8] (22 MB) as target database [gnumed_v9] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v8-v9-dynamic" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v9-v10-static" in <gnumed_v10> (or overridden) on <>
+bundle "v9-v10-dynamic" in <gnumed_v10> (or overridden) on <>
+bundle "v10-fixups" in <gnumed_v10> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 9
+database to the version 10 schema. It does not do
+any harm to the data contained within.
+
+The existing database is cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v9-v10-static" ...
+==> dropping pre-existing target database [gnumed_v10] ...
+==> cloning [gnumed_v9] (22 MB) as target database [gnumed_v10] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v9-v10-dynamic" ...
+==> bootstrapping "v10-fixups" ...
+==> setting up auditing ...
+    ... skipped (disabled)
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v10_fixups-pre_v11" in <gnumed_v11> (or overridden) on <>
+bundle "v10-v11-static" in <gnumed_v11> (or overridden) on <>
+bundle "v10-v11-dynamic" in <gnumed_v11> (or overridden) on <>
+bundle "v11-fixups" in <gnumed_v11> (or overridden) on <>
+bundle "v11-test_data" in <gnumed_v11> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 10
+database to the version 11 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v10_fixups-pre_v11" ...
+==> dropping pre-existing target database [gnumed_v11] ...
+==> cloning [gnumed_v10] (23 MB) as target database [gnumed_v11] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v10-v11-static" ...
+==> bootstrapping "v10-v11-dynamic" ...
+==> bootstrapping "v11-fixups" ...
+==> bootstrapping "v11-test_data" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+    ... skipped (no scripts to run)
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v11_fixups-pre_v12" in <gnumed_v12> (or overridden) on <>
+bundle "v11-v12-static" in <gnumed_v12> (or overridden) on <>
+bundle "v11-v12-dynamic" in <gnumed_v12> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 11
+database to the version 12 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v11_fixups-pre_v12" ...
+==> dropping pre-existing target database [gnumed_v12] ...
+==> cloning [gnumed_v11] (24 MB) as target database [gnumed_v12] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v11-v12-static" ...
+==> bootstrapping "v11-v12-dynamic" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v12-v13-static" in <gnumed_v13> (or overridden) on <>
+bundle "v12-v13-dynamic" in <gnumed_v13> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 12
+database to the version 13 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v12-v13-static" ...
+==> dropping pre-existing target database [gnumed_v13] ...
+==> cloning [gnumed_v12] (25 MB) as target database [gnumed_v13] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v12-v13-dynamic" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "pg_8.3_v14-pre_conversion_fixups" in <gnumed_v14> (or overridden) on <>
+bundle "v13-v14-static" in <gnumed_v14> (or overridden) on <>
+bundle "v13-v14-dynamic" in <gnumed_v14> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 13
+database to the version 14 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "pg_8.3_v14-pre_conversion_fixups" ...
+==> dropping pre-existing target database [gnumed_v14] ...
+==> cloning [gnumed_v13] (36 MB) as target database [gnumed_v14] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v13-v14-static" ...
+==> bootstrapping "v13-v14-dynamic" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v14-v15-static" in <gnumed_v15> (or overridden) on <>
+bundle "v14-v15-dynamic" in <gnumed_v15> (or overridden) on <>
+bundle "v15-fixups" in <gnumed_v15> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 14
+database to the version 15 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v14-v15-static" ...
+==> dropping pre-existing target database [gnumed_v15] ...
+==> cloning [gnumed_v14] (37 MB) as target database [gnumed_v15] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v14-v15-dynamic" ...
+==> bootstrapping "v15-fixups" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v15_fixups-pre_v16" in <gnumed_v16> (or overridden) on <>
+bundle "v15-v16-static" in <gnumed_v16> (or overridden) on <>
+bundle "v15-v16-dynamic" in <gnumed_v16> (or overridden) on <>
+bundle "v16-fixups" in <gnumed_v16> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 15
+database to the version 16 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v15_fixups-pre_v16" ...
+==> dropping pre-existing target database [gnumed_v16] ...
+==> cloning [gnumed_v15] (41 MB) as target database [gnumed_v16] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v15-v16-static" ...
+==> bootstrapping "v15-v16-dynamic" ...
+==> bootstrapping "v16-fixups" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v16_fixups-pre_v17" in <gnumed_v17> (or overridden) on <>
+bundle "v16-v17-static" in <gnumed_v17> (or overridden) on <>
+bundle "v16-v17-dynamic" in <gnumed_v17> (or overridden) on <>
+bundle "v17-fixups" in <gnumed_v17> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 16
+database to the version 17 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v16_fixups-pre_v17" ...
+==> dropping pre-existing target database [gnumed_v17] ...
+==> cloning [gnumed_v16] (44 MB) as target database [gnumed_v17] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v16-v17-static" ...
+==> bootstrapping "v16-v17-dynamic" ...
+==> bootstrapping "v17-fixups" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v17_fixups-pre_v18" in <gnumed_v18> (or overridden) on <>
+bundle "v17-v18-static" in <gnumed_v18> (or overridden) on <>
+bundle "v17-v18-dynamic" in <gnumed_v18> (or overridden) on <>
+bundle "v18-fixups" in <gnumed_v18> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 17
+database to the version 18 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v17_fixups-pre_v18" ...
+==> dropping pre-existing target database [gnumed_v18] ...
+==> cloning [gnumed_v17] (45 MB) as target database [gnumed_v18] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v17-v18-static" ...
+==> bootstrapping "v17-v18-dynamic" ...
+==> bootstrapping "v18-fixups" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> upgrading reference data sets ...
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v18_fixups-pre_v19" in <gnumed_v19> (or overridden) on <>
+bundle "v18-v19-static" in <gnumed_v19> (or overridden) on <>
+bundle "v18-v19-dynamic" in <gnumed_v19> (or overridden) on <>
+bundle "v19-fixups" in <gnumed_v19> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 18
+database to the version 19 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+
+************************************************************
+* Before upgrading your existing v18 database to the       *
+* v19 schema it is very advisable to make sure you         *
+* have created - using the 1.3 client against the v18      *
+* database -- an organization and a unit thereof to        *
+* serve as your praxis and praxis location. During the     *
+* very first start of the 1.4 client you will be asked     *
+* which organization/unit represents your praxis/location. *
+************************************************************
+
+==> bootstrapping "v18_fixups-pre_v19" ...
+==> dropping pre-existing target database [gnumed_v19] ...
+==> cloning [gnumed_v18] (52 MB) as target database [gnumed_v19] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v18-v19-static" ...
+==> bootstrapping "v18-v19-dynamic" ...
+==> bootstrapping "v19-fixups" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> setting up generic notifications ...
+==> upgrading reference data sets ...
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v19_fixups-pre_v20" in <gnumed_v20> (or overridden) on <>
+bundle "v19-v20-static" in <gnumed_v20> (or overridden) on <>
+bundle "v19-v20-dynamic" in <gnumed_v20> (or overridden) on <>
+bundle "v20-fixups" in <gnumed_v20> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 19
+database to the version 20 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v19_fixups-pre_v20" ...
+==> dropping pre-existing target database [gnumed_v20] ...
+==> cloning [gnumed_v19] (68 MB) as target database [gnumed_v20] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v19-v20-static" ...
+==> bootstrapping "v19-v20-dynamic" ...
+==> bootstrapping "v20-fixups" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> setting up encounter/episode FK sanity check triggers ...
+==> setting up generic notifications ...
+==> upgrading reference data sets ...
+You are about to install the following parts of GNUmed:
+-------------------------------------------------------
+bundle "v20_fixups-pre_v21" in <gnumed_v21> (or overridden) on <>
+bundle "v20-v21-static" in <gnumed_v21> (or overridden) on <>
+bundle "v20-v21-dynamic" in <gnumed_v21> (or overridden) on <>
+bundle "v21-fixups" in <gnumed_v21> (or overridden) on <>
+-------------------------------------------------------
+This will update an existing GNUmed version 20
+database to the version 21 schema. It does not do
+any harm to the data contained within.
+
+The existing database will be cloned first. The copy is
+then modified. The original database remains unchanged.
+==> bootstrapping "v20_fixups-pre_v21" ...
+==> dropping pre-existing target database [gnumed_v21] ...
+==> cloning [gnumed_v20] (69 MB) as target database [gnumed_v21] ...
+==> reindexing target database (can take a while) ...
+==> transferring users ...
+==> bootstrapping "v20-v21-static" ...
+==> bootstrapping "v20-v21-dynamic" ...
+==> bootstrapping "v21-fixups" ...
+==> setting up auditing ...
+==> setting up encounter/episode FKs and IDXs ...
+==> setting up encounter/episode FK sanity check triggers ...
+==> setting up generic notifications ...
+==> upgrading reference data sets ...
+==> verifying target database schema ...
+==> checking migrated data for plausibility ...
+Done bootstrapping GNUmed database: We very likely succeeded.
+log: /home/ncq/Projekte/gm-git/gnumed/gnumed/server/bootstrap/bootstrap-latest.log
+*** Error in `python': free(): invalid pointer: 0x00770b14 ***
+======= Backtrace: =========
+/lib/i386-linux-gnu/libc.so.6(+0x6738a)[0xb7ccc38a]
+/lib/i386-linux-gnu/libc.so.6(+0x6dfc7)[0xb7cd2fc7]
+/lib/i386-linux-gnu/libc.so.6(+0x6e806)[0xb7cd3806]
+python(PyObject_Free+0xfb)[0x44affb]
+python(+0x110b51)[0x534b51]
+python(+0x110b51)[0x534b51]
+python(+0x110b51)[0x534b51]
+python(+0xf3ea7)[0x517ea7]
+python(PyDict_SetItem+0x201)[0x4d4f81]
+python(_PyModule_Clear+0x150)[0x539630]
+python(PyImport_Cleanup+0x61d)[0x53927d]
+python(Py_Finalize+0x9d)[0x53635d]
+python(Py_Exit+0x14)[0x55cb24]
+python(+0x136102)[0x55a102]
+python(PyErr_PrintEx+0x35)[0x559975]
+python(+0x3dd41)[0x461d41]
+python(Py_Main+0x753)[0x4d2c83]
+python(main+0x1b)[0x4d251b]
+/lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf6)[0xb7c7d286]
+python(+0xae3f3)[0x4d23f3]
+======= Memory map: ========
+00424000-00763000 r-xp 00000000 08:01 6285092    /usr/bin/python2.7
+00763000-00764000 r--p 0033e000 08:01 6285092    /usr/bin/python2.7
+00764000-007c4000 rw-p 0033f000 08:01 6285092    /usr/bin/python2.7
+007c4000-007d9000 rw-p 00000000 00:00 0 
+026f1000-02921000 rw-p 00000000 00:00 0          [heap]
+b6800000-b6821000 rw-p 00000000 00:00 0 
+b6821000-b6900000 ---p 00000000 00:00 0 
+b6995000-b69b0000 r-xp 00000000 08:01 8151085    /lib/i386-linux-gnu/libgcc_s.so.1
+b69b0000-b69b1000 r--p 0001a000 08:01 8151085    /lib/i386-linux-gnu/libgcc_s.so.1
+b69b1000-b69b2000 rw-p 0001b000 08:01 8151085    /lib/i386-linux-gnu/libgcc_s.so.1
+b69f5000-b6b35000 rw-p 00000000 00:00 0 
+b6b35000-b6b40000 r-xp 00000000 08:01 8151337    /lib/i386-linux-gnu/libnss_files-2.24.so
+b6b40000-b6b41000 r--p 0000a000 08:01 8151337    /lib/i386-linux-gnu/libnss_files-2.24.so
+b6b41000-b6b42000 rw-p 0000b000 08:01 8151337    /lib/i386-linux-gnu/libnss_files-2.24.so
+b6b42000-b6b48000 rw-p 00000000 00:00 0 
+b6b48000-b6b53000 r-xp 00000000 08:01 8151339    /lib/i386-linux-gnu/libnss_nis-2.24.so
+b6b53000-b6b54000 r--p 0000a000 08:01 8151339    /lib/i386-linux-gnu/libnss_nis-2.24.so
+b6b54000-b6b55000 rw-p 0000b000 08:01 8151339    /lib/i386-linux-gnu/libnss_nis-2.24.so
+b6b64000-b6b6b000 r--p 00000000 08:01 6286752    /usr/share/locale/de/LC_MESSAGES/libpq5-10.mo
+b6b6b000-b6b72000 r--s 00000000 08:01 6903281    /usr/lib/i386-linux-gnu/gconv/gconv-modules.cache
+b6b72000-b6b98000 r--p 00000000 08:01 6288754    /usr/share/locale/de/LC_MESSAGES/libc.mo
+b6b98000-b6c98000 rw-p 00000000 00:00 0 
+b6c9e000-b6cb4000 r-xp 00000000 08:01 8151334    /lib/i386-linux-gnu/libnsl-2.24.so
+b6cb4000-b6cb5000 r--p 00016000 08:01 8151334    /lib/i386-linux-gnu/libnsl-2.24.so
+b6cb5000-b6cb6000 rw-p 00017000 08:01 8151334    /lib/i386-linux-gnu/libnsl-2.24.so
+b6cb6000-b6cb8000 rw-p 00000000 00:00 0 
+b6cb8000-b6cc0000 r-xp 00000000 08:01 8151335    /lib/i386-linux-gnu/libnss_compat-2.24.so
+b6cc0000-b6cc1000 r--p 00007000 08:01 8151335    /lib/i386-linux-gnu/libnss_compat-2.24.so
+b6cc1000-b6cc2000 rw-p 00008000 08:01 8151335    /lib/i386-linux-gnu/libnss_compat-2.24.so
+b6cc2000-b6d02000 rw-p 00000000 00:00 0 
+b6d02000-b6d09000 r-xp 00000000 08:01 6899491    /usr/lib/i386-linux-gnu/libffi.so.6.0.4
+b6d09000-b6d0a000 r--p 00006000 08:01 6899491    /usr/lib/i386-linux-gnu/libffi.so.6.0.4
+b6d0a000-b6d0b000 rw-p 00007000 08:01 6899491    /usr/lib/i386-linux-gnu/libffi.so.6.0.4
+b6d0b000-b6d96000 r-xp 00000000 08:01 6899509    /usr/lib/i386-linux-gnu/libgmp.so.10.3.2
+b6d96000-b6d97000 r--p 0008a000 08:01 6899509    /usr/lib/i386-linux-gnu/libgmp.so.10.3.2
+b6d97000-b6d98000 rw-p 0008b000 08:01 6899509    /usr/lib/i386-linux-gnu/libgmp.so.10.3.2
+b6d98000-b6dcc000 r-xp 00000000 08:01 6899139    /usr/lib/i386-linux-gnu/libhogweed.so.4.3
+b6dcc000-b6dcd000 r--p 00033000 08:01 6899139    /usr/lib/i386-linux-gnu/libhogweed.so.4.3
+b6dcd000-b6dce000 rw-p 00034000 08:01 6899139    /usr/lib/i386-linux-gnu/libhogweed.so.4.3
+b6dce000-b6e08000 r-xp 00000000 08:01 6897991    /usr/lib/i386-linux-gnu/libnettle.so.6.3
+b6e08000-b6e09000 ---p 0003a000 08:01 6897991    /usr/lib/i386-linux-gnu/libnettle.so.6.3
+b6e09000-b6e0a000 r--p 0003a000 08:01 6897991    /usr/lib/i386-linux-gnu/libnettle.so.6.3
+b6e0a000-b6e0b000 rw-p 0003b000 08:01 6897991    /usr/lib/i386-linux-gnu/libnettle.so.6.3
+b6e0b000-b6e1e000 r-xp 00000000 08:01 6898338    /usr/lib/i386-linux-gnu/libtasn1.so.6.5.4
+b6e1e000-b6e1f000 r--p 00012000 08:01 6898338    /usr/lib/i386-linux-gnu/libtasn1.so.6.5.4
+b6e1f000-b6e20000 rw-p 00013000 08:01 6898338    /usr/lib/i386-linux-gnu/libtasn1.so.6.5.4
+b6e20000-b6f8c000 r-xp 00000000 08:01 6899693    /usr/lib/i386-linux-gnu/libunistring.so.2.0.0
+b6f8c000-b6f8d000 ---p 0016c000 08:01 6899693    /usr/lib/i386-linux-gnu/libunistring.so.2.0.0
+b6f8d000-b6f8f000 r--p 0016c000 08:01 6899693    /usr/lib/i386-linux-gnu/libunistring.so.2.0.0
+b6f8f000-b6f90000 rw-p 0016e000 08:01 6899693    /usr/lib/i386-linux-gnu/libunistring.so.2.0.0
+b6f90000-b6fac000 r-xp 00000000 08:01 6899147    /usr/lib/i386-linux-gnu/libidn2.so.0.3.1
+b6fac000-b6fad000 r--p 0001b000 08:01 6899147    /usr/lib/i386-linux-gnu/libidn2.so.0.3.1
+b6fad000-b6fae000 rw-p 0001c000 08:01 6899147    /usr/lib/i386-linux-gnu/libidn2.so.0.3.1
+b6fae000-b70fe000 r-xp 00000000 08:01 6899036    /usr/lib/i386-linux-gnu/libp11-kit.so.0.3.0
+b70fe000-b7104000 r--p 0014f000 08:01 6899036    /usr/lib/i386-linux-gnu/libp11-kit.so.0.3.0
+b7104000-b7109000 rw-p 00155000 08:01 6899036    /usr/lib/i386-linux-gnu/libp11-kit.so.0.3.0
+b7109000-b710a000 rw-p 00000000 00:00 0 
+b710a000-b7299000 r-xp 00000000 08:01 6898093    /usr/lib/i386-linux-gnu/libgnutls.so.30.14.7
+b7299000-b72a1000 r--p 0018e000 08:01 6898093    /usr/lib/i386-linux-gnu/libgnutls.so.30.14.7
+b72a1000-b72a2000 rw-p 00196000 08:01 6898093    /usr/lib/i386-linux-gnu/libgnutls.so.30.14.7
+b72a2000-b72a3000 rw-p 00000000 00:00 0 
+b72a3000-b72bf000 r-xp 00000000 08:01 6897853    /usr/lib/i386-linux-gnu/libsasl2.so.2.0.25
+b72bf000-b72c0000 r--p 0001b000 08:01 6897853    /usr/lib/i386-linux-gnu/libsasl2.so.2.0.25
+b72c0000-b72c1000 rw-p 0001c000 08:01 6897853    /usr/lib/i386-linux-gnu/libsasl2.so.2.0.25
+b72c1000-b72d5000 r-xp 00000000 08:01 8151343    /lib/i386-linux-gnu/libresolv-2.24.so
+b72d5000-b72d6000 r--p 00013000 08:01 8151343    /lib/i386-linux-gnu/libresolv-2.24.so
+b72d6000-b72d7000 rw-p 00014000 08:01 8151343    /lib/i386-linux-gnu/libresolv-2.24.so
+b72d7000-b72d9000 rw-p 00000000 00:00 0 
+b72d9000-b730b000 r-xp 00000000 08:01 6898091    /usr/lib/i386-linux-gnu/libk5crypto.so.3.1
+b730b000-b730c000 ---p 00032000 08:01 6898091    /usr/lib/i386-linux-gnu/libk5crypto.so.3.1
+b730c000-b730d000 r--p 00032000 08:01 6898091    /usr/lib/i386-linux-gnu/libk5crypto.so.3.1
+b730d000-b730e000 rw-p 00033000 08:01 6898091    /usr/lib/i386-linux-gnu/libk5crypto.so.3.1
+b730e000-b730f000 rw-p 00000000 00:00 0 
+b730f000-b73e2000 r-xp 00000000 08:01 6898964    /usr/lib/i386-linux-gnu/libkrb5.so.3.3
+b73e2000-b73e3000 ---p 000d3000 08:01 6898964    /usr/lib/i386-linux-gnu/libkrb5.so.3.3
+b73e3000-b73e9000 r--p 000d3000 08:01 6898964    /usr/lib/i386-linux-gnu/libkrb5.so.3.3
+b73e9000-b73eb000 rw-p 000d9000 08:01 6898964    /usr/lib/i386-linux-gnu/libkrb5.so.3.3
+b73eb000-b7441000 r-xp 00000000 08:01 6899719    /usr/lib/i386-linux-gnu/libldap_r-2.4.so.2.10.8
+b7441000-b7442000 ---p 00056000 08:01 6899719    /usr/lib/i386-linux-gnu/libldap_r-2.4.so.2.10.8
+b7442000-b7443000 r--p 00056000 08:01 6899719    /usr/lib/i386-linux-gnu/libldap_r-2.4.so.2.10.8
+b7443000-b7444000 rw-p 00057000 08:01 6899719    /usr/lib/i386-linux-gnu/libldap_r-2.4.so.2.10.8
+b7444000-b7445000 rw-p 00000000 00:00 0 
+b7445000-b7495000 r-xp 00000000 08:01 6898215    /usr/lib/i386-linux-gnu/libgssapi_krb5.so.2.2
+b7495000-b7496000 r--p 0004f000 08:01 6898215    /usr/lib/i386-linux-gnu/libgssapi_krb5.so.2.2
+b7496000-b7497000 rw-p 00050000 08:01 6898215    /usr/lib/i386-linux-gnu/libgssapi_krb5.so.2.2
+b7497000-b74e1000 r-xp 00000000 08:01 6899474    /usr/lib/i386-linux-gnu/libpq.so.5.10
+b74e1000-b74e3000 r--p 00049000 08:01 6899474    /usr/lib/i386-linux-gnu/libpq.so.5.10
+b74e3000-b74e4000 rw-p 0004b000 08:01 6899474    /usr/lib/i386-linux-gnu/libpq.so.5.10
+b74e8000-b74ed000 r-xp 00000000 08:01 6365428    /usr/lib/python2.7/dist-packages/faulthandler.i386-linux-gnu.so
+b74ed000-b74ee000 r--p 00004000 08:01 6365428    /usr/lib/python2.7/dist-packages/faulthandler.i386-linux-gnu.so
+b74ee000-b74ef000 rw-p 00005000 08:01 6365428    /usr/lib/python2.7/dist-packages/faulthandler.i386-linux-gnu.so
+b74ef000-b74f6000 r-xp 00000000 08:01 6367548    /usr/lib/python2.7/lib-dynload/_csv.i386-linux-gnu.so
+b74f6000-b74f7000 r--p 00006000 08:01 6367548    /usr/lib/python2.7/lib-dynload/_csv.i386-linux-gnu.so
+b74f7000-b74f9000 rw-p 00007000 08:01 6367548    /usr/lib/python2.7/lib-dynload/_csv.i386-linux-gnu.so
+b74f9000-b750c000 r-xp 00000000 08:01 6367559    /usr/lib/python2.7/lib-dynload/_json.i386-linux-gnu.so
+b750c000-b750d000 r--p 00012000 08:01 6367559    /usr/lib/python2.7/lib-dynload/_json.i386-linux-gnu.so
+b750d000-b750e000 rw-p 00013000 08:01 6367559    /usr/lib/python2.7/lib-dynload/_json.i386-linux-gnu.so
+b750e000-b7523000 r-xp 00000000 08:01 6367569    /usr/lib/python2.7/lib-dynload/_ssl.i386-linux-gnu.so
+b7523000-b7524000 r--p 00014000 08:01 6367569    /usr/lib/python2.7/lib-dynload/_ssl.i386-linux-gnu.so
+b7524000-b7527000 rw-p 00015000 08:01 6367569    /usr/lib/python2.7/lib-dynload/_ssl.i386-linux-gnu.so
+b7527000-b7559000 r-xp 00000000 08:01 6479968    /usr/lib/python2.7/dist-packages/psycopg2/_psycopg.i386-linux-gnu.so
+b7559000-b755a000 r--p 00031000 08:01 6479968    /usr/lib/python2.7/dist-packages/psycopg2/_psycopg.i386-linux-gnu.so
+b755a000-b755e000 rw-p 00032000 08:01 6479968    /usr/lib/python2.7/dist-packages/psycopg2/_psycopg.i386-linux-gnu.so
+b755e000-b756e000 r-xp 00000000 08:01 8151113    /lib/i386-linux-gnu/libbz2.so.1.0.4
+b756e000-b756f000 r--p 0000f000 08:01 8151113    /lib/i386-linux-gnu/libbz2.so.1.0.4
+b756f000-b7570000 rw-p 00010000 08:01 8151113    /lib/i386-linux-gnu/libbz2.so.1.0.4
+b7576000-b7584000 r-xp 00000000 08:01 6897979    /usr/lib/i386-linux-gnu/liblber-2.4.so.2.10.8
+b7584000-b7585000 r--p 0000d000 08:01 6897979    /usr/lib/i386-linux-gnu/liblber-2.4.so.2.10.8
+b7585000-b7586000 rw-p 0000e000 08:01 6897979    /usr/lib/i386-linux-gnu/liblber-2.4.so.2.10.8
+b7586000-b7589000 r-xp 00000000 08:01 8151178    /lib/i386-linux-gnu/libkeyutils.so.1.5
+b7589000-b758a000 r--p 00002000 08:01 8151178    /lib/i386-linux-gnu/libkeyutils.so.1.5
+b758a000-b758b000 rw-p 00003000 08:01 8151178    /lib/i386-linux-gnu/libkeyutils.so.1.5
+b758b000-b7596000 r-xp 00000000 08:01 6899192    /usr/lib/i386-linux-gnu/libkrb5support.so.0.1
+b7596000-b7597000 r--p 0000a000 08:01 6899192    /usr/lib/i386-linux-gnu/libkrb5support.so.0.1
+b7597000-b7598000 rw-p 0000b000 08:01 6899192    /usr/lib/i386-linux-gnu/libkrb5support.so.0.1
+b7598000-b759f000 r-xp 00000000 08:01 8151344    /lib/i386-linux-gnu/librt-2.24.so
+b759f000-b75a0000 r--p 00006000 08:01 8151344    /lib/i386-linux-gnu/librt-2.24.so
+b75a0000-b75a1000 rw-p 00007000 08:01 8151344    /lib/i386-linux-gnu/librt-2.24.so
+b75a1000-b75b1000 r-xp 00000000 08:01 6570027    /usr/lib/python2.7/dist-packages/mx/DateTime/mxDateTime/mxDateTime.so
+b75b1000-b75b2000 r--p 0000f000 08:01 6570027    /usr/lib/python2.7/dist-packages/mx/DateTime/mxDateTime/mxDateTime.so
+b75b2000-b75b3000 rw-p 00010000 08:01 6570027    /usr/lib/python2.7/dist-packages/mx/DateTime/mxDateTime/mxDateTime.so
+b75b3000-b77fe000 r-xp 00000000 08:01 6897994    /usr/lib/i386-linux-gnu/libcrypto.so.1.1
+b77fe000-b77ff000 ---p 0024b000 08:01 6897994    /usr/lib/i386-linux-gnu/libcrypto.so.1.1
+b77ff000-b7810000 r--p 0024b000 08:01 6897994    /usr/lib/i386-linux-gnu/libcrypto.so.1.1
+b7810000-b7817000 rw-p 0025c000 08:01 6897994    /usr/lib/i386-linux-gnu/libcrypto.so.1.1
+b7817000-b781a000 rw-p 00000000 00:00 0 
+b781a000-b7881000 r-xp 00000000 08:01 6899137    /usr/lib/i386-linux-gnu/libssl.so.1.1
+b7881000-b7884000 r--p 00066000 08:01 6899137    /usr/lib/i386-linux-gnu/libssl.so.1.1
+b7884000-b7888000 rw-p 00069000 08:01 6899137    /usr/lib/i386-linux-gnu/libssl.so.1.1
+b7888000-b7988000 rw-p 00000000 00:00 0 
+b798a000-b798d000 r-xp 00000000 08:01 8151240    /lib/i386-linux-gnu/libcom_err.so.2.1
+b798d000-b798e000 r--p 00002000 08:01 8151240    /lib/i386-linux-gnu/libcom_err.so.2.1
+b798e000-b798f000 rw-p 00003000 08:01 8151240    /lib/i386-linux-gnu/libcom_err.so.2.1
+b798f000-b7998000 r-xp 00000000 08:01 6367575    /usr/lib/python2.7/lib-dynload/bz2.i386-linux-gnu.so
+b7998000-b7999000 r--p 00008000 08:01 6367575    /usr/lib/python2.7/lib-dynload/bz2.i386-linux-gnu.so
+b7999000-b799b000 rw-p 00009000 08:01 6367575    /usr/lib/python2.7/lib-dynload/bz2.i386-linux-gnu.so
+b799b000-b79fc000 rw-p 00000000 00:00 0 
+b79fc000-b7a00000 r-xp 00000000 08:01 6367555    /usr/lib/python2.7/lib-dynload/_hashlib.i386-linux-gnu.so
+b7a00000-b7a01000 r--p 00003000 08:01 6367555    /usr/lib/python2.7/lib-dynload/_hashlib.i386-linux-gnu.so
+b7a01000-b7a02000 rw-p 00004000 08:01 6367555    /usr/lib/python2.7/lib-dynload/_hashlib.i386-linux-gnu.so
+b7a02000-b7a05000 r-xp 00000000 08:01 6367622    /usr/lib/python2.7/lib-dynload/termios.i386-linux-gnu.so
+b7a05000-b7a06000 r--p 00002000 08:01 6367622    /usr/lib/python2.7/lib-dynload/termios.i386-linux-gnu.so
+b7a06000-b7a08000 rw-p 00003000 08:01 6367622    /usr/lib/python2.7/lib-dynload/termios.i386-linux-gnu.so
+b7a08000-b7a48000 rw-p 00000000 00:00 0 
+b7a48000-b7be3000 r--p 00000000 08:01 6299936    /usr/lib/locale/locale-archive
+b7be3000-b7c65000 rw-p 00000000 00:00 0 
+b7c65000-b7e16000 r-xp 00000000 08:01 8151265    /lib/i386-linux-gnu/libc-2.24.so
+b7e16000-b7e18000 r--p 001b0000 08:01 8151265    /lib/i386-linux-gnu/libc-2.24.so
+b7e18000-b7e19000 rw-p 001b2000 08:01 8151265    /lib/i386-linux-gnu/libc-2.24.so
+b7e19000-b7e1c000 rw-p 00000000 00:00 0 
+b7e1c000-b7e6f000 r-xp 00000000 08:01 8151332    /lib/i386-linux-gnu/libm-2.24.so
+b7e6f000-b7e70000 r--p 00052000 08:01 8151332    /lib/i386-linux-gnu/libm-2.24.so
+b7e70000-b7e71000 rw-p 00053000 08:01 8151332    /lib/i386-linux-gnu/libm-2.24.so
+b7e71000-b7e8a000 r-xp 00000000 08:01 8151148    /lib/i386-linux-gnu/libz.so.1.2.8
+b7e8a000-b7e8b000 r--p 00018000 08:01 8151148    /lib/i386-linux-gnu/libz.so.1.2.8
+b7e8b000-b7e8c000 rw-p 00019000 08:01 8151148    /lib/i386-linux-gnu/libz.so.1.2.8
+b7e8c000-b7e8e000 r-xp 00000000 08:01 8151355    /lib/i386-linux-gnu/libutil-2.24.so
+b7e8e000-b7e8f000 r--p 00001000 08:01 8151355    /lib/i386-linux-gnu/libutil-2.24.so
+b7e8f000-b7e90000 rw-p 00002000 08:01 8151355    /lib/i386-linux-gnu/libutil-2.24.so
+b7e90000-b7e93000 r-xp 00000000 08:01 8151331    /lib/i386-linux-gnu/libdl-2.24.so
+b7e93000-b7e94000 r--p 00002000 08:01 8151331    /lib/i386-linux-gnu/libdl-2.24.so
+b7e94000-b7e95000 rw-p 00003000 08:01 8151331    /lib/i386-linux-gnu/libdl-2.24.so
+b7e95000-b7eae000 r-xp 00000000 08:01 8151342    /lib/i386-linux-gnu/libpthread-2.24.so
+b7eae000-b7eaf000 r--p 00018000 08:01 8151342    /lib/i386-linux-gnu/libpthread-2.24.so
+b7eaf000-b7eb0000 rw-p 00019000 08:01 8151342    /lib/i386-linux-gnu/libpthread-2.24.so
+b7eb0000-b7eb2000 rw-p 00000000 00:00 0 
+b7eb4000-b7ef8000 rw-p 00000000 00:00 0 
+b7ef8000-b7efb000 r--p 00000000 00:00 0          [vvar]
+b7efb000-b7efd000 r-xp 00000000 00:00 0          [vdso]
+b7efd000-b7f20000 r-xp 00000000 08:01 8151050    /lib/i386-linux-gnu/ld-2.24.so
+b7f20000-b7f21000 r--p 00022000 08:01 8151050    /lib/i386-linux-gnu/ld-2.24.so
+b7f21000-b7f22000 rw-p 00023000 08:01 8151050    /lib/i386-linux-gnu/ld-2.24.so
+bf9f5000-bfa16000 rw-p 00000000 00:00 0          [stack]
+Fatal Python error: Aborted
+
+Current thread 0xb7c63d00 (most recent call first):
+./bootstrap-latest.sh: Zeile 80: 20984 Abgebrochen             ./bootstrap_gm_db_system.py --log-file=${LOG} --conf-file=${CONF} --${QUIET}
+Bootstrapping "gnumed_v21" did not finish successfully (134). Aborting.
+
+Sie haben neue Post in /var/mail/ncq.
+ncq at hermes:~/Projekte/gm-git/gnumed/gnumed/server/bootstrap$ exit
+exit
+
+Script done on 2017-10-16 23:18:46+0200
diff --git a/server/bootstrap/bootstrap-latest.conf b/server/bootstrap/bootstrap-latest.conf
index bb67fd8..add6a2a 100644
--- a/server/bootstrap/bootstrap-latest.conf
+++ b/server/bootstrap/bootstrap-latest.conf
@@ -39,3 +39,5 @@ update_db-v18_v19.conf
 update_db-v19_v20.conf
 update_db-v20_v21.conf
 $config files$
+
+interactive = no
diff --git a/server/bootstrap/bootstrap-latest.sh b/server/bootstrap/bootstrap-latest.sh
index 17dead7..fefea96 100755
--- a/server/bootstrap/bootstrap-latest.sh
+++ b/server/bootstrap/bootstrap-latest.sh
@@ -78,8 +78,10 @@ done
 LOG="${GM_LOG_BASE}/bootstrap-latest.log"
 CONF="bootstrap-latest.conf"
 ./bootstrap_gm_db_system.py --log-file=${LOG} --conf-file=${CONF} --${QUIET}
-if test "$?" != "0" ; then
-	echo "Bootstrapping \"gnumed_v${VER}\" did not finish successfully. Aborting."
+#gdb --args /usr/bin/python2.7-dbg ./bootstrap_gm_db_system.py --log-file=${LOG} --conf-file=${CONF} --${QUIET}
+RESULT="$?"
+if test "${RESULT}" != "0" ; then
+	echo "Bootstrapping \"gnumed_v${VER}\" did not finish successfully (${RESULT}). Aborting."
 	read
 	exit 1
 fi
diff --git a/server/bootstrap/bootstrap_gm_db_system.py b/server/bootstrap/bootstrap_gm_db_system.py
index a67a1c0..f018675 100755
--- a/server/bootstrap/bootstrap_gm_db_system.py
+++ b/server/bootstrap/bootstrap_gm_db_system.py
@@ -1,6 +1,7 @@
 #!/usr/bin/env python
+##!/usr/bin/python2.7-dbg
 
-"""GNUmed schema installation.
+u"""GNUmed schema installation.
 
 This script bootstraps a GNUmed database system.
 
@@ -25,7 +26,7 @@ further details.
 --log-file=
 --conf-file=
 
-Requires psycopg 2.7 !
+Requires psycopg 2.7.3 !
 """
 #==================================================================
 # TODO
@@ -82,7 +83,11 @@ try:
 except ImportError:
 	print """Please make sure the GNUmed Python modules are in the Python path !"""
 	raise
-from Gnumed.pycommon import gmCfg2, gmPsql, gmPG2, gmTools, gmI18N
+from Gnumed.pycommon import gmCfg2
+from Gnumed.pycommon import gmPsql
+from Gnumed.pycommon import gmPG2
+from Gnumed.pycommon import gmTools
+from Gnumed.pycommon import gmI18N
 from Gnumed.pycommon.gmExceptions import ConstructorError
 
 
@@ -92,10 +97,18 @@ aud_gen = gmAuditSchemaGenerator
 
 
 _log = logging.getLogger('gm.bootstrapper')
+
+try:
+	import faulthandler
+	#faulthandler.enable(file = gmLog2._logfile)
+	faulthandler.enable()
+except ImportError:
+	_log.error(u'<faulthandler> not available')
+
 _cfg = gmCfg2.gmCfgData()
 
 
-_interactive = False
+_interactive = None
 _bootstrapped_servers = {}
 _bootstrapped_dbs = {}
 _dbowner = None
@@ -205,13 +218,13 @@ def user_exists(cursor=None, user=None):
 	try:
 		cursor.execute(cmd, args)
 	except:
-		_log.exception(">>>[%s]<<< failed for user [%s]", cmd, user)
+		_log.exception(u">>>[%s]<<< failed for user [%s]", cmd, user)
 		return None
 	res = cursor.fetchone()
 	if cursor.rowcount == 1:
-		_log.info("user [%s] exists", user)
+		_log.info(u"user [%s] exists", user)
 		return True
-	_log.info("user [%s] does not exist", user)
+	_log.info(u"user [%s] does not exist", user)
 	return None
 #------------------------------------------------------------------
 def db_group_exists(cursor=None, group=None):
@@ -220,13 +233,13 @@ def db_group_exists(cursor=None, group=None):
 	try:
 		cursor.execute(cmd, args)
 	except:
-		_log.exception(">>>[%s]<<< failed for group [%s]", cmd, group)
+		_log.exception(u">>>[%s]<<< failed for group [%s]", cmd, group)
 		return False
 	rows = cursor.fetchall()
 	if len(rows) > 0:
-		_log.info("group [%s] exists" % group)
+		_log.info(u"group [%s] exists" % group)
 		return True
-	_log.info("group [%s] does not exist" % group)
+	_log.info(u"group [%s] does not exist" % group)
 	return False
 #------------------------------------------------------------------
 def create_db_group(cursor=None, group=None):
@@ -239,7 +252,7 @@ def create_db_group(cursor=None, group=None):
 	try:
 		cursor.execute(cmd)
 	except:
-		_log.exception(">>>[%s]<<< failed for group [%s]", cmd, group)
+		_log.exception(u">>>[%s]<<< failed for group [%s]", cmd, group)
 		return False
 
 	# paranoia is good
@@ -266,7 +279,7 @@ def connect(host, port, db, user, passwd, conn_name=None):
 			passwd = ''
 
 	dsn = gmPG2.make_psycopg2_dsn(database=db, host=host, port=port, user=user, password=passwd)
-	_log.info("trying DB connection to %s on %s as %s", db, host or 'localhost', user)
+	_log.info(u"trying DB connection to %s on %s as %s", db, host or 'localhost', user)
 	try:
 		conn = gmPG2.get_connection(dsn=dsn, readonly=False, pooled=False, verbose=True, connection_name = conn_name)
 	except:
@@ -277,7 +290,7 @@ def connect(host, port, db, user, passwd, conn_name=None):
 	cached_passwd[user] = passwd
 	conn_ref_count.append(conn)
 
-	_log.info('successfully connected')
+	_log.info(u'successfully connected')
 	return conn
 
 #==================================================================
@@ -302,7 +315,7 @@ class user:
 			# this means the user does not need a password
 			# but connects via IDENT or TRUST
 			if self.password is None:
-				_log.info('password not defined, assuming connect via IDENT/TRUST')
+				_log.info(u'password not defined, assuming connect via IDENT/TRUST')
 			# defined but empty:
 			# this means to ask the user if interactive
 			elif self.password == '':
@@ -317,12 +330,12 @@ class user:
 #==================================================================
 class db_server:
 	def __init__(self, aSrv_alias, auth_group):
-		_log.info("bootstrapping server [%s]" % aSrv_alias)
+		_log.info(u"bootstrapping server [%s]" % aSrv_alias)
 
 		global _bootstrapped_servers
 
 		if _bootstrapped_servers.has_key(aSrv_alias):
-			_log.info("server [%s] already bootstrapped" % aSrv_alias)
+			_log.info(u"server [%s] already bootstrapped" % aSrv_alias)
 			return None
 
 		self.alias = aSrv_alias
@@ -335,47 +348,47 @@ class db_server:
 
 		_bootstrapped_servers[self.alias] = self
 
-		_log.info('done bootstrapping server [%s]', aSrv_alias)
+		_log.info(u'done bootstrapping server [%s]', aSrv_alias)
 	#--------------------------------------------------------------
 	def __bootstrap(self):
 		self.superuser = user(anAlias = cfg_get(self.section, "super user alias"))
 
 		# connect to server level template database
 		if not self.__connect_superuser_to_srv_template():
-			_log.error("Cannot connect to server template database.")
+			_log.error(u"Cannot connect to server template database.")
 			return None
 
 		# add users/groups
 		if not self.__bootstrap_db_users():
-			_log.error("Cannot bootstrap database users.")
+			_log.error(u"Cannot bootstrap database users.")
 			return None
 
 		self.conn.close()
 		return True
 	#--------------------------------------------------------------
 	def __connect_superuser_to_srv_template(self):
-		_log.info("connecting to server template database")
+		_log.info(u"connecting to server template database")
 
 		# sanity checks
 		self.template_db = cfg_get(self.section, "template database")
 		if self.template_db is None:
-			_log.error("Need to know the template database name.")
+			_log.error(u"Need to know the template database name.")
 			return None
 
 		self.name = cfg_get(self.section, "name")
 		if self.name is None:
-			_log.error("Need to know the server name.")
+			_log.error(u"Need to know the server name.")
 			return None
 
 		env_var = 'GM_DB_PORT'
 		self.port = os.getenv(env_var)
 		if self.port is None:
-			_log.info('environment variable [%s] is not set, using database port from config file' % env_var)
+			_log.info(u'environment variable [%s] is not set, using database port from config file' % env_var)
 			self.port = cfg_get(self.section, "port")
 		else:
-			_log.info('using database port [%s] from environment variable [%s]' % (self.port, env_var))
+			_log.info(u'using database port [%s] from environment variable [%s]' % (self.port, env_var))
 		if self.port is None:
-			_log.error("Need to know the database server port address.")
+			_log.error(u"Need to know the database server port address.")
 			return None
 
 		if self.conn is not None:
@@ -384,7 +397,7 @@ class db_server:
 
 		self.conn = connect(self.name, self.port, self.template_db, self.superuser.name, self.superuser.password, conn_name = u'root at template.server')
 		if self.conn is None:
-			_log.error('Cannot connect.')
+			_log.error(u'Cannot connect.')
 			return None
 
 		self.conn.cookie = 'db_server.__connect_superuser_to_srv_template'
@@ -394,7 +407,7 @@ class db_server:
 		curs.execute(u"select setting from pg_settings where name = 'lc_ctype'")
 		data = curs.fetchall()
 		lc_ctype = data[0][0]
-		_log.info('template database LC_CTYPE is [%s]', lc_ctype)
+		_log.info(u'template database LC_CTYPE is [%s]', lc_ctype)
 		lc_ctype = lc_ctype.lower()
 		if lc_ctype in ['c', 'posix']:
 			_log.warning('while this cluster setting allows to store databases')
@@ -402,43 +415,43 @@ class db_server:
 			_log.warning('sorting etc, hence it is not recommended for use')
 			_log.warning('(although it will, technically, work)')
 		elif not (lc_ctype.endswith('.utf-8') or lc_ctype.endswith('.utf8')):
-			_log.error('LC_CTYPE does not end in .UTF-8 or .UTF8')
+			_log.error(u'LC_CTYPE does not end in .UTF-8 or .UTF8')
 			curs.execute(u"show server_encoding")
 			data = curs.fetchall()
 			srv_enc = data[0][0]
-			_log.info('server_encoding is [%s]', srv_enc)
+			_log.info(u'server_encoding is [%s]', srv_enc)
 			srv_enc = srv_enc.lower()
 			if not srv_enc in ['utf8', 'utf-8']:
-				_log.error('cluster encoding incompatible with utf8 encoded databases but')
-				_log.error('for GNUmed installation the cluster must accept this encoding')
-				_log.error('you may need to re-initdb or create a new cluster')
+				_log.error(u'cluster encoding incompatible with utf8 encoded databases but')
+				_log.error(u'for GNUmed installation the cluster must accept this encoding')
+				_log.error(u'you may need to re-initdb or create a new cluster')
 				return None
-			_log.info('server encoding seems compatible despite not being reported in LC_CTYPE')
+			_log.info(u'server encoding seems compatible despite not being reported in LC_CTYPE')
 
 		# make sure we get english messages
 		curs.execute(u"set lc_messages to 'C'")
 		curs.close()
 
-		_log.info("successfully connected to template database [%s]" % self.template_db)
+		_log.info(u"successfully connected to template database [%s]" % self.template_db)
 		return True
 	#--------------------------------------------------------------
 	# user and group related
 	#--------------------------------------------------------------
 	def __bootstrap_db_users(self):
-		_log.info("bootstrapping database users and groups")
+		_log.info(u"bootstrapping database users and groups")
 
 		# insert standard groups
 		if not self.__create_groups():
-			_log.error("Cannot create GNUmed standard groups.")
+			_log.error(u"Cannot create GNUmed standard groups.")
 			return None
 
 		# create GNUmed owner
 		if self.__create_dbowner() is None:
-			_log.error("Cannot install GNUmed database owner.")
+			_log.error(u"Cannot install GNUmed database owner.")
 			return None
 
 #		if not _import_schema(group=self.section, schema_opt='schema', conn=self.conn):
-#			_log.error("Cannot import schema definition for server [%s] into database [%s]." % (self.name, self.template_db))
+#			_log.error(u"Cannot import schema definition for server [%s] into database [%s]." % (self.name, self.template_db))
 #			return None
 
 		return True
@@ -448,7 +461,7 @@ class db_server:
 
 		dbowner_alias = cfg_get("GnuMed defaults", "database owner alias")
 		if dbowner_alias is None:
-			_log.error("Cannot load GNUmed database owner name from config file.")
+			_log.error(u"Cannot load GNUmed database owner name from config file.")
 			return None
 
 		cursor = self.conn.cursor()
@@ -469,8 +482,8 @@ class db_server:
 			try:
 				cursor.execute(cmd)
 			except:
-				_log.error(">>>[%s]<<< failed." % cmd)
-				_log.exception("Cannot add GNUmed database owner [%s] to groups [gm-logins] and [%s]." % (name, self.auth_group))
+				_log.error(u">>>[%s]<<< failed." % cmd)
+				_log.exception(u"Cannot add GNUmed database owner [%s] to groups [gm-logins] and [%s]." % (name, self.auth_group))
 				cursor.close()
 				return False
 			self.conn.commit()
@@ -479,7 +492,7 @@ class db_server:
 			return True
 
 		print_msg ((
-"""The database owner [%s] will be created.
+u"""The database owner [%s] will be created.
 
 You will have to provide a new password for it
 unless it is pre-defined in the configuration file.
@@ -492,8 +505,8 @@ Make sure to remember the password for later use !
 		try:
 			cursor.execute(cmd)
 		except:
-			_log.error(">>>[%s]<<< failed." % cmd)
-			_log.exception("Cannot create GNUmed database owner [%s]." % _dbowner.name)
+			_log.error(u">>>[%s]<<< failed." % cmd)
+			_log.exception(u"Cannot create GNUmed database owner [%s]." % _dbowner.name)
 			cursor.close()
 			return None
 
@@ -515,7 +528,7 @@ Make sure to remember the password for later use !
 
 		groups = cfg_get(section, "groups")
 		if groups is None:
-			_log.error("Cannot load GNUmed group names from config file (section [%s])." % section)
+			_log.error(u"Cannot load GNUmed group names from config file (section [%s])." % section)
 			groups = [self.auth_group]
 		else:
 			groups.append(self.auth_group)
@@ -532,7 +545,7 @@ Make sure to remember the password for later use !
 #==================================================================
 class database:
 	def __init__(self, aDB_alias):
-		_log.info("bootstrapping database [%s]" % aDB_alias)
+		_log.info(u"bootstrapping database [%s]" % aDB_alias)
 
 		self.section = "database %s" % aDB_alias
 
@@ -541,24 +554,24 @@ class database:
 		if overrider is not None:
 			self.name = os.getenv(overrider)
 			if self.name is None:
-				_log.info('environment variable [%s] is not set, using database name from config file' % overrider)
+				_log.info(u'environment variable [%s] is not set, using database name from config file' % overrider)
 				self.name = cfg_get(self.section, 'name')
 		else:
 			self.name = cfg_get(self.section, 'name')
 
 		if self.name is None or str(self.name).strip() == '':
-			_log.error("Need to know database name.")
+			_log.error(u"Need to know database name.")
 			raise ConstructorError, "database.__init__(): Cannot bootstrap database."
 
 		# already bootstrapped ?
 		global _bootstrapped_dbs
 		if _bootstrapped_dbs.has_key(aDB_alias):
 			if _bootstrapped_dbs[aDB_alias].name == self.name:
-				_log.info("database [%s] already bootstrapped", self.name)
+				_log.info(u"database [%s] already bootstrapped", self.name)
 				return None
 
 		# no, so bootstrap from scratch
-		_log.info('bootstrapping database [%s] alias "%s"', self.name, aDB_alias)
+		_log.info(u'bootstrapping database [%s] alias "%s"', self.name, aDB_alias)
 
 		for db in _bootstrapped_dbs.values():
 			if db.conn.closed == 0:
@@ -568,12 +581,12 @@ class database:
 
 		self.server_alias = cfg_get(self.section, "server alias")
 		if self.server_alias is None:
-			_log.error("Server alias missing.")
+			_log.error(u"Server alias missing.")
 			raise ConstructorError, "database.__init__(): Cannot bootstrap database."
 
 		self.template_db = cfg_get(self.section, "template database")
 		if self.template_db is None:
-			_log.error("Template database name missing.")
+			_log.error(u"Template database name missing.")
 			raise ConstructorError, "database.__init__(): Cannot bootstrap database."
 
 		# make sure server is bootstrapped
@@ -596,33 +609,32 @@ class database:
 			_dbowner = user(anAlias = cfg_get("GnuMed defaults", "database owner alias"))
 
 		if _dbowner is None:
-			_log.error("Cannot load GNUmed database owner name from config file.")
+			_log.error(u"Cannot load GNUmed database owner name from config file.")
 			return None
 
-		# get owner
 		self.owner = _dbowner
 
 		# connect as owner to template
 		if not self.__connect_superuser_to_template():
-			_log.error("Cannot connect to template database.")
+			_log.error(u"Cannot connect to template database.")
 			return False
 
 		# make sure db exists
 		if not self.__create_db():
-			_log.error("Cannot create database.")
+			_log.error(u"Cannot create database.")
 			return False
 
 		# reconnect as superuser to db
 		if not self.__connect_superuser_to_db():
-			_log.error("Cannot connect to database.")
+			_log.error(u"Cannot connect to database.")
 			return None
 
 		# create authentication group
-		_log.info('creating database-specific authentication group role')
+		_log.info(u'creating database-specific authentication group role')
 		curs = self.conn.cursor()
 		if not create_db_group(cursor = curs, group = self.name):
 			curs.close()
-			_log.error('cannot create authentication group role')
+			_log.error(u'cannot create authentication group role')
 			return False
 		self.conn.commit()
 		curs.close()
@@ -631,33 +643,33 @@ class database:
 		curs = self.conn.cursor()
 		if not db_group_exists(cursor = curs, group = self.name):
 			curs.close()
-			_log.error('cannot find authentication group role')
+			_log.error(u'cannot find authentication group role')
 			return False
 		curs.close()
 
 		# reindex db so upgrade doesn't fail on broken index
 		if not self.reindex_all():
-			_log.error('cannot REINDEX cloned target database')
+			_log.error(u'cannot REINDEX cloned target database')
 			return False
 
 		tmp = cfg_get(self.section, 'superuser schema')
 		if tmp is not None:
 			if not _import_schema(group=self.section, schema_opt='superuser schema', conn=self.conn):
-				_log.error("cannot import schema definition for database [%s]" % (self.name))
+				_log.error(u"cannot import schema definition for database [%s]" % (self.name))
 				return False
 		del tmp
 
 		# transfer users
 		if not self.transfer_users():
-			_log.error("Cannot transfer users from old to new database.")
+			_log.error(u"Cannot transfer users from old to new database.")
 			return False
 
 		# reconnect as owner to db
 		if not self.__connect_owner_to_db():
-			_log.error("Cannot connect to database.")
+			_log.error(u"Cannot connect to database.")
 			return None
 		if not _import_schema(group=self.section, schema_opt='schema', conn=self.conn):
-			_log.error("cannot import schema definition for database [%s]" % (self.name))
+			_log.error(u"cannot import schema definition for database [%s]" % (self.name))
 			return None
 
 		# don't close this here, the  connection will
@@ -711,23 +723,23 @@ class database:
 		# we need English messages to detect errors
 		curs.execute(u"set lc_messages to 'C'")
 		curs.execute(u"alter database %s set lc_messages to 'C'" % self.name)
-		# we need inheritance or else things will fail miserably
-		curs.execute("alter database %s set sql_inheritance to on" % self.name)
 		# we want READ ONLY default transactions for maximum patient data safety
 		curs.execute("alter database %s set default_transaction_read_only to on" % self.name)
 		# we want checking of function bodies
 		curs.execute("alter database %s set check_function_bodies to on" % self.name)
+		# we want checking of data checksums if available
+		curs.execute("alter database %s set ignore_checksum_failure to off" % self.name)
 		curs.close()
 		self.conn.commit()
 
-		# we want checking of data checksums if available
-		# remove exception handler when 9.3 is default
+		# we need inheritance or else things will fail miserably
 		curs = self.conn.cursor()
 		try:
-			curs.execute("alter database %s set ignore_checksum_failure to off" % self.name)
+			curs.execute("alter database %s set sql_inheritance to DEFAULT" % self.name)
 		except:
-			_log.exception('PostgreSQL version < 9.3 does not support <ignore_checksum_failure>')
+			_log.exception(u'PG 10 hardwired for sql_inheritance')
 		curs.close()
+		self.conn.commit()
 
 		# we want to track commit timestamps if available
 		# remove exception handler when 9.5 is default
@@ -735,9 +747,8 @@ class database:
 		try:
 			curs.execute("alter database %s set track_commit_timestamp to on" % self.name)
 		except:
-			_log.exception('PostgreSQL version < 9.5 does not support <track_commit_timestamp> OR <track_commit_timestamp> cannot be set at runtime')
+			_log.exception(u'PostgreSQL version < 9.5 does not support <track_commit_timestamp> OR <track_commit_timestamp> cannot be set at runtime')
 		curs.close()
-
 		self.conn.commit()
 
 		curs = self.conn.cursor()
@@ -749,13 +760,17 @@ class database:
 	#--------------------------------------------------------------
 	def __connect_owner_to_db(self):
 
+		_log.debug(u'__connect_owner_to_db')
+
 		# reconnect as superuser to db
 		if not self.__connect_superuser_to_db():
-			_log.error("Cannot connect to database.")
+			_log.error(u"Cannot connect to database.")
 			return False
 
 		self.conn.cookie = 'database.__connect_owner_to_db via database.__connect_superuser_to_db'
 
+		_log.debug(u'setting session authorization to user %s', self.owner.name)
+
 		curs = self.conn.cursor()
 		cmd = "set session authorization %(usr)s"
 		curs.execute(cmd, {'usr': self.owner.name})
@@ -771,17 +786,17 @@ class database:
 		try:
 			aCursor.execute(cmd)
 		except:
-			_log.exception(">>>[%s]<<< failed." % cmd)
+			_log.exception(u">>>[%s]<<< failed." % cmd)
 			return None
 
 		res = aCursor.fetchall()
 		tmp = aCursor.rowcount
 		aCursor.close()
 		if tmp == 1:
-			_log.info("Database [%s] exists." % self.name)
+			_log.info(u"Database [%s] exists." % self.name)
 			return True
 
-		_log.info("Database [%s] does not exist." % self.name)
+		_log.info(u"Database [%s] does not exist." % self.name)
 		return None
 	#--------------------------------------------------------------
 	def __create_db(self):
@@ -793,10 +808,10 @@ class database:
 		else:
 			converted, version = gmTools.input2int(template_version.lstrip('v'), 0)
 			if not converted:
-				_log.error('invalid template database definition: %s', template_version)
+				_log.error(u'invalid template database definition: %s', template_version)
 				return False
 			if not gmPG2.database_schema_compatible(link_obj = self.conn, version = version):
-				_log.error('invalid [%s] schema structure in GNUmed template database [%s]', template_version, self.template_db)
+				_log.error(u'invalid [%s] schema structure in GNUmed template database [%s]', template_version, self.template_db)
 				return False
 
 		# check for target database
@@ -804,20 +819,20 @@ class database:
 			drop_existing = bool(int(cfg_get(self.section, 'drop target database')))
 			if drop_existing:
 				print_msg("==> dropping pre-existing target database [%s] ..." % self.name)
-				_log.info('trying to drop target database')
+				_log.info(u'trying to drop target database')
 				cmd = 'DROP DATABASE "%s"' % self.name
-				_log.debug('committing existing connection before setting autocommit')
+				_log.debug(u'committing existing connection before setting autocommit')
 				self.conn.commit()
-				_log.debug('setting autocommit to TRUE')
+				_log.debug(u'setting autocommit to TRUE')
 				self.conn.autocommit = True
 				self.conn.readonly = False
 				cursor = self.conn.cursor()
 				try:
 					cursor.execute(u'SET default_transaction_read_only TO OFF')
-					_log.debug('running SQL: %s', cmd)
+					_log.debug(u'running SQL: %s', cmd)
 					cursor.execute(cmd)
 				except:
-					_log.exception(">>>[%s]<<< failed" % cmd)
+					_log.exception(u">>>[%s]<<< failed" % cmd)
 					_log.debug(u'conn state after failed DROP: %s', gmPG2.capture_conn_state(self.conn))
 					return False
 				finally:
@@ -828,10 +843,10 @@ class database:
 				if use_existing:
 					# FIXME: verify that database is owned by "gm-dbo"
 					print_msg("==> using pre-existing target database [%s] ..." % self.name)
-					_log.info('using existing database [%s]', self.name)
+					_log.info(u'using existing database [%s]', self.name)
 					return True
 				else:
-					_log.info('not using existing database [%s]', self.name)
+					_log.info(u'not using existing database [%s]', self.name)
 					return False
 
 		tablespace = cfg_get(self.section, 'tablespace')
@@ -869,7 +884,7 @@ class database:
 			cursor.execute(u'SET default_transaction_read_only TO OFF')
 			cursor.execute(create_db_cmd)
 		except:
-			_log.exception(">>>[%s]<<< failed" % create_db_cmd)
+			_log.exception(u">>>[%s]<<< failed" % create_db_cmd)
 			return False
 		finally:
 			cursor.close()
@@ -877,7 +892,7 @@ class database:
 
 		if not self.__db_exists():
 			return None
-		_log.info("Successfully created GNUmed database [%s]." % self.name)
+		_log.info(u"Successfully created GNUmed database [%s]." % self.name)
 
 		return True
 
@@ -894,7 +909,7 @@ class database:
 
 		no_of_queries, remainder = divmod(len(plausibility_queries), 2)
 		if remainder != 0:
-			_log.error('odd number of plausibility queries defined, aborting')
+			_log.error(u'odd number of plausibility queries defined, aborting')
 			print_msg("    ... failed (configuration error)")
 			return False
 
@@ -921,7 +936,7 @@ class database:
 		for idx in range(no_of_queries):
 			check_def = plausibility_queries[idx*2]
 			if check_def.startswith('--'):
-				_log.debug('skipped: %s', check_def)
+				_log.debug(u'skipped: %s', check_def)
 				continue
 
 			tag = u'?'
@@ -976,6 +991,7 @@ class database:
 		target_conn.close()
 
 		return all_tests_successful
+
 	#--------------------------------------------------------------
 	def check_holy_auth_line(self):
 
@@ -989,50 +1005,50 @@ class database:
 			self.server.superuser.name,
 			self.server.superuser.password
 		)
-		conn.cookie = 'holy auth check connection'
+		conn.cookie = u'holy auth check connection'
 
 		cmd = u"select setting from pg_settings where name = 'hba_file'"
 		rows, idx = gmPG2.run_ro_queries(link_obj = conn, queries = [{'cmd': cmd}])
 		conn.close()
 		if len(rows) == 0:
-			_log.info('cannot check pg_hba.conf for authentication information - not detectable in pg_settings')
+			_log.info(u'cannot check pg_hba.conf for authentication information - not detectable in pg_settings')
 			return
 
 		hba_file = rows[0][0]
-		_log.info('hba file: %s', hba_file)
+		_log.info(u'hba file: %s', hba_file)
 
 		try:
 			f = io.open(hba_file, mode = 'rt').close()
 		except Exception:
-			_log.exception('cannot check pg_hba.conf for authentication information - not readable')
+			_log.exception(u'cannot check pg_hba.conf for authentication information - not readable')
 			return
 
 		found_holy_line = False
 		for line in fileinput.input(hba_file):
 			if regex.match(holy_pattern, line) is not None:
 				found_holy_line = True
-				_log.info('found standard GNUmed authentication directive in pg_hba.conf')
-				_log.info('[%s]', line)
-				_log.info('it may still be in the wrong place, though, so double-check if clients cannot connect')
+				_log.info(u'found standard GNUmed authentication directive in pg_hba.conf')
+				_log.info(u'[%s]', line)
+				_log.info(u'it may still be in the wrong place, though, so double-check if clients cannot connect')
 				break
 
 		if not found_holy_line:
-			_log.info('did not find active standard GNUmed authentication directive in pg_hba.conf')
-			_log.info('regex: %s' % holy_pattern)
+			_log.info(u'did not find active standard GNUmed authentication directive in pg_hba.conf')
+			_log.info(u'regex: %s' % holy_pattern)
 
 			found_holy_line_inactive = False
 			for line in fileinput.input(hba_file):
 				if regex.match(holy_pattern_inactive, line) is not None:
 					found_holy_line_inactive = True
-					_log.info('found inactive standard GNUmed authentication directive in pg_hba.conf')
-					_log.info('[%s]', line)
-					_log.info('it may still be in the wrong place, though, so double-check if clients cannot connect')
+					_log.info(u'found inactive standard GNUmed authentication directive in pg_hba.conf')
+					_log.info(u'[%s]', line)
+					_log.info(u'it may still be in the wrong place, though, so double-check if clients cannot connect')
 					break
 			if not found_holy_line_inactive:
-				_log.info('did not find inactive standard GNUmed authentication directive in pg_hba.conf either')
-				_log.info('regex: %s' % holy_pattern_inactive)
+				_log.info(u'did not find inactive standard GNUmed authentication directive in pg_hba.conf either')
+				_log.info(u'regex: %s' % holy_pattern_inactive)
 
-			_log.info('bootstrapping is likely to have succeeded but clients probably cannot connect yet')
+			_log.info(u'bootstrapping is likely to have succeeded but clients probably cannot connect yet')
 			print_msg('==> sanity checking PostgreSQL authentication settings ...')
 			print_msg('')
 			print_msg('Note that even after successfully bootstrapping the GNUmed ')
@@ -1060,7 +1076,7 @@ class database:
 
 		import_scripts = cfg_get(self.section, "data import scripts")
 		if (import_scripts is None) or (len(import_scripts) == 0):
-			_log.info('skipped data import: no scripts to run')
+			_log.info(u'skipped data import: no scripts to run')
 			print_msg("    ... skipped (no scripts to run)")
 			return True
 
@@ -1075,14 +1091,14 @@ class database:
 				script = gmTools.import_module_from_directory(module_path = script_base_dir, module_name = import_script, always_remove_path = True)
 			except ImportError:
 				print_msg("    ... failed (cannot load script [%s])" % import_script)
-				_log.error('cannot load data set import script [%s/%s]' % (script_base_dir, import_script))
+				_log.error(u'cannot load data set import script [%s/%s]' % (script_base_dir, import_script))
 				return False
 
 			try:
 				script.run(conn = self.conn)
 			except:
 				print_msg("    ... failed (cannot run script [%s])" % import_script)
-				_log.exception('cannot run import script [%s]' % import_script)
+				_log.exception(u'cannot run import script [%s]' % import_script)
 				return False
 
 			if import_script.endswith('.py'):
@@ -1093,7 +1109,7 @@ class database:
 				del script
 				gc.collect()
 			except:
-				_log.exception('cannot remove data import script module [%s], hoping for the best', import_script)
+				_log.exception(u'cannot remove data import script module [%s], hoping for the best', import_script)
 
 		return True
 
@@ -1105,18 +1121,18 @@ class database:
 		target_version = cfg_get(self.section, 'target version')
 		if target_version == 'devel':
 			print_msg("    ... skipped (devel version)")
-			_log.info('result schema hash: %s', gmPG2.get_schema_hash(link_obj = self.conn))
+			_log.info(u'result schema hash: %s', gmPG2.get_schema_hash(link_obj = self.conn))
 			_log.warning('testing/development only, not failing due to invalid target database identity hash')
 			return True
 		converted, version = gmTools.input2int(target_version.lstrip('v'), 2)
 		if not converted:
-			_log.error('cannot convert target database version: %s', target_version)
+			_log.error(u'cannot convert target database version: %s', target_version)
 			print_msg("    ... failed (invalid target version specification)")
 			return False
 		if gmPG2.database_schema_compatible(link_obj = self.conn, version = version):
-			_log.info('database identity hash properly verified')
+			_log.info(u'database identity hash properly verified')
 			return True
-		_log.error('target database identity hash invalid')
+		_log.error(u'target database identity hash invalid')
 		print_msg("    ... failed (hash mismatch)")
 		return False
 
@@ -1135,9 +1151,9 @@ class database:
 			print_msg("    ... skipped")
 			return True
 
-		_log.info('REINDEXing cloned target database so upgrade does not fail in case of a broken index')
-		_log.info('this may potentially take "quite a long time" depending on how much data there is in the database')
-		_log.info('you may want to monitor the PostgreSQL log for signs of progress')
+		_log.info(u'REINDEXing cloned target database so upgrade does not fail in case of a broken index')
+		_log.info(u'this may potentially take "quite a long time" depending on how much data there is in the database')
+		_log.info(u'you may want to monitor the PostgreSQL log for signs of progress')
 
 		self.conn.commit()
 		self.conn.set_session(readonly = False, autocommit = True)
@@ -1147,15 +1163,15 @@ class database:
 		try:
 			curs_outer.execute(cmd)
 		except:
-			_log.exception(">>>[%s]<<< failed" % cmd)
+			_log.exception(u">>>[%s]<<< failed" % cmd)
 			# re-attempt w/o VERBOSE
-			_log.info('attempting REINDEXing without VERBOSE')
+			_log.info(u'attempting REINDEXing without VERBOSE')
 			curs_inner = self.conn.cursor()
 			cmd = 'REINDEX DATABASE %s' % self.name
 			try:
 				curs_inner.execute(cmd)
 			except:
-				_log.exception(">>>[%s]<<< failed" % cmd)
+				_log.exception(u">>>[%s]<<< failed" % cmd)
 				return False
 			finally:
 				curs_inner.close()
@@ -1171,12 +1187,12 @@ class database:
 		print_msg("==> transferring users ...")
 		do_user_transfer = cfg_get(self.section, 'transfer users')
 		if do_user_transfer is None:
-			_log.info('user transfer not defined')
+			_log.info(u'user transfer not defined')
 			print_msg("    ... skipped (unconfigured)")
 			return True
 		do_user_transfer = int(do_user_transfer)
 		if not do_user_transfer:
-			_log.info('configured to not transfer users')
+			_log.info(u'configured to not transfer users')
 			print_msg("    ... skipped (disabled)")
 			return True
 
@@ -1185,14 +1201,14 @@ class database:
 			rows, idx = gmPG2.run_rw_queries(link_obj = self.conn, queries = [{'cmd': cmd}], end_tx = True, return_data = True)
 		except gmPG2.dbapi.ProgrammingError:
 			# maybe an old database
-			_log.info('problem running gm.transfer_users(), trying gm_transfer_users()')
+			_log.info(u'problem running gm.transfer_users(), trying gm_transfer_users()')
 			cmd = u"select gm_transfer_users('%s'::text)" % self.template_db
 			rows, idx = gmPG2.run_rw_queries(link_obj = self.conn, queries = [{'cmd': cmd}], end_tx = True, return_data = True)
 
 		if rows[0][0]:
-			_log.info('users properly transferred from [%s] to [%s]' % (self.template_db, self.name))
+			_log.info(u'users properly transferred from [%s] to [%s]' % (self.template_db, self.name))
 			return True
-		_log.error('error transferring user from [%s] to [%s]' % (self.template_db, self.name))
+		_log.error(u'error transferring user from [%s] to [%s]' % (self.template_db, self.name))
 		print_msg("    ... failed")
 		return False
 
@@ -1228,7 +1244,7 @@ class database:
 		audit_schema = gmAuditSchemaGenerator.create_audit_ddl(curs)
 		curs.close()
 		if audit_schema is None:
-			_log.error('cannot generate audit trail schema for GNUmed database [%s]' % self.name)
+			_log.error(u'cannot generate audit trail schema for GNUmed database [%s]' % self.name)
 			return None
 		# write schema to file
 		tmpfile = os.path.join(tempfile.gettempdir(), 'audit-trail-schema.sql')
@@ -1240,7 +1256,7 @@ class database:
 		# import auditing schema
 		psql = gmPsql.Psql(self.conn)
 		if psql.run(tmpfile) != 0:
-			_log.error("cannot import audit schema definition for database [%s]" % (self.name))
+			_log.error(u"cannot import audit schema definition for database [%s]" % (self.name))
 			return None
 
 		if _keep_temp_files:
@@ -1249,7 +1265,7 @@ class database:
 		try:
 			os.remove(tmpfile)
 		except Exception:
-			_log.exception('cannot remove audit trail schema file [%s]' % tmpfile)
+			_log.exception(u'cannot remove audit trail schema file [%s]' % tmpfile)
 		return True
 
 	#--------------------------------------------------------------
@@ -1258,9 +1274,9 @@ class database:
 		# setup clin.clin_root_item child tables FK's
 		print_msg("==> setting up encounter/episode FKs and IDXs ...")
 		child_tables = gmPG2.get_child_tables(link_obj = self.conn, schema = 'clin', table = 'clin_root_item')
-		_log.info('clin.clin_root_item child tables:')
+		_log.info(u'clin.clin_root_item child tables:')
 		for child in child_tables:
-			_log.info('%s.%s', child['namespace'], child['table'])
+			_log.info(u'%s.%s', child['namespace'], child['table'])
 		for child in child_tables:
 			# .fk_episode
 			FKs = gmPG2.get_foreign_key_names (
@@ -1273,12 +1289,12 @@ class database:
 				target_column = 'pk',
 			)
 			if len(FKs) > 0:
-				_log.info('%s FK(s) exist:', len(FKs))
+				_log.info(u'%s FK(s) exist:', len(FKs))
 				for idx in range(len(FKs)):
 					FK = FKs[idx]
 					_log.info(u' #%s = %s.%s: %s.%s.%s -> %s.%s.%s', idx + 1, FK['constraint_schema'], FK['constraint_name'], FK['source_schema'], FK['source_table'], FK['source_column'], FK['target_schema'], FK['target_table'], FK['target_column'])
 			else:
-				_log.info('adding FK: %s.%s.fk_episode -> clin.episode.pk', child['namespace'], child['table'])
+				_log.info(u'adding FK: %s.%s.fk_episode -> clin.episode.pk', child['namespace'], child['table'])
 				cmd = SQL_add_foreign_key % {
 					'src_schema': child['namespace'],
 					'src_tbl': child['table'],
@@ -1316,12 +1332,12 @@ class database:
 				target_column = 'pk'
 			)
 			if len(FKs) > 0:
-				_log.info('%s FK(s) exist:', len(FKs))
+				_log.info(u'%s FK(s) exist:', len(FKs))
 				for idx in range(len(FKs)):
 					FK = FKs[idx]
 					_log.info(u' #%s = %s.%s: %s.%s.%s -> %s.%s.%s', idx + 1, FK['constraint_schema'], FK['constraint_name'], FK['source_schema'], FK['source_table'], FK['source_column'], FK['target_schema'], FK['target_table'], FK['target_column'])
 			else:
-				_log.info('adding FK: %s.%s.fk_encounter -> clin.encounter.pk', child['namespace'], child['table'])
+				_log.info(u'adding FK: %s.%s.fk_encounter -> clin.encounter.pk', child['namespace'], child['table'])
 				cmd = SQL_add_foreign_key % {
 					'src_schema': child['namespace'],
 					'src_tbl': child['table'],
@@ -1353,26 +1369,26 @@ class database:
 		# re-create fk_encounter/fk_episode sanity check triggers on all tables
 		if gmPG2.function_exists(link_obj = curs, schema = u'gm', function = u'create_all_enc_epi_sanity_check_triggers'):
 			print_msg("==> setting up encounter/episode FK sanity check triggers ...")
-			_log.debug('attempting to set up sanity check triggers on all tables linking to encounter AND episode')
+			_log.debug(u'attempting to set up sanity check triggers on all tables linking to encounter AND episode')
 			cmd = u'select gm.create_all_enc_epi_sanity_check_triggers()'
 			curs.execute(cmd)
 			result = curs.fetchone()
 			if result[0] is False:
-				_log.error('error creating sanity check triggers on all tables linking to clin.encounter AND clin.episode')
+				_log.error(u'error creating sanity check triggers on all tables linking to clin.encounter AND clin.episode')
 				curs.close()
 				return None
 
 		# always re-create generic super signal (if exists)
 		if gmPG2.function_exists(link_obj = curs, schema = u'gm', function = u'create_all_table_mod_triggers'):
 			print_msg("==> setting up generic notifications ...")
-			_log.debug('attempting to create generic modification announcement triggers on all registered tables')
+			_log.debug(u'attempting to create generic modification announcement triggers on all registered tables')
 
 			cmd = u"SELECT gm.create_all_table_mod_triggers(True::boolean)"
 			curs.execute(cmd)
 			result = curs.fetchone()
 			curs.close()
 			if result[0] is False:
-				_log.error('cannot create generic modification announcement triggers on all tables')
+				_log.error(u'cannot create generic modification announcement triggers on all tables')
 				return None
 
 		self.conn.commit()
@@ -1389,12 +1405,12 @@ class gmBundle:
 		self.section = "bundle %s" % aBundleAlias
 	#--------------------------------------------------------------
 	def bootstrap(self):
-		_log.info("bootstrapping bundle [%s]" % self.alias)
+		_log.info(u"bootstrapping bundle [%s]" % self.alias)
 
 		# load bundle definition
 		database_alias = cfg_get(self.section, "database alias")
 		if database_alias is None:
-			_log.error("Need to know database name to install bundle [%s]." % self.alias)
+			_log.error(u"Need to know database name to install bundle [%s]." % self.alias)
 			return None
 		# bootstrap database
 		try:
@@ -1406,12 +1422,12 @@ class gmBundle:
 
 		# check PostgreSQL version
 		if not self.__verify_pg_version():
-			_log.error("Wrong PostgreSQL version.")
+			_log.error(u"Wrong PostgreSQL version.")
 			return None
 
 		# import schema
 		if not _import_schema(group=self.section, schema_opt='schema', conn=self.db.conn):
-			_log.error("Cannot import schema definition for bundle [%s] into database [%s]." % (self.alias, database_alias))
+			_log.error(u"Cannot import schema definition for bundle [%s] into database [%s]." % (self.alias, database_alias))
 			return None
 
 		return True
@@ -1421,25 +1437,25 @@ class gmBundle:
 
 		required_version = cfg_get(self.section, "minimum postgresql version")
 		if required_version is None:
-			_log.error("Cannot load minimum required PostgreSQL version from config file.")
+			_log.error(u"Cannot load minimum required PostgreSQL version from config file.")
 			return None
 
-		_log.info("minimum required PostgreSQL version: %s" % required_version)
+		_log.info(u"minimum required PostgreSQL version: %s" % required_version)
 
 		converted, pg_ver = gmTools.input2decimal(gmPG2.postgresql_version)
 		if not converted:
-			_log.error('error checking PostgreSQL version')
+			_log.error(u'error checking PostgreSQL version')
 			return None
 		converted, req_version = gmTools.input2decimal(required_version)
 		if not converted:
-			_log.error('error checking PostgreSQL version')
-			_log.error('required: %s', required_version)
+			_log.error(u'error checking PostgreSQL version')
+			_log.error(u'required: %s', required_version)
 			return None
 		if pg_ver < req_version:
-			_log.error("Reported live PostgreSQL version [%s] is smaller than the required minimum version [%s]." % (gmPG2.postgresql_version, required_version))
+			_log.error(u"Reported live PostgreSQL version [%s] is smaller than the required minimum version [%s]." % (gmPG2.postgresql_version, required_version))
 			return None
 
-		_log.info("installed PostgreSQL version: %s - this is fine with me" % gmPG2.postgresql_version)
+		_log.info(u"installed PostgreSQL version: %s - this is fine with me" % gmPG2.postgresql_version)
 		return True
 #==================================================================
 def bootstrap_bundles():
@@ -1484,16 +1500,17 @@ def _run_query(aCurs, aQuery, args=None):
 		try:
 			aCurs.execute(aQuery)
 		except:
-			_log.exception(">>>%s<<< failed" % aQuery)
+			_log.exception(u">>>%s<<< failed" % aQuery)
 			return False
 	else:
 		try:
 			aCurs.execute(aQuery, args)
 		except:
-			_log.exception(">>>%s<<< failed" % aQuery)
+			_log.exception(u">>>%s<<< failed" % aQuery)
 			_log.error(str(args))
 			return False
 	return True
+
 #------------------------------------------------------------------
 def ask_for_confirmation():
 	bundles = cfg_get("installation", "bundles")
@@ -1501,6 +1518,7 @@ def ask_for_confirmation():
 		return True
 	if len(bundles) == 0:
 		return True
+
 	if not _interactive:
 		print_msg("You are about to install the following parts of GNUmed:")
 		print_msg("-------------------------------------------------------")
@@ -1515,35 +1533,34 @@ def ask_for_confirmation():
 		if desc is not None:
 			for line in desc:
 				print_msg(line)
-	else:
-		print "You are about to install the following parts of GNUmed:"
-		print "-------------------------------------------------------"
-		for bundle in bundles:
-			db_alias = cfg_get("bundle %s" % bundle, "database alias")
-			db_name = cfg_get("database %s" % db_alias, "name")
-			srv_alias = cfg_get("database %s" % db_alias, "server alias")
-			srv_name = cfg_get("server %s" % srv_alias, "name")
-			print 'bundle "%s" in <%s> (or overridden) on <%s>' % (bundle, db_name, srv_name)
-		print "-------------------------------------------------------"
-		desc = cfg_get("installation", "description")
-		if desc is not None:
-			for line in desc:
-				print line
+		return True
 
-		print "Do you really want to install this database setup ?"
-		answer = raw_input("Type yes or no: ")
-		if answer == "yes":
-			return True
-		else:
-			return None
-	return True
+	print "You are about to install the following parts of GNUmed:"
+	print "-------------------------------------------------------"
+	for bundle in bundles:
+		db_alias = cfg_get("bundle %s" % bundle, "database alias")
+		db_name = cfg_get("database %s" % db_alias, "name")
+		srv_alias = cfg_get("database %s" % db_alias, "server alias")
+		srv_name = cfg_get("server %s" % srv_alias, "name")
+		print 'bundle "%s" in <%s> (or overridden) on <%s>' % (bundle, db_name, srv_name)
+	print "-------------------------------------------------------"
+	desc = cfg_get("installation", "description")
+	if desc is not None:
+		for line in desc:
+			print line
+
+	print "Do you really want to install this database setup ?"
+	answer = raw_input("Type yes or no: ")
+	if answer == "yes":
+		return True
+	return None
 
 #--------------------------------------------------------------
 def _import_schema (group=None, schema_opt="schema", conn=None):
 	# load schema
 	schema_files = cfg_get(group, schema_opt)
 	if schema_files is None:
-		_log.error("Need to know schema definition to install it.")
+		_log.error(u"Need to know schema definition to install it.")
 		return None
 
 	schema_base_dir = cfg_get(group, "schema base directory")
@@ -1569,7 +1586,7 @@ def _import_schema (group=None, schema_opt="schema", conn=None):
 			continue
 		full_path = os.path.join(schema_base_dir, filename)
 		if psql.run(full_path) == 0:
-			#_log.info('success')
+			#_log.info(u'success')
 			continue
 		_log.error(u'failure')
 		return None
@@ -1586,14 +1603,16 @@ def exit_with_msg(aMsg = None):
 	print ' ', gmLog2._logfile_name
 	print ''
 
-	_log.error(aMsg)
- 	_log.info("shutdown")
+	_log.error(unicode(aMsg, errors = 'replace'))
+ 	_log.info(u'shutdown')
 	sys.exit(1)
+
 #------------------------------------------------------------------
 def print_msg(msg=None):
 	if quiet:
 		return
 	print msg
+
 #-----------------------------------------------------------------
 def become_pg_demon_user():
 	"""Become "postgres" user.
@@ -1615,7 +1634,7 @@ def become_pg_demon_user():
 
 	try:
 		running_as = pwd.getpwuid(os.getuid())[0]
-		_log.info('running as user [%s]' % running_as)
+		_log.info(u'running as user [%s]' % running_as)
 	except:
 		running_as = None
 
@@ -1635,18 +1654,19 @@ def become_pg_demon_user():
 			return None
 
 	if os.getuid() == 0: # we are the super-user
-		_log.info('switching to UNIX user [%s]' % pg_demon_user_passwd_line[0])
+		_log.info(u'switching to UNIX user [%s]' % pg_demon_user_passwd_line[0])
 		os.setuid(pg_demon_user_passwd_line[2])
 		gmPG2.log_auth_environment()
 
 	elif running_as == pg_demon_user_passwd_line[0]: # we are the postgres user already
-		_log.info('I already am the UNIX user [%s]' % pg_demon_user_passwd_line[0])
+		_log.info(u'I already am the UNIX user [%s]' % pg_demon_user_passwd_line[0])
 
 	else:
 		_log.warning('not running as root or postgres, cannot become postmaster demon user')
 		_log.warning('may have trouble connecting as gm-dbo if IDENT auth is forced upon us')
 		if _interactive:
 			print_msg("WARNING: This script may not work if not running as the system administrator.")
+
 #==============================================================================
 def cfg_get(group=None, option=None):
 	return _cfg.get (
@@ -1654,20 +1674,23 @@ def cfg_get(group=None, option=None):
 		option = option,
 		source_order = [('file', 'return')]
 	)
+
 #==================================================================
 def handle_cfg():
 	"""Bootstrap the source 'file' in _cfg."""
 
-	_log.info('config file: %s', _cfg.source_files['file'])
+	_log.info(u'config file: %s', _cfg.source_files['file'])
 
 	become_pg_demon_user()
 
-	tmp = cfg_get("installation", "interactive")
 	global _interactive
-	if tmp == "yes":
-		_interactive = True
-	elif tmp == "no":
-		_interactive = False
+
+	if _interactive is None:
+		tmp = cfg_get("installation", "interactive")
+		if tmp == "no":
+			_interactive = False
+		else:
+			_interactive = True
 
 	tmp = cfg_get('installation', 'keep temp files')
 	if tmp == "yes":
@@ -1704,10 +1727,10 @@ def main():
 	# get initial conf file from CLI
 	cfg_file = _cfg.get(option = '--conf-file', source_order = [('cli', 'return')])
 	if cfg_file is None:
-		_log.error("no config file specified on command line")
+		_log.error(u"no config file specified on command line")
 		exit_with_msg('Cannot bootstrap without config file. Use --conf-file=<FILE>.')
 
-	_log.info('initial config file: %s', cfg_file)
+	_log.info(u'initial config file: %s', cfg_file)
 
 	# read that conf file
 	_cfg.add_file_source (
@@ -1723,10 +1746,16 @@ def main():
 	)
 
 	if cfg_files is None:
-		_log.info('single-shot config file')
+		_log.info(u'single-shot config file')
 		handle_cfg()
 	else:
-		_log.info('aggregation of config files')
+		_log.info(u'aggregation of config files')
+		tmp = cfg_get("installation", "interactive")
+		global _interactive
+		if tmp == "no":
+			_interactive = False
+		else:
+			_interactive = True
 		for cfg_file in cfg_files:
 			# read that conf file
 			_cfg.add_file_source (
@@ -1750,40 +1779,40 @@ def main():
 
 	db.check_holy_auth_line()
 
-	for conn in conn_ref_count:
-		if conn.closed == 0:
-			_log.warning('open connection detected: %s', conn.cookie)
-			_log.warning('%s', conn)
-			_log.warning('closing connection')
-			conn.close()
-
-	_log.info("shutdown")
+	_log.info(u"shutdown")
 	print("Done bootstrapping GNUmed database: We very likely succeeded.")
 	print 'log:', gmLog2._logfile_name
 
 #==================================================================
-if __name__ == "__main__":
+if __name__ != "__main__":
+	print "This currently is not intended to be used as a module."
+	sys.exit(1)
 
-	gmI18N.activate_locale()
-	gmLog2.set_string_encoding()
 
-	_log.info("startup")
+gmI18N.activate_locale()
+gmLog2.set_string_encoding()
+
+_log.info(u'startup')
+
+try:
+	main()
+except StandardError:
+	_log.exception(u'unhandled exception caught, shutting down connections')
+	exit_with_msg(u'Bootstrapping failed: unhandled exception occurred')
+finally:
+	for conn in conn_ref_count:
+		if conn.closed == 0:
+			_log.warning(u'open connection detected: %s', conn.cookie)
+			_log.warning(u'%s', conn)
+			_log.warning(u'closing connection')
+			conn.close()
+		del conn
+	del conn_ref_count
+
+_log.info(u'after main, before sys.exit(0)')
+
+sys.exit(0)
 
-	try:
-		main()
-	except Exception:
-		for c in conn_ref_count:
-			if c.closed == 0:
-				print 'closing open connection from:', c.cookie
-				print c
-				c.close()
-		_log.exception('unhandled exception caught')
-		exit_with_msg("Bootstrapping failed: unhandled exception occurred")
-
-	sys.exit(0)
-else:
-	print "This currently is not intended to be used as a module."
-	sys.exit(1)
 
 #==================================================================
 #	pipe = popen2.Popen3(cmd, 1==1)
@@ -1800,15 +1829,14 @@ else:
 #	tmp = pipe.fromchild.read()
 #	lines = tmp.split("\n")
 #	for line in lines:
-#		_log.debug("child stdout: [%s]" % line, gmLog.lCooked)
+#		_log.debug(u"child stdout: [%s]" % line, gmLog.lCooked)
 #	tmp = pipe.childerr.read()
 #	lines = tmp.split("\n")
 #	for line in lines:
-#		_log.error("child stderr: [%s]" % line, gmLog.lCooked)
+#		_log.error(u"child stderr: [%s]" % line, gmLog.lCooked)
 
 #	pipe.fromchild.close()
 #	pipe.childerr.close()
 #	del pipe
 
 #==================================================================
-
diff --git a/server/bootstrap/fixup_db-v21.conf b/server/bootstrap/fixup_db-v21.conf
index 54d29cc..12acc66 100644
--- a/server/bootstrap/fixup_db-v21.conf
+++ b/server/bootstrap/fixup_db-v21.conf
@@ -27,6 +27,9 @@ database alias = gnumed_v21
 minimum postgresql version = 9.2
 schema base directory = ../sql/v20-v21/fixups/
 schema = $schema$
+v21-db-sql_inheritance-fixup.sql
+v21-audit-add_table_for_audit-fixup.sql
+v21-i18n-lang_funcs-fixup.sql
 v21-previously-missing-array_agg-fixup.sql
 v21-dem-view_grants-fixup.sql
 ../dynamic/v21-release_notes-dynamic.sql
@@ -38,6 +41,7 @@ v21-AMTS_Medikationsplan-fixup.sql
 v21-ref-auto_hint-smoking_status-fixup.sql
 v21-ref-GKV_CU-fixup.sql
 v21-clin-get_hints_for_patient-fixup.sql
+v21-clin-v_substance_intakes-fixup.sql
 v21-notifications-dynamic.sql
 v21-clin-uppercase_soap_cat-fixup.sql
 v21-dem-identity-fixup.sql
diff --git a/server/bootstrap/update_db-v20_v21.conf b/server/bootstrap/update_db-v20_v21.conf
index 1c5a801..200f97d 100644
--- a/server/bootstrap/update_db-v20_v21.conf
+++ b/server/bootstrap/update_db-v20_v21.conf
@@ -119,6 +119,9 @@ database alias = gnumed_v21
 minimum postgresql version = 9.2
 schema base directory = ../sql/v20-v21/fixups/
 schema = $schema$
+v21-db-sql_inheritance-fixup.sql
+v21-audit-add_table_for_audit-fixup.sql
+v21-i18n-lang_funcs-fixup.sql
 v21-previously-missing-array_agg-fixup.sql
 v21-dem-view_grants-fixup.sql
 v21-ref-auto_hint-tetanus_STIKO.sql
@@ -129,6 +132,7 @@ v21-AMTS_Medikationsplan-fixup.sql
 v21-ref-auto_hint-smoking_status-fixup.sql
 v21-ref-GKV_CU-fixup.sql
 v21-clin-get_hints_for_patient-fixup.sql
+v21-clin-v_substance_intakes-fixup.sql
 v21-notifications-dynamic.sql
 v21-clin-uppercase_soap_cat-fixup.sql
 v21-dem-identity-fixup.sql
diff --git a/server/doc/schema/gnumed-entire_schema.html b/server/doc/schema/gnumed-entire_schema.html
index 6a174d8..69f33fe 100644
--- a/server/doc/schema/gnumed-entire_schema.html
+++ b/server/doc/schema/gnumed-entire_schema.html
@@ -112,7 +112,7 @@
   <body>
 
     <!-- Primary Index -->
-	<p><br><br>Dumped on 2017-08-31</p>
+	<p><br><br>Dumped on 2017-10-28</p>
 <h1><a name="index">Index of database - gnumed_v21</a></h1>
 <ul>
     
diff --git a/server/gm-adjust_db_settings.sh b/server/gm-adjust_db_settings.sh
index 14f6eef..b226211 100755
--- a/server/gm-adjust_db_settings.sh
+++ b/server/gm-adjust_db_settings.sh
@@ -51,18 +51,13 @@ echo "alter database ${TARGET_DB} set default_transaction_isolation to 'read com
 echo "alter database ${TARGET_DB} set lc_messages to 'C';" >> $SQL_FILE
 echo "alter database ${TARGET_DB} set password_encryption to 'on';" >> $SQL_FILE
 echo "alter database ${TARGET_DB} set synchronous_commit to 'on';" >> $SQL_FILE
-echo "alter database ${TARGET_DB} set sql_inheritance to 'on';" >> $SQL_FILE
 echo "alter database ${TARGET_DB} set check_function_bodies to 'on';" >> $SQL_FILE
+echo "-- starting with 9.3:" >> $SQL_FILE
+echo "alter database ${TARGET_DB} set ignore_checksum_failure to 'off';" >> $SQL_FILE
+
 echo "" >> $SQL_FILE
-echo "-- starting with 9.3 (remove when 9.3 is required):" >> $SQL_FILE
-echo "\unset ON_ERROR_STOP" >> $SQL_FILE
-echo "alter database ${TARGET_DB} set ignore_checksum_failure to 'off';     -- comment out if the script fails" >> $SQL_FILE
-echo "\set ON_ERROR_STOP 1" >> $SQL_FILE
-echo "" >> $SQL_FILE
-echo "-- < PG 9.0 only:" >> $SQL_FILE
-echo "--\unset ON_ERROR_STOP" >> $SQL_FILE
-echo "--alter database ${TARGET_DB} set regex_flavor to 'advanced';" >> $SQL_FILE
-echo "--\set ON_ERROR_STOP 1" >> $SQL_FILE
+echo "-- PG < 10 only:" >> $SQL_FILE
+echo "--alter database ${TARGET_DB} set sql_inheritance to 'on';" >> $SQL_FILE
 
 echo "" >> $SQL_FILE
 echo "-- the following can only be set at server start" >> $SQL_FILE
diff --git a/server/pycommon/gmMimeLib.py b/server/pycommon/gmMimeLib.py
index 417f853..7b6510d 100644
--- a/server/pycommon/gmMimeLib.py
+++ b/server/pycommon/gmMimeLib.py
@@ -46,8 +46,13 @@ def guess_mimetype(filename = None):
 			if (prop == 'mimetype') and (val != worst_case):
 				return val
 	except ImportError:
-		_log.debug('module <extractor> (python wrapper for libextractor) not installed')
-
+		_log.debug(u'module <extractor> (python wrapper for libextractor) not installed')
+	except OSError as exc:
+		# winerror 126, errno 22
+		if exc.errno == 22:
+			_log.exception(u'module <extractor> (python wrapper for libextractor) not installed')
+		else:
+			raise
 	ret_code = -1
 
 	# 2) use "file" system command
@@ -385,10 +390,11 @@ if __name__ == "__main__":
 
 	#_get_system_startfile_cmd(filename)
 	#print(_system_startfile_cmd)
-	#print(guess_mimetype(filename))
+	print(guess_mimetype(filename))
 	#print(get_viewer_cmd(guess_mimetype(filename), filename))
 	#print(guess_ext_by_mimetype(mimetype=filename))
 	#call_viewer_on_file(aFile = filename, block=None)
-	status, desc = describe_file(filename)
-	print status
-	print desc
+
+	#status, desc = describe_file(filename)
+	#print status
+	#print desc
diff --git a/server/pycommon/gmPG2.py b/server/pycommon/gmPG2.py
index 36d2f87..60f5f4c 100644
--- a/server/pycommon/gmPG2.py
+++ b/server/pycommon/gmPG2.py
@@ -1549,6 +1549,10 @@ def capture_conn_state(conn=None):
 	conn_status = u'%s (%s)' % (conn.status, map_psyco_conn_status2str[conn.status])
 	if conn.closed != 0:
 		conn_status = u'undefined (%s)' % conn_status
+	try:
+		conn_deferrable = conn.deferrable
+	except AttributeError:
+		conn_deferrable = u'unavailable'
 
 	d = {
 		u'identity': id(conn),
@@ -1560,7 +1564,7 @@ def capture_conn_state(conn=None):
 		u'autocommit': conn.autocommit,
 		u'isolation level (psyco)': isolation_level,
 		u'async': conn.async,
-		u'deferrable': conn.deferrable,
+		u'deferrable': conn_deferrable,
 		u'transaction status': u'%s (%s)' % (tx_status, map_psyco_tx_status2str[tx_status]),
 		u'connection status': conn_status,
 		u'executing async op': conn.isexecuting(),
@@ -1597,6 +1601,10 @@ def capture_cursor_state(cursor=None):
 		isolation_level = u'tx aborted or unknown, cannot retrieve'
 	else:
 		isolation_level = conn.isolation_level
+	try:
+		conn_deferrable = conn.deferrable
+	except AttributeError:
+		conn_deferrable = u'unavailable'
 
 	if cursor.query is None:
 		query = u'<no query>'
@@ -1638,7 +1646,7 @@ Query
 		isolation_level,
 		conn.encoding,
 		conn.async,
-		conn.deferrable,
+		conn_deferrable,
 		conn.readonly,
 		map_psyco_tx_status2str[tx_status],
 		map_psyco_conn_status2str[conn.status],
@@ -1853,7 +1861,7 @@ def run_rw_queries(link_obj=None, queries=None, end_tx=False, return_data=None,
 			if verbose:
 				_log.debug(capture_cursor_state(curs))
 			for notice in notices_accessor.notices:
-				_log.debug(notice.strip(u'\n').strip(u'\r'))
+				_log.debug(unicode(notice, 'utf8', 'replace').strip(u'\n').strip(u'\r'))
 			del notices_accessor.notices[:]
 		# DB related exceptions
 		except dbapi.Error as pg_exc:
@@ -1868,7 +1876,7 @@ def run_rw_queries(link_obj=None, queries=None, end_tx=False, return_data=None,
 						continue
 					_log.error(u'PG diags %s: %s', prop, val)
 			for notice in notices_accessor.notices:
-				_log.error(notice.strip(u'\n').strip(u'\r'))
+				_log.error(unicode(notice, 'utf8', 'replace').strip(u'\n').strip(u'\r'))
 			del notices_accessor.notices[:]
 			pg_exc = make_pg_exception_fields_unicode(pg_exc)
 			_log.error(u'PG error code: %s', pg_exc.pgcode)
@@ -1912,7 +1920,7 @@ def run_rw_queries(link_obj=None, queries=None, end_tx=False, return_data=None,
 			_log.exception('error running query in RW connection')
 			_log.error(capture_cursor_state(curs))
 			for notice in notices_accessor.notices:
-				_log.debug(notice.strip(u'\n').strip(u'\r'))
+				_log.debug(unicode(notice, 'utf8', 'replace').strip(u'\n').strip(u'\r'))
 			del notices_accessor.notices[:]
 			gmLog2.log_stack_trace()
 			try:
@@ -2289,30 +2297,30 @@ def sanity_check_database_settings():
 
 	options2check = {
 		# setting: [expected value, risk, fatal?]
-		u'allow_system_table_mods': [u'off', u'system breakage', False],
-		u'check_function_bodies': [u'on', u'suboptimal error detection', False],
-		u'datestyle': [u'ISO', u'faulty timestamp parsing', True],
-		u'default_transaction_isolation': [u'read committed', u'faulty database reads', True],
-		u'default_transaction_read_only': [u'on', u'accidental database writes', False],
-		u'fsync': [u'on', u'data loss/corruption', True],
-		u'full_page_writes': [u'on', u'data loss/corruption', False],
-		u'lc_messages': [u'C', u'suboptimal error detection', False],
-		u'password_encryption': [u'on', u'breach of confidentiality', False],
-		#u'regex_flavor': [u'advanced', u'query breakage', False],					# 9.0 doesn't support this anymore, default now advanced anyway
-		u'synchronous_commit': [u'on', u'data loss/corruption', False],
-		u'sql_inheritance': [u'on', u'query breakage, data loss/corruption', True],
-		u'ignore_checksum_failure': [u'off', u'data loss/corruption', False],		# starting with PG 9.3
-		u'track_commit_timestamp': [u'on', u'suboptimal auditing', False]			# starting with PG 9.3
+		u'allow_system_table_mods': [[u'off'], u'system breakage', False],
+		u'check_function_bodies': [[u'on'], u'suboptimal error detection', False],
+		u'datestyle': [[u'ISO'], u'faulty timestamp parsing', True],
+		u'default_transaction_isolation': [[u'read committed'], u'faulty database reads', True],
+		u'default_transaction_read_only': [[u'on'], u'accidental database writes', False],
+		u'fsync': [[u'on'], u'data loss/corruption', True],
+		u'full_page_writes': [[u'on'], u'data loss/corruption', False],
+		u'lc_messages': [[u'C'], u'suboptimal error detection', False],
+		u'password_encryption': [[u'on', u'md5', u'scram-sha-256'], u'breach of confidentiality', False],
+		#u'regex_flavor': [[u'advanced'], u'query breakage', False],					# 9.0 doesn't support this anymore, default now advanced anyway
+		u'synchronous_commit': [[u'on'], u'data loss/corruption', False],
+		u'sql_inheritance': [[u'on'], u'query breakage, data loss/corruption', True],	# IF returned (<PG10): better be ON, if NOT returned (PG10): hardwired
+		u'ignore_checksum_failure': [[u'off'], u'data loss/corruption', False],		# starting with PG 9.3
+		u'track_commit_timestamp': [[u'on'], u'suboptimal auditing', False]			# starting with PG 9.3
 	}
 
 	from Gnumed.pycommon import gmCfg2
 	_cfg = gmCfg2.gmCfgData()
 	if _cfg.get(option = u'hipaa'):
-		options2check[u'log_connections'] = [u'on', u'non-compliance with HIPAA', True]
-		options2check[u'log_disconnections'] = [u'on', u'non-compliance with HIPAA', True]
+		options2check[u'log_connections'] = [[u'on'], u'non-compliance with HIPAA', True]
+		options2check[u'log_disconnections'] = [[u'on'], u'non-compliance with HIPAA', True]
 	else:
-		options2check[u'log_connections'] = [u'on', u'non-compliance with HIPAA', None]
-		options2check[u'log_disconnections'] = [u'on', u'non-compliance with HIPAA', None]
+		options2check[u'log_connections'] = [[u'on'], u'non-compliance with HIPAA', None]
+		options2check[u'log_disconnections'] = [[u'on'], u'non-compliance with HIPAA', None]
 
 	cmd = u"SELECT name, setting from pg_settings where name in %(settings)s"
 	rows, idx = run_ro_queries (
@@ -2327,10 +2335,10 @@ def sanity_check_database_settings():
 	for row in rows:
 		option = row['name']
 		value_found = row['setting']
-		value_expected = options2check[option][0]
+		values_expected = options2check[option][0]
 		risk = options2check[option][1]
 		fatal_setting = options2check[option][2]
-		if value_found != value_expected:
+		if value_found not in values_expected:
 			if fatal_setting is True:
 				found_error = True
 			elif fatal_setting is False:
@@ -2342,7 +2350,7 @@ def sanity_check_database_settings():
 				raise ValueError(u'invalid database configuration sanity check')
 			msg.append(_(' option [%s]: %s') % (option, value_found))
 			msg.append(_('  risk: %s') % risk)
-			_log.warning('PG option [%s] set to [%s], expected [%s], risk: <%s>' % (option, value_found, value_expected, risk))
+			_log.warning('PG option [%s] set to [%s], expected %s, risk: <%s>' % (option, value_found, values_expected, risk))
 
 	if found_error:
 		return 2, u'\n'.join(msg)
@@ -2491,27 +2499,6 @@ class cAdapterPyDateTime(object):
 	def getquoted(self):
 		return _timestamp_template % self.__dt.isoformat()
 
-## remove for 0.9
-## ----------------------------------------------------------------------
-##class cAdapterMxDateTime(object):
-##
-##	def __init__(self, dt):
-##		if dt.tz == '???':
-##			_log.info('[%s]: no time zone string available in (%s), assuming local time zone', self.__class__.__name__, dt)
-##		self.__dt = dt
-##
-##	def getquoted(self):
-##		# under some locale settings the mx.DateTime ISO formatter
-##		# will insert "," into the ISO string,
-##		# while this is allowed per the ISO8601 spec PostgreSQL
-##		# cannot currently handle that,
-##		# so map those "," to "." to make things work:
-##		return mxDT.ISO.str(self.__dt).replace(',', '.')
-##
-## ----------------------------------------------------------------------
-## PostgreSQL -> Python
-## ----------------------------------------------------------------------
-
 #=======================================================================
 #  main
 #-----------------------------------------------------------------------
diff --git a/server/pycommon/gmPsql.py b/server/pycommon/gmPsql.py
index ad1b963..682d034 100644
--- a/server/pycommon/gmPsql.py
+++ b/server/pycommon/gmPsql.py
@@ -9,28 +9,16 @@ __author__ = "Ian Haywood"
 __license__ = "GPL v2 or later (details at http://www.gnu.org)"
 
 # stdlib
-import sys, os, string, re, urllib2, logging, io
+import sys
+import os
+import re
+import logging
+import io
 
 
 _log = logging.getLogger('gm.bootstrapper')
 
 unformattable_error_id = 12345
-#===================================================================
-def shellrun (cmd):
-	"""
-	runs the shell command and returns a string
-	"""
-	stdin, stdout = os.popen4 (cmd.group (1))
-	r = stdout.read ()
-	stdout.close()
-	stdin.close()
-	return r
-#-------------------------------------------------------------------
-def shell(str):
-	"""
-	performs backtick shell extension in a string
-	"""
-	return re.sub (r"`(.*)`", shellrun, str)
 
 #===================================================================
 class Psql:
@@ -40,17 +28,16 @@ class Psql:
 		db : the interpreter to connect to, must be a DBAPI compliant interface
 		"""
 		self.conn = conn
-		self.vars = {'ON_ERROR_STOP':None}
+		self.vars = {'ON_ERROR_STOP': None}
 
 	#---------------------------------------------------------------
-	def match (self, str):
-		match = re.match (str, self.line)
+	def match(self, pattern):
+		match = re.match(pattern, self.line)
 		if match is None:
-			ret = 0
-		else:
-			ret = 1
-			self.groups = match.groups ()
-		return ret
+			return 0
+
+		self.groups = match.groups()
+		return 1
 
 	#---------------------------------------------------------------
 	def fmt_msg(self, aMsg):
@@ -74,18 +61,17 @@ class Psql:
 		filename: a file, containg semicolon-separated SQL commands
 		"""
 		_log.debug('processing [%s]', filename)
-		if re.match ("http://.*", filename) or re.match ("ftp://.*", filename) or re.match ("gopher://.*", filename):
-			try:
-				self.file = urllib2.urlopen (filename)
-			except URLError:
-				_log.error(u"cannot access [%s]", filename)
-				return 1
+		curs = self.conn.cursor()
+		curs.execute(u'show session authorization')
+		start_auth = curs.fetchall()[0][0]
+		curs.close()
+		_log.debug(u'session auth: %s', start_auth)
+
+		if os.access (filename, os.R_OK):
+			sql_file = io.open(filename, mode = 'rt', encoding = 'utf8')
 		else:
-			if os.access (filename, os.R_OK):
-				self.file = io.open(filename, mode = 'rt', encoding = 'utf8')
-			else:
-				_log.error(u"cannot open file [%s]", filename)
-				return 1
+			_log.error(u"cannot open file [%s]", filename)
+			return 1
 
 		self.lineno = 0
 		self.filename = filename
@@ -94,31 +80,18 @@ class Psql:
 		curr_cmd = ''
 		curs = self.conn.cursor()
 
-		for self.line in self.file.readlines():
+		for self.line in sql_file.readlines():
 			self.lineno += 1
 			if len(self.line.strip()) == 0:
 				continue
 
-			# \echo
-			if self.match (r"^\\echo (.*)"):
-				_log.info(self.fmt_msg(shell(self.groups[0])))
-				continue
-
-			# \qecho
-			if self.match (r"^\\qecho (.*)"):
-				_log.info(self.fmt_msg(shell (self.groups[0])))
-				continue
-
-			# \q
-			if self.match (r"^\\q"):
-				_log.warning(self.fmt_msg(u"script terminated by \\q"))
-				return 0
-
 			# \set
-			if self.match (r"^\\set (\S+) (\S+)"):
-				self.vars[self.groups[0]] = shell (self.groups[1])
+			if self.match(r"^\\set (\S+) (\S+)"):
+				_log.debug(u'"\set" found: %s', self.groups)
+				self.vars[self.groups[0]] = self.groups[1]
 				if self.groups[0] == 'ON_ERROR_STOP':
-					self.vars['ON_ERROR_STOP'] = int (self.vars['ON_ERROR_STOP'])
+					# adjusting from string to int so that "1" -> 1 -> True
+					self.vars['ON_ERROR_STOP'] = int(self.vars['ON_ERROR_STOP'])
 				continue
 
 			# \unset
@@ -142,7 +115,7 @@ class Psql:
 				if this_char == "'":
 					in_string = not in_string
 
-				# detect -- style comments
+				# detect "--"-style comments
 				if this_char == '-' and next_char == '-' and not in_string:
 					break
 
@@ -152,31 +125,39 @@ class Psql:
 				if this_char == ')' and not in_string:
 					bracketlevel -= 1
 
-				# found end of command, not inside string, not inside bracket ?
-				if not (not in_string and (bracketlevel == 0) and (this_char == ';')):
+				# have we:
+				# - found end of command ?
+				# - are not inside a string ?
+				# - are not inside bracket pair ?
+				if not ((in_string is False) and (bracketlevel == 0) and (this_char == ';')):
 					curr_cmd += this_char
 				else:
-					try:
-						if curr_cmd.strip() != '':
-							curs.execute (curr_cmd)
-					except Exception as error:
-						_log.exception(curr_cmd)
-						if re.match (r"^NOTICE:.*", str(error)):
-							_log.warning(self.fmt_msg(error))
-						else:
-							_log.error(self.fmt_msg(error))
-							if hasattr(error, 'diag'):
-								for prop in dir(error.diag):
-									if prop.startswith(u'__'):
-										continue
-									val = getattr(error.diag, prop)
-									if val is None:
-										continue
-									_log.error(u'PG diags %s: %s', prop, val)
-							if self.vars['ON_ERROR_STOP']:
-								self.conn.commit()
-								curs.close()
-								return 1
+					if curr_cmd.strip() != '':
+						try:
+							curs.execute(curr_cmd)
+							try:
+								data = curs.fetchall()
+								_log.debug(u'cursor data: %s', data)
+							except StandardError:	# actually: psycopg2.ProgrammingError but no handle
+								pass
+						except Exception as error:
+							_log.exception(curr_cmd)
+							if re.match(r"^NOTICE:.*", str(error)):
+								_log.warning(self.fmt_msg(error))
+							else:
+								_log.error(self.fmt_msg(error))
+								if hasattr(error, 'diag'):
+									for prop in dir(error.diag):
+										if prop.startswith(u'__'):
+											continue
+										val = getattr(error.diag, prop)
+										if val is None:
+											continue
+										_log.error(u'PG diags %s: %s', prop, val)
+								if self.vars['ON_ERROR_STOP']:
+									self.conn.commit()
+									curs.close()
+									return 1
 
 					self.conn.commit()
 					curs.close()
@@ -184,12 +165,17 @@ class Psql:
 					curr_cmd = ''
 
 				this_char = next_char
-
 			# end of loop over chars
 
 		# end of loop over lines
 		self.conn.commit()
+		curs.execute(u'show session authorization')
+		end_auth = curs.fetchall()[0][0]
 		curs.close()
+		_log.debug(u'session auth after sql file processing: %s', end_auth)
+		if start_auth != end_auth:
+			_log.error('session auth changed before/after processing sql file')
+
 		return 0
 
 #===================================================================
@@ -203,7 +189,7 @@ if __name__ == '__main__':
 		sys.exit()
 
 	#from pyPgSQL import PgSQL
-	conn = PgSQL.connect (user='gm-dbo', database = 'gnumed')
-	psql = Psql (conn)
-	psql.run (sys.argv[1])
-	conn.close ()
+	conn = PgSQL.connect(user='gm-dbo', database = 'gnumed')
+	psql = Psql(conn)
+	psql.run(sys.argv[1])
+	conn.close()
diff --git a/server/sql/gmAudit-dynamic.sql b/server/sql/gmAudit-dynamic.sql
index 87e14f0..c8cf42b 100644
--- a/server/sql/gmAudit-dynamic.sql
+++ b/server/sql/gmAudit-dynamic.sql
@@ -48,7 +48,7 @@ comment on column audit.audit_trail.audit_by is
 
 -- ===================================================================
 create or replace function audit.add_table_for_audit(name, name)
-	returns unknown
+	returns boolean
 	language 'plpgsql'
 	security definer
 	as '
@@ -87,7 +87,7 @@ comment on function audit.add_table_for_audit (name, name) is
 
 
 create or replace function audit.add_table_for_audit(name)
-	returns unknown
+	returns boolean
 	language SQL
 	security definer
 	as '
diff --git a/server/sql/gmI18N-dynamic.sql b/server/sql/gmI18N-dynamic.sql
index 5cc0d7f..2455a52 100644
--- a/server/sql/gmI18N-dynamic.sql
+++ b/server/sql/gmI18N-dynamic.sql
@@ -162,7 +162,7 @@ comment on function _(text, text) is
 
 -- =============================================
 create or replace function i18n.set_curr_lang(text)
-	returns unknown
+	returns boolean
 	language 'plpgsql'
 	security definer
 	as '
@@ -186,7 +186,7 @@ comment on function i18n.set_curr_lang(text) is
 
 -- =============================================
 create or replace function i18n.force_curr_lang(text)
-	returns unknown
+	returns boolean
 	language 'plpgsql'
 	security definer
 	as '
@@ -260,96 +260,3 @@ TO group "gm-public";
 -- =============================================
 -- do simple schema revision tracking
 select log_script_insertion('$RCSfile: gmI18N-dynamic.sql,v $', '$Revision: 1.5 $');
-
--- =============================================
--- $Log: gmI18N-dynamic.sql,v $
--- Revision 1.5  2006-07-24 14:18:52  ncq
--- - add comment
---
--- Revision 1.4  2006/07/01 15:22:03  ncq
--- - do not hard-fail set_curr_lang()
---
--- Revision 1.3  2006/02/06 13:18:27  ncq
--- - quote user when column name
---
--- Revision 1.2  2006/01/10 08:44:22  ncq
--- - drop index does not require "on"
---
--- Revision 1.1  2006/01/09 13:42:29  ncq
--- - factor out dynamic stuff
--- - move into schema "i18n" (except for _())
---
--- Revision 1.23  2005/09/19 16:38:51  ncq
--- - adjust to removed is_core from gm_schema_revision
---
--- Revision 1.22  2005/07/14 21:31:42  ncq
--- - partially use improved schema revision tracking
---
--- Revision 1.21  2005/07/04 11:42:24  ncq
--- - fix _(text, text)
---
--- Revision 1.20  2005/03/31 20:08:38  ncq
--- - add i18n_upd_tx() for safe update of translations
---
--- Revision 1.19  2005/03/01 20:38:19  ncq
--- - varchar -> text
---
--- Revision 1.18  2005/02/03 20:28:25  ncq
--- - improved comments
--- - added _(text, text)
---
--- Revision 1.17  2005/02/01 16:52:50  ncq
--- - added force_curr_lang()
---
--- Revision 1.16  2004/07/17 20:57:53  ncq
--- - don't use user/_user workaround anymore as we dropped supporting
---   it (but we did NOT drop supporting readonly connections on > 7.3)
---
--- Revision 1.15  2003/12/29 15:40:42  uid66147
--- - added not null
--- - added v_missing_translations
---
--- Revision 1.14  2003/06/10 09:58:11  ncq
--- - i18n() inserts strings into i18n_keys, not _(), fix comment to that effect
---
--- Revision 1.13  2003/05/12 12:43:39  ncq
--- - gmI18N, gmServices and gmSchemaRevision are imported globally at the
---   database level now, don't include them in individual schema file anymore
---
--- Revision 1.12  2003/05/02 15:06:44  ncq
--- - fix comment
---
--- Revision 1.11  2003/04/23 08:36:00  michaelb
--- made i18n_curr_lang longer still (11 to 15)
---
--- Revision 1.9  2003/02/04 13:22:01  ncq
--- - refined set_curr_lang to only work if translations available
--- - also auto-set for both "user" and "_user"
---
--- Revision 1.8  2003/02/04 12:22:52  ncq
--- - valid until in create user cannot do a sub-query :-(
--- - columns "owner" should really be of type "name" if defaulting to "CURRENT_USER"
--- - new functions set_curr_lang(*)
---
--- Revision 1.7  2003/01/24 14:16:18  ncq
--- - don't drop functions repeatedly since that will kill views created earlier
---
--- Revision 1.6  2003/01/20 20:21:53  ncq
--- - keep the last useful bit from i18n.sql as documentation
---
--- Revision 1.5  2003/01/20 19:42:47  ncq
--- - simplified creation of translating view a lot
---
--- Revision 1.4  2003/01/17 00:24:33  ncq
--- - add a few access right definitions
---
--- Revision 1.3  2003/01/05 13:05:51  ncq
--- - schema_revision -> gm_schema_revision
---
--- Revision 1.2  2003/01/04 10:30:26  ncq
--- - better documentation
--- - insert default english "translation" into i18n_translations
---
--- Revision 1.1  2003/01/01 17:41:57  ncq
--- - improved database i18n
---
diff --git a/server/sql/gmI18N.sql b/server/sql/gmI18N.sql
index 2de733a..3ac6555 100644
--- a/server/sql/gmI18N.sql
+++ b/server/sql/gmI18N.sql
@@ -58,87 +58,3 @@ create table i18n.translations (
 -- =============================================
 -- do simple schema revision tracking
 select log_script_insertion('$RCSfile: gmI18N.sql,v $', '$Revision: 1.25 $');
-
--- =============================================
--- $Log: gmI18N.sql,v $
--- Revision 1.25  2006-02-10 14:06:40  ncq
--- - proper script insertion logging
---
--- Revision 1.24  2006/01/09 13:42:29  ncq
--- - factor out dynamic stuff
--- - move into schema "i18n" (except for _())
---
--- Revision 1.23  2005/09/19 16:38:51  ncq
--- - adjust to removed is_core from gm_schema_revision
---
--- Revision 1.22  2005/07/14 21:31:42  ncq
--- - partially use improved schema revision tracking
---
--- Revision 1.21  2005/07/04 11:42:24  ncq
--- - fix _(text, text)
---
--- Revision 1.20  2005/03/31 20:08:38  ncq
--- - add i18n_upd_tx() for safe update of translations
---
--- Revision 1.19  2005/03/01 20:38:19  ncq
--- - varchar -> text
---
--- Revision 1.18  2005/02/03 20:28:25  ncq
--- - improved comments
--- - added _(text, text)
---
--- Revision 1.17  2005/02/01 16:52:50  ncq
--- - added force_curr_lang()
---
--- Revision 1.16  2004/07/17 20:57:53  ncq
--- - don't use user/_user workaround anymore as we dropped supporting
---   it (but we did NOT drop supporting readonly connections on > 7.3)
---
--- Revision 1.15  2003/12/29 15:40:42  uid66147
--- - added not null
--- - added v_missing_translations
---
--- Revision 1.14  2003/06/10 09:58:11  ncq
--- - i18n() inserts strings into i18n_keys, not _(), fix comment to that effect
---
--- Revision 1.13  2003/05/12 12:43:39  ncq
--- - gmI18N, gmServices and gmSchemaRevision are imported globally at the
---   database level now, don't include them in individual schema file anymore
---
--- Revision 1.12  2003/05/02 15:06:44  ncq
--- - fix comment
---
--- Revision 1.11  2003/04/23 08:36:00  michaelb
--- made i18n_curr_lang longer still (11 to 15)
---
--- Revision 1.9  2003/02/04 13:22:01  ncq
--- - refined set_curr_lang to only work if translations available
--- - also auto-set for both "user" and "_user"
---
--- Revision 1.8  2003/02/04 12:22:52  ncq
--- - valid until in create user cannot do a sub-query :-(
--- - columns "owner" should really be of type "name" if defaulting to "CURRENT_USER"
--- - new functions set_curr_lang(*)
---
--- Revision 1.7  2003/01/24 14:16:18  ncq
--- - don't drop functions repeatedly since that will kill views created earlier
---
--- Revision 1.6  2003/01/20 20:21:53  ncq
--- - keep the last useful bit from i18n.sql as documentation
---
--- Revision 1.5  2003/01/20 19:42:47  ncq
--- - simplified creation of translating view a lot
---
--- Revision 1.4  2003/01/17 00:24:33  ncq
--- - add a few access right definitions
---
--- Revision 1.3  2003/01/05 13:05:51  ncq
--- - schema_revision -> gm_schema_revision
---
--- Revision 1.2  2003/01/04 10:30:26  ncq
--- - better documentation
--- - insert default english "translation" into i18n_translations
---
--- Revision 1.1  2003/01/01 17:41:57  ncq
--- - improved database i18n
---
diff --git a/server/sql/v10-v11/dynamic/v11-i18n-force_curr_lang.sql b/server/sql/v10-v11/dynamic/v11-i18n-force_curr_lang.sql
index 4afef58..226cf38 100644
--- a/server/sql/v10-v11/dynamic/v11-i18n-force_curr_lang.sql
+++ b/server/sql/v10-v11/dynamic/v11-i18n-force_curr_lang.sql
@@ -20,7 +20,7 @@ drop function i18n.force_curr_lang(text, name) cascade;
 
 
 create or replace function i18n.force_curr_lang(text, name)
-	returns unknown
+	returns boolean
 	language 'plpgsql'
 	security definer
 	as E'
@@ -41,7 +41,7 @@ comment on function i18n.force_curr_lang(text, name) is
 
 -- =============================================
 create or replace function i18n.force_curr_lang(text)
-	returns unknown
+	returns boolean
 	language 'plpgsql'
 	as '
 DECLARE
diff --git a/server/sql/v14-v15/dynamic/v15-clin-v_pat_substance_intake.sql b/server/sql/v14-v15/dynamic/v15-clin-v_pat_substance_intake.sql
index d2e69d7..6dac3a8 100644
--- a/server/sql/v14-v15/dynamic/v15-clin-v_pat_substance_intake.sql
+++ b/server/sql/v14-v15/dynamic/v15-clin-v_pat_substance_intake.sql
@@ -121,7 +121,7 @@ select
 	(select fk_patient from clin.encounter where pk = c_si.fk_encounter)
 		as pk_patient,
 	c_si.soap_cat,
-	null
+	null::text
 		as brand,
 	c_si.preparation,
 	r_cs.description
@@ -131,11 +131,11 @@ select
 		as unit,
 	r_cs.atc_code
 		as atc_substance,
-	null
+	null::text
 		as atc_brand,
-	null
+	null::text
 		as external_code_brand,
-	null
+	null::text
 		as external_code_type_brand,
 
 	c_si.clin_when
@@ -151,7 +151,7 @@ select
 		as episode,
 	c_si.narrative
 		as notes,
-	null
+	null::boolean
 		as fake_brand,
 	-- currently active ?
 	case
@@ -177,13 +177,13 @@ select
 		else null
 	end::boolean
 		as seems_inactive,
-	null
+	null::integer
 		as pk_brand,
-	null
+	null::integer
 		as pk_data_source,
 	r_cs.pk
 		as pk_substance,
-	null
+	null::integer
 		as pk_drug_component,
 	c_si.fk_encounter
 		as pk_encounter,
diff --git a/server/sql/v15-v16/dynamic/v16-db-default_settings.sql b/server/sql/v15-v16/dynamic/v16-db-default_settings.sql
index fd57475..43f332a 100644
--- a/server/sql/v15-v16/dynamic/v16-db-default_settings.sql
+++ b/server/sql/v15-v16/dynamic/v16-db-default_settings.sql
@@ -14,10 +14,9 @@ ALTER DATABASE gnumed_v16
 ALTER DATABASE gnumed_v16
 	SET default_transaction_isolation to 'read committed';
 
-ALTER DATABASE gnumed_v16
-	SET sql_inheritance to 'on';
+-- does not exist on PG10 anymore, so can't be set if bootstrapping on PG10
+--ALTER DATABASE gnumed_v16
+--	SET sql_inheritance to 'on';
 
 -- --------------------------------------------------------------
 select gm.log_script_insertion('v16-db-default_settings.sql', 'v16');
-
--- ==============================================================
\ No newline at end of file
diff --git a/server/sql/v16-v17/dynamic/v17-clin-v_pat_substance_intake.sql b/server/sql/v16-v17/dynamic/v17-clin-v_pat_substance_intake.sql
index 9dc74d6..027f5bd 100644
--- a/server/sql/v16-v17/dynamic/v17-clin-v_pat_substance_intake.sql
+++ b/server/sql/v16-v17/dynamic/v17-clin-v_pat_substance_intake.sql
@@ -123,7 +123,7 @@ select
 	(select fk_patient from clin.encounter where pk = c_si.fk_encounter)
 		as pk_patient,
 	c_si.soap_cat,
-	null
+	null::text
 		as brand,
 	c_si.preparation,
 	r_cs.description
@@ -133,11 +133,11 @@ select
 		as unit,
 	r_cs.atc_code
 		as atc_substance,
-	null
+	null::text
 		as atc_brand,
-	null
+	null::text
 		as external_code_brand,
-	null
+	null::text
 		as external_code_type_brand,
 
 	c_si.clin_when
@@ -155,7 +155,7 @@ select
 		as health_issue,
 	c_si.narrative
 		as notes,
-	null
+	null::boolean
 		as fake_brand,
 	-- currently active ?
 	case
@@ -181,13 +181,13 @@ select
 		else null
 	end::boolean
 		as seems_inactive,
-	null
+	null::integer
 		as pk_brand,
-	null
+	null::integer
 		as pk_data_source,
 	r_cs.pk
 		as pk_substance,
-	null
+	null::integer
 		as pk_drug_component,
 	c_si.fk_encounter
 		as pk_encounter,
diff --git a/server/sql/v16-v17/fixups/v17-blobs-doc_obj-fixup.sql b/server/sql/v16-v17/fixups/v17-blobs-doc_obj-fixup.sql
index 26a16a0..b67a033 100644
--- a/server/sql/v16-v17/fixups/v17-blobs-doc_obj-fixup.sql
+++ b/server/sql/v16-v17/fixups/v17-blobs-doc_obj-fixup.sql
@@ -8,14 +8,12 @@
 \set ON_ERROR_STOP 1
 
 -- --------------------------------------------------------------
-\unset ON_ERROR_STOP
 -- very old:
-alter table blobs.doc_obj drop constraint "$1" cascade;
+alter table blobs.doc_obj drop constraint if exists "$1" cascade;
 -- medium age:
-alter table blobs.doc_obj drop constraint doc_obj_doc_id_fkey cascade;
+alter table blobs.doc_obj drop constraint if exists doc_obj_doc_id_fkey cascade;
 -- current:
-alter table blobs.doc_obj drop constraint doc_obj_fk_doc_fkey cascade;
-\set ON_ERROR_STOP 1
+alter table blobs.doc_obj drop constraint if exists doc_obj_fk_doc_fkey cascade;
 
 -- recreate:
 alter table blobs.doc_obj
diff --git a/server/sql/v16-v17/fixups/v17-clin-v_waiting_list-fixup.sql b/server/sql/v16-v17/fixups/v17-clin-v_waiting_list-fixup.sql
index 6fcc7c4..a8ed0fe 100644
--- a/server/sql/v16-v17/fixups/v17-clin-v_waiting_list-fixup.sql
+++ b/server/sql/v16-v17/fixups/v17-clin-v_waiting_list-fixup.sql
@@ -6,9 +6,6 @@
 --
 -- ==============================================================
 \set ON_ERROR_STOP 1
-set check_function_bodies to on;
-
---set default_transaction_read_only to off;
 
 -- --------------------------------------------------------------
 \unset ON_ERROR_STOP
diff --git a/server/sql/v17-v18/dynamic/v18-i18n-fr_FR_translations.sql b/server/sql/v17-v18/dynamic/v18-i18n-fr_FR_translations.sql
index 55e190e..2fc0a81 100644
--- a/server/sql/v17-v18/dynamic/v18-i18n-fr_FR_translations.sql
+++ b/server/sql/v17-v18/dynamic/v18-i18n-fr_FR_translations.sql
@@ -15,7 +15,7 @@
 
 \unset ON_ERROR_STOP
 
-set client_encoding 'utf8';
+set client_encoding to 'utf8';
 
 select i18n.upd_tx(quote_literal(E'fr'), quote_literal(E'British Columbia'), quote_literal(E'Colombie-Britannique'));
 select i18n.upd_tx(quote_literal(E'fr'), quote_literal(E'New Brunswick'), quote_literal(E'Nouveau-Brunswick'));
diff --git a/server/sql/v17-v18/dynamic/v18-i18n-ru_RU_translations.sql b/server/sql/v17-v18/dynamic/v18-i18n-ru_RU_translations.sql
index 7e4d189..ca37ad9 100644
--- a/server/sql/v17-v18/dynamic/v18-i18n-ru_RU_translations.sql
+++ b/server/sql/v17-v18/dynamic/v18-i18n-ru_RU_translations.sql
@@ -15,7 +15,7 @@
 
 \unset ON_ERROR_STOP
 
-set client_encoding 'utf8';
+set client_encoding to 'utf8';
 
 select i18n.upd_tx(quote_literal(E'ru'), quote_literal(E'cause of death'), quote_literal(E'причина смерти'));
 select i18n.upd_tx(quote_literal(E'ru_RU'), quote_literal(E'Abakan'), quote_literal(E'Абакан'));
diff --git a/server/sql/v18-v19/dynamic/v19-clin-v_substance_intakes.sql b/server/sql/v18-v19/dynamic/v19-clin-v_substance_intakes.sql
index 0f2b7a9..d9c5ae5 100644
--- a/server/sql/v18-v19/dynamic/v19-clin-v_substance_intakes.sql
+++ b/server/sql/v18-v19/dynamic/v19-clin-v_substance_intakes.sql
@@ -129,7 +129,7 @@ select
 	(select fk_patient from clin.encounter where pk = c_si.fk_encounter)
 		as pk_patient,
 	c_si.soap_cat,
-	null
+	null::text
 		as brand,
 	c_si.preparation,
 	r_cs.description
@@ -139,11 +139,11 @@ select
 		as unit,
 	r_cs.atc_code
 		as atc_substance,
-	null
+	null::text
 		as atc_brand,
-	null
+	null::text
 		as external_code_brand,
-	null
+	null::text
 		as external_code_type_brand,
 
 	c_si.clin_when
@@ -161,7 +161,7 @@ select
 		as health_issue,
 	c_si.narrative
 		as notes,
-	null
+	null::boolean
 		as fake_brand,
 	-- currently active ?
 	case
@@ -187,13 +187,13 @@ select
 		else null
 	end::boolean
 		as seems_inactive,
-	null
+	null::integer
 		as pk_brand,
-	null
+	null::integer
 		as pk_data_source,
 	r_cs.pk
 		as pk_substance,
-	null
+	null::integer
 		as pk_drug_component,
 	c_si.fk_encounter
 		as pk_encounter,
diff --git a/server/sql/v20-v21/dynamic/v21-clin-v_substance_intakes.sql b/server/sql/v20-v21/dynamic/v21-clin-v_substance_intakes.sql
index 6db6e2b..c90f1ad 100644
--- a/server/sql/v20-v21/dynamic/v21-clin-v_substance_intakes.sql
+++ b/server/sql/v20-v21/dynamic/v21-clin-v_substance_intakes.sql
@@ -139,7 +139,7 @@ select
 	(select fk_patient from clin.encounter where pk = c_si.fk_encounter)
 		as pk_patient,
 	c_si.soap_cat,
-	null
+	null::text
 		as brand,
 	c_si.preparation,
 	r_cs.description
@@ -149,11 +149,11 @@ select
 		as unit,
 	r_cs.atc_code
 		as atc_substance,
-	null
+	null::text
 		as atc_brand,
-	null
+	null::text
 		as external_code_brand,
-	null
+	null::text
 		as external_code_type_brand,
 
 	-- uncertainty of start
@@ -192,7 +192,7 @@ select
 		as health_issue,
 	c_si.narrative
 		as notes,
-	null
+	null::boolean
 		as fake_brand,
 	-- currently active ?
 	case
@@ -218,13 +218,13 @@ select
 		else null
 	end::boolean
 		as seems_inactive,
-	null
+	null::integer
 		as pk_brand,
-	null
+	null::integer
 		as pk_data_source,
 	r_cs.pk
 		as pk_substance,
-	null
+	null::integer
 		as pk_drug_component,
 	c_si.fk_encounter
 		as pk_encounter,
@@ -416,4 +416,4 @@ INSERT INTO clin.substance_intake (
 ;
 
 -- --------------------------------------------------------------
-select gm.log_script_insertion('v21-clin-v_substance_intakes.sql', '21.0');
+select gm.log_script_insertion('v21-clin-v_substance_intakes.sql', '21.15');
diff --git a/server/sql/v20-v21/dynamic/v21-release_notes-dynamic.sql b/server/sql/v20-v21/dynamic/v21-release_notes-dynamic.sql
index 253a1d8..4c71927 100644
--- a/server/sql/v20-v21/dynamic/v21-release_notes-dynamic.sql
+++ b/server/sql/v20-v21/dynamic/v21-release_notes-dynamic.sql
@@ -17,24 +17,27 @@ INSERT INTO dem.message_inbox (
 ) VALUES (
 	(select pk from dem.staff where db_user = 'any-doc'),
 	(select pk_type from dem.v_inbox_item_type where type = 'memo' and category = 'administrative'),
-	'Release Notes for GNUmed 1.6.14 (database v21.14)',
-	'GNUmed 1.6.14 Release Notes:
-
-	1.6.14
-
-FIX: exception when having issues with calculating eGFR in medication plugin
-FIX: exception on disabling identity [thanks Marc]
-FIX: exception on adding archived documents to export area
-FIX: Orthanc DICOM patient ID modification
-FIX: faulty file drop target declarations
-
-IMPROVED: saving of export area items
-IMPROVED: patient display in provider inbox
-IMPROVED: copy document to export area from document plugin
-IMPROVED: Orthanc modification dialog title
-IMPROVED: imported documents deletion confirmation
-IMPROVED: patient media metadata
+	'Release Notes for GNUmed 1.6.15 (database v21.15)',
+	'GNUmed 1.6.15 Release Notes:
+
+	1.6.15
+
+FIX: exception on tooltipping patient overview inbox item
+FIX: exception in cursor/connection state logging w/ older psycopg2s
+FIX: exception on import error inside portable app
+
+IMPROVED: use Dicom[RequestingPhysician] if available
+IMPROVED: user visible rendering of raw DICOM strings
+IMPROVED: baptize SCRAM for PG passwords in settings check
+
+	21.15
+
+FIX: handle SQL_INHERITANCE in a way compatible with PG10
+FIX: untyped UNIONs not tolerated by PG10 anymore
+FIX: RETURNS UNKNOWN functions not tolerated by PG10 anymore
+
+IMPROVED: script to adjust db settings
 ');
 
 -- --------------------------------------------------------------
-select gm.log_script_insertion('v21-release_notes-dynamic.sql', '21.14');
+select gm.log_script_insertion('v21-release_notes-dynamic.sql', '21.15');
diff --git a/server/sql/v20-v21/fixups/v21-audit-add_table_for_audit-fixup.sql b/server/sql/v20-v21/fixups/v21-audit-add_table_for_audit-fixup.sql
new file mode 100644
index 0000000..b37f7fa
--- /dev/null
+++ b/server/sql/v20-v21/fixups/v21-audit-add_table_for_audit-fixup.sql
@@ -0,0 +1,62 @@
+-- GNUmed auditing functionality
+-- ===================================================================
+-- license: GPL v2 or later
+-- author: Karsten Hilbert
+
+-- ===================================================================
+-- force terminate + exit(3) on errors if non-interactive
+\set ON_ERROR_STOP 1
+
+-- --------------------------------------------------------------
+create or replace function audit.add_table_for_audit(name, name)
+	returns boolean
+	language 'plpgsql'
+	security definer
+	as '
+DECLARE
+	_relnamespace alias for $1;
+	_relname ALIAS FOR $2;
+	dummy RECORD;
+	tmp text;
+BEGIN
+	-- does table exist ?
+	select relname into dummy from pg_class where
+		relname = _relname and
+		relnamespace = (select oid from pg_namespace where nspname = _relnamespace)
+	;
+	if not found then
+		tmp := _relnamespace || ''.'' || _relname;
+		raise exception ''audit.add_table_for_audit: Table [%] does not exist.'', tmp;
+		return false;
+	end if;
+	-- already queued for auditing ?
+	select 1 into dummy from audit.audited_tables where table_name = _relname and schema = _relnamespace;
+	if found then
+		return true;
+	end if;
+	-- add definition
+	insert into audit.audited_tables (
+		schema, table_name
+	) values (
+		_relnamespace, _relname
+	);
+	return true;
+END;';
+
+comment on function audit.add_table_for_audit (name, name) is
+	'sanity-checking convenience function for marking tables for auditing';
+
+
+create or replace function audit.add_table_for_audit(name)
+	returns boolean
+	language SQL
+	security definer
+	as '
+select audit.add_table_for_audit(''public'', $1);';
+
+comment on function audit.add_table_for_audit(name) is
+	'sanity-checking convenience function for marking tables
+	 for auditing, schema is always "public"';
+
+-- --------------------------------------------------------------
+select gm.log_script_insertion('v21-audit-add_table_for_audit-fixup.sql', '21.15');
diff --git a/server/sql/v20-v21/fixups/v21-clin-v_substance_intakes-fixup.sql b/server/sql/v20-v21/fixups/v21-clin-v_substance_intakes-fixup.sql
new file mode 100644
index 0000000..4dc7753
--- /dev/null
+++ b/server/sql/v20-v21/fixups/v21-clin-v_substance_intakes-fixup.sql
@@ -0,0 +1,144 @@
+-- ==============================================================
+-- GNUmed database schema change script
+--
+-- License: GPL v2 or later
+-- Author: karsten.hilbert at gmx.net
+--
+-- ==============================================================
+\set ON_ERROR_STOP 1
+--set default_transaction_read_only to off;
+
+-- --------------------------------------------------------------
+drop view if exists clin.v_nonbrand_intakes cascade;
+
+create view clin.v_nonbrand_intakes as
+select
+	c_si.pk
+		as pk_substance_intake,
+	(select fk_patient from clin.encounter where pk = c_si.fk_encounter)
+		as pk_patient,
+	c_si.soap_cat,
+	null::text
+		as brand,
+	c_si.preparation,
+	r_cs.description
+		as substance,
+	r_cs.amount,
+	r_cs.unit
+		as unit,
+	r_cs.atc_code
+		as atc_substance,
+	null::text
+		as atc_brand,
+	null::text
+		as external_code_brand,
+	null::text
+		as external_code_type_brand,
+
+	-- uncertainty of start
+	case
+		when c_si.comment_on_start = '?' then null
+		else c_si.clin_when
+	end::timestamp with time zone
+		as started,
+	c_si.comment_on_start,
+	case
+		when c_si.comment_on_start = '?' then true
+		else false
+	end::boolean
+		as start_is_unknown,
+	case
+		when c_si.comment_on_start is null then false
+		else true
+	end::boolean
+		as start_is_approximate,
+	c_si.intake_is_approved_of,
+	c_si.harmful_use_type,
+	CASE
+		WHEN c_si.harmful_use_type IS NULL THEN NULL::timestamp with time zone
+		ELSE c_enc.started
+	END
+		AS last_checked_when,
+	c_si.schedule,
+	c_si.duration,
+	c_si.discontinued,
+	c_si.discontinue_reason,
+	c_si.is_long_term,
+	c_si.aim,
+	cep.description
+		as episode,
+	c_hi.description
+		as health_issue,
+	c_si.narrative
+		as notes,
+	null::boolean
+		as fake_brand,
+	-- currently active ?
+	case
+		-- no discontinue date documented so assumed active
+		when c_si.discontinued is null then true
+		-- else not active (constraints guarantee that .discontinued > clin_when and < current_timestamp)
+		else false
+	end::boolean
+		as is_currently_active,
+	-- seems inactive ?
+	case
+		when c_si.discontinued is not null then true
+		-- from here on discontinued is NULL
+		when c_si.clin_when is null then
+			case
+				when c_si.is_long_term is true then false
+				else null
+			end
+		-- from here clin_when is NOT null
+		when (c_si.clin_when > current_timestamp) is true then true
+		when ((c_si.clin_when + c_si.duration) < current_timestamp) is true then true
+		when ((c_si.clin_when + c_si.duration) > current_timestamp) is true then false
+		else null
+	end::boolean
+		as seems_inactive,
+	null::integer
+		as pk_brand,
+	null::integer
+		as pk_data_source,
+	r_cs.pk
+		as pk_substance,
+	null::integer
+		as pk_drug_component,
+	c_si.fk_encounter
+		as pk_encounter,
+	c_si.fk_episode
+		as pk_episode,
+	cep.fk_health_issue
+		as pk_health_issue,
+	c_si.modified_when,
+	c_si.modified_by,
+	c_si.row_version
+		as row_version,
+	c_si.xmin
+		as xmin_substance_intake
+from
+	clin.substance_intake c_si
+		inner join ref.consumable_substance r_cs on (c_si.fk_substance = r_cs.pk)
+			left join clin.episode cep on (c_si.fk_episode = cep.pk)
+				left join clin.health_issue c_hi on (c_hi.pk = cep.fk_health_issue)
+					left join clin.encounter c_enc on (c_si.fk_encounter = c_enc.pk)
+where
+	c_si.fk_drug_component IS NULL
+;
+
+grant select on clin.v_nonbrand_intakes to group "gm-doctors";
+
+-- --------------------------------------------------------------
+drop view if exists clin.v_substance_intakes cascade;
+
+create view clin.v_substance_intakes as
+select * from clin.v_brand_intakes
+	union all
+select * from clin.v_nonbrand_intakes
+;
+
+grant select on clin.v_substance_intakes to group "gm-doctors";
+
+-- --------------------------------------------------------------
+select gm.log_script_insertion('v21-clin-v_substance_intakes-fixup.sql', '21.15');
diff --git a/server/sql/v15-v16/dynamic/v16-db-default_settings.sql b/server/sql/v20-v21/fixups/v21-db-sql_inheritance-fixup.sql
similarity index 54%
copy from server/sql/v15-v16/dynamic/v16-db-default_settings.sql
copy to server/sql/v20-v21/fixups/v21-db-sql_inheritance-fixup.sql
index fd57475..2cb963a 100644
--- a/server/sql/v15-v16/dynamic/v16-db-default_settings.sql
+++ b/server/sql/v20-v21/fixups/v21-db-sql_inheritance-fixup.sql
@@ -3,21 +3,13 @@
 --
 -- License: GPL v2 or later
 -- Author: karsten.hilbert at gmx.net
--- 
+--
 -- ==============================================================
 \set ON_ERROR_STOP 1
+--set default_transaction_read_only to off;
 
 -- --------------------------------------------------------------
-ALTER DATABASE gnumed_v16
-	SET datestyle to 'ISO';
-
-ALTER DATABASE gnumed_v16
-	SET default_transaction_isolation to 'read committed';
-
-ALTER DATABASE gnumed_v16
-	SET sql_inheritance to 'on';
+select 'no-op SELECT such that the bootstrapper is run and forces SQL_INHERITANCE back to DEFAULT if on PG <10';
 
 -- --------------------------------------------------------------
-select gm.log_script_insertion('v16-db-default_settings.sql', 'v16');
-
--- ==============================================================
\ No newline at end of file
+select gm.log_script_insertion('v21-db-sql_inheritance-fixup.sql', '21.15');
diff --git a/server/sql/v20-v21/fixups/v21-i18n-lang_funcs-fixup.sql b/server/sql/v20-v21/fixups/v21-i18n-lang_funcs-fixup.sql
new file mode 100644
index 0000000..78a4a39
--- /dev/null
+++ b/server/sql/v20-v21/fixups/v21-i18n-lang_funcs-fixup.sql
@@ -0,0 +1,52 @@
+-- ======================================================
+-- GNUmed fixed string internationalisation (SQL gettext)
+-- ======================================================
+-- force terminate + exit(3) on errors if non-interactive
+\set ON_ERROR_STOP 1
+
+-- =============================================
+create or replace function i18n.set_curr_lang(text)
+	returns boolean
+	language 'plpgsql'
+	security definer
+	as '
+DECLARE
+	_lang ALIAS FOR $1;
+BEGIN
+	if exists(select pk from i18n.translations where lang = _lang) then
+		delete from i18n.curr_lang where user = CURRENT_USER;
+		insert into i18n.curr_lang (lang) values (_lang);
+		return true;
+	end if;
+	raise notice ''Cannot set current language to [%]. No translations available.'', _lang;
+	return false;
+END;
+';
+
+comment on function i18n.set_curr_lang(text) is
+	'set preferred language:
+	 - for "current user"
+	 - only if translations for this language are available';
+
+-- =============================================
+create or replace function i18n.force_curr_lang(text)
+	returns boolean
+	language 'plpgsql'
+	security definer
+	as '
+DECLARE
+    _lang ALIAS FOR $1;
+BEGIN
+    raise notice ''Forcing current language to [%] without checking for translations..'', _lang;
+    delete from i18n.curr_lang where user = CURRENT_USER;
+    insert into i18n.curr_lang(lang) values (_lang);
+    return 1;
+END;
+';
+
+comment on function i18n.force_curr_lang(text) is
+	'force preferred language to some language:
+	 - for "current user"';
+
+-- --------------------------------------------------------------
+select gm.log_script_insertion('v21-i18n-lang_funcs-fixup.sql', '21.15');

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/gnumed-server.git



More information about the debian-med-commit mailing list