[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