New upstream version 21.15
Andreas Tille
6 years ago
0 | Script started on 2017-10-16 22:44:21+0200 | |
1 | ncq@hermes:~/Projekte/gm-git/gnumed/gnumed/server/bootstrap$ sudo ./bootstrap-latest.sh | |
2 | [sudo] Passwort für ncq: | |
3 | =========================================================== | |
4 | Bootstrapping latest GNUmed database. | |
5 | ||
6 | This will set up a GNUmed database of version v21 | |
7 | with the name "gnumed_v21". | |
8 | ||
9 | ------------------------------------------------ | |
10 | The database "gnumed_v2" already exists. | |
11 | Note that during bootstrapping this | |
12 | database will be OVERWRITTEN ! | |
13 | ||
14 | Do you really intend to bootstrap or did you | |
15 | rather want to *upgrade* from v20 to v21 ? | |
16 | ||
17 | (For upgrading you should run the | |
18 | upgrade script instead.) | |
19 | ||
20 | Continue bootstrapping (deletes databases) ? | |
21 | ||
22 | [yes / NO]: yes | |
23 | ||
24 | ------------------------------------------------ | |
25 | The database "gnumed_v3" already exists. | |
26 | Note that during bootstrapping this | |
27 | database will be OVERWRITTEN ! | |
28 | ||
29 | Do you really intend to bootstrap or did you | |
30 | rather want to *upgrade* from v20 to v21 ? | |
31 | ||
32 | (For upgrading you should run the | |
33 | upgrade script instead.) | |
34 | ||
35 | Continue bootstrapping (deletes databases) ? | |
36 | ||
37 | [yes / NO]: yes | |
38 | ||
39 | ------------------------------------------------ | |
40 | The database "gnumed_v4" already exists. | |
41 | Note that during bootstrapping this | |
42 | database will be OVERWRITTEN ! | |
43 | ||
44 | Do you really intend to bootstrap or did you | |
45 | rather want to *upgrade* from v20 to v21 ? | |
46 | ||
47 | (For upgrading you should run the | |
48 | upgrade script instead.) | |
49 | ||
50 | Continue bootstrapping (deletes databases) ? | |
51 | ||
52 | [yes / NO]: yes | |
53 | ||
54 | ------------------------------------------------ | |
55 | The database "gnumed_v5" already exists. | |
56 | Note that during bootstrapping this | |
57 | database will be OVERWRITTEN ! | |
58 | ||
59 | Do you really intend to bootstrap or did you | |
60 | rather want to *upgrade* from v20 to v21 ? | |
61 | ||
62 | (For upgrading you should run the | |
63 | upgrade script instead.) | |
64 | ||
65 | Continue bootstrapping (deletes databases) ? | |
66 | ||
67 | [yes / NO]: yes | |
68 | ||
69 | ------------------------------------------------ | |
70 | The database "gnumed_v6" already exists. | |
71 | Note that during bootstrapping this | |
72 | database will be OVERWRITTEN ! | |
73 | ||
74 | Do you really intend to bootstrap or did you | |
75 | rather want to *upgrade* from v20 to v21 ? | |
76 | ||
77 | (For upgrading you should run the | |
78 | upgrade script instead.) | |
79 | ||
80 | Continue bootstrapping (deletes databases) ? | |
81 | ||
82 | [yes / NO]: yes | |
83 | ||
84 | ------------------------------------------------ | |
85 | The database "gnumed_v7" already exists. | |
86 | Note that during bootstrapping this | |
87 | database will be OVERWRITTEN ! | |
88 | ||
89 | Do you really intend to bootstrap or did you | |
90 | rather want to *upgrade* from v20 to v21 ? | |
91 | ||
92 | (For upgrading you should run the | |
93 | upgrade script instead.) | |
94 | ||
95 | Continue bootstrapping (deletes databases) ? | |
96 | ||
97 | [yes / NO]: yes | |
98 | ||
99 | ------------------------------------------------ | |
100 | The database "gnumed_v8" already exists. | |
101 | Note that during bootstrapping this | |
102 | database will be OVERWRITTEN ! | |
103 | ||
104 | Do you really intend to bootstrap or did you | |
105 | rather want to *upgrade* from v20 to v21 ? | |
106 | ||
107 | (For upgrading you should run the | |
108 | upgrade script instead.) | |
109 | ||
110 | Continue bootstrapping (deletes databases) ? | |
111 | ||
112 | [yes / NO]: yes | |
113 | ||
114 | ------------------------------------------------ | |
115 | The database "gnumed_v9" already exists. | |
116 | Note that during bootstrapping this | |
117 | database will be OVERWRITTEN ! | |
118 | ||
119 | Do you really intend to bootstrap or did you | |
120 | rather want to *upgrade* from v20 to v21 ? | |
121 | ||
122 | (For upgrading you should run the | |
123 | upgrade script instead.) | |
124 | ||
125 | Continue bootstrapping (deletes databases) ? | |
126 | ||
127 | [yes / NO]: yes | |
128 | ||
129 | ------------------------------------------------ | |
130 | The database "gnumed_v10" already exists. | |
131 | Note that during bootstrapping this | |
132 | database will be OVERWRITTEN ! | |
133 | ||
134 | Do you really intend to bootstrap or did you | |
135 | rather want to *upgrade* from v20 to v21 ? | |
136 | ||
137 | (For upgrading you should run the | |
138 | upgrade script instead.) | |
139 | ||
140 | Continue bootstrapping (deletes databases) ? | |
141 | ||
142 | [yes / NO]: yes | |
143 | ||
144 | ------------------------------------------------ | |
145 | The database "gnumed_v11" already exists. | |
146 | Note that during bootstrapping this | |
147 | database will be OVERWRITTEN ! | |
148 | ||
149 | Do you really intend to bootstrap or did you | |
150 | rather want to *upgrade* from v20 to v21 ? | |
151 | ||
152 | (For upgrading you should run the | |
153 | upgrade script instead.) | |
154 | ||
155 | Continue bootstrapping (deletes databases) ? | |
156 | ||
157 | [yes / NO]: yes | |
158 | ||
159 | ------------------------------------------------ | |
160 | The database "gnumed_v12" already exists. | |
161 | Note that during bootstrapping this | |
162 | database will be OVERWRITTEN ! | |
163 | ||
164 | Do you really intend to bootstrap or did you | |
165 | rather want to *upgrade* from v20 to v21 ? | |
166 | ||
167 | (For upgrading you should run the | |
168 | upgrade script instead.) | |
169 | ||
170 | Continue bootstrapping (deletes databases) ? | |
171 | ||
172 | [yes / NO]: yes | |
173 | ||
174 | ------------------------------------------------ | |
175 | The database "gnumed_v13" already exists. | |
176 | Note that during bootstrapping this | |
177 | database will be OVERWRITTEN ! | |
178 | ||
179 | Do you really intend to bootstrap or did you | |
180 | rather want to *upgrade* from v20 to v21 ? | |
181 | ||
182 | (For upgrading you should run the | |
183 | upgrade script instead.) | |
184 | ||
185 | Continue bootstrapping (deletes databases) ? | |
186 | ||
187 | [yes / NO]: yes | |
188 | ||
189 | ------------------------------------------------ | |
190 | The database "gnumed_v14" already exists. | |
191 | Note that during bootstrapping this | |
192 | database will be OVERWRITTEN ! | |
193 | ||
194 | Do you really intend to bootstrap or did you | |
195 | rather want to *upgrade* from v20 to v21 ? | |
196 | ||
197 | (For upgrading you should run the | |
198 | upgrade script instead.) | |
199 | ||
200 | Continue bootstrapping (deletes databases) ? | |
201 | ||
202 | [yes / NO]: yes | |
203 | ||
204 | ------------------------------------------------ | |
205 | The database "gnumed_v15" already exists. | |
206 | Note that during bootstrapping this | |
207 | database will be OVERWRITTEN ! | |
208 | ||
209 | Do you really intend to bootstrap or did you | |
210 | rather want to *upgrade* from v20 to v21 ? | |
211 | ||
212 | (For upgrading you should run the | |
213 | upgrade script instead.) | |
214 | ||
215 | Continue bootstrapping (deletes databases) ? | |
216 | ||
217 | [yes / NO]: yes | |
218 | ||
219 | ------------------------------------------------ | |
220 | The database "gnumed_v16" already exists. | |
221 | Note that during bootstrapping this | |
222 | database will be OVERWRITTEN ! | |
223 | ||
224 | Do you really intend to bootstrap or did you | |
225 | rather want to *upgrade* from v20 to v21 ? | |
226 | ||
227 | (For upgrading you should run the | |
228 | upgrade script instead.) | |
229 | ||
230 | Continue bootstrapping (deletes databases) ? | |
231 | ||
232 | [yes / NO]: yes | |
233 | ||
234 | ------------------------------------------------ | |
235 | The database "gnumed_v17" already exists. | |
236 | Note that during bootstrapping this | |
237 | database will be OVERWRITTEN ! | |
238 | ||
239 | Do you really intend to bootstrap or did you | |
240 | rather want to *upgrade* from v20 to v21 ? | |
241 | ||
242 | (For upgrading you should run the | |
243 | upgrade script instead.) | |
244 | ||
245 | Continue bootstrapping (deletes databases) ? | |
246 | ||
247 | [yes / NO]: yes | |
248 | ||
249 | ------------------------------------------------ | |
250 | The database "gnumed_v18" already exists. | |
251 | Note that during bootstrapping this | |
252 | database will be OVERWRITTEN ! | |
253 | ||
254 | Do you really intend to bootstrap or did you | |
255 | rather want to *upgrade* from v20 to v21 ? | |
256 | ||
257 | (For upgrading you should run the | |
258 | upgrade script instead.) | |
259 | ||
260 | Continue bootstrapping (deletes databases) ? | |
261 | ||
262 | [yes / NO]: yes | |
263 | ||
264 | ------------------------------------------------ | |
265 | The database "gnumed_v19" already exists. | |
266 | Note that during bootstrapping this | |
267 | database will be OVERWRITTEN ! | |
268 | ||
269 | Do you really intend to bootstrap or did you | |
270 | rather want to *upgrade* from v20 to v21 ? | |
271 | ||
272 | (For upgrading you should run the | |
273 | upgrade script instead.) | |
274 | ||
275 | Continue bootstrapping (deletes databases) ? | |
276 | ||
277 | [yes / NO]: yes | |
278 | ||
279 | ------------------------------------------------ | |
280 | The database "gnumed_v20" already exists. | |
281 | Note that during bootstrapping this | |
282 | database will be OVERWRITTEN ! | |
283 | ||
284 | Do you really intend to bootstrap or did you | |
285 | rather want to *upgrade* from v20 to v21 ? | |
286 | ||
287 | (For upgrading you should run the | |
288 | upgrade script instead.) | |
289 | ||
290 | Continue bootstrapping (deletes databases) ? | |
291 | ||
292 | [yes / NO]: yes | |
293 | ||
294 | ------------------------------------------------ | |
295 | The database "gnumed_v21" already exists. | |
296 | Note that during bootstrapping this | |
297 | database will be OVERWRITTEN ! | |
298 | ||
299 | Do you really intend to bootstrap or did you | |
300 | rather want to *upgrade* from v20 to v21 ? | |
301 | ||
302 | (For upgrading you should run the | |
303 | upgrade script instead.) | |
304 | ||
305 | Continue bootstrapping (deletes databases) ? | |
306 | ||
307 | [yes / NO]: yes | |
308 | Adjusting PYTHONPATH ... | |
309 | ======================================= | |
310 | Bootstrapping GNUmed database system... | |
311 | ======================================= | |
312 | You are about to install the following parts of GNUmed: | |
313 | ------------------------------------------------------- | |
314 | bundle "config" in <gnumed_v2> (or overridden) on <> | |
315 | bundle "reference" in <gnumed_v2> (or overridden) on <> | |
316 | bundle "demographics" in <gnumed_v2> (or overridden) on <> | |
317 | bundle "clinical" in <gnumed_v2> (or overridden) on <> | |
318 | bundle "documents" in <gnumed_v2> (or overridden) on <> | |
319 | bundle "office" in <gnumed_v2> (or overridden) on <> | |
320 | ------------------------------------------------------- | |
321 | This will set up a monolithic GNUmed backend with all bundles | |
322 | in one database named [gnumed]. It will contain the core schema | |
323 | without country or language-specific components. Those will | |
324 | have to be added by using one of the bootstrap-XX.conf file | |
325 | where XX represents the ISO country code. | |
326 | ||
327 | Currently this file will also import the test accounts which | |
328 | MUST be removed prior to real use. | |
329 | ||
330 | ==> bootstrapping "config" ... | |
331 | ==> dropping pre-existing target database [gnumed_v2] ... | |
332 | ==> cloning [template1] (7997 kB) as target database [gnumed_v2] ... | |
333 | ==> reindexing target database (can take a while) ... | |
334 | ==> transferring users ... | |
335 | ... skipped (unconfigured) | |
336 | ==> bootstrapping "reference" ... | |
337 | ==> bootstrapping "demographics" ... | |
338 | ==> bootstrapping "clinical" ... | |
339 | ==> bootstrapping "documents" ... | |
340 | ==> bootstrapping "office" ... | |
341 | ==> setting up auditing ... | |
342 | ==> setting up encounter/episode FKs and IDXs ... | |
343 | ==> upgrading reference data sets ... | |
344 | ... skipped (no scripts to run) | |
345 | You are about to install the following parts of GNUmed: | |
346 | ------------------------------------------------------- | |
347 | bundle "demographics-de" in <gnumed_v2> (or overridden) on <> | |
348 | bundle "clinical-de" in <gnumed_v2> (or overridden) on <> | |
349 | bundle "reference-de" in <gnumed_v2> (or overridden) on <> | |
350 | bundle "Uebersetzung" in <gnumed_v2> (or overridden) on <> | |
351 | ------------------------------------------------------- | |
352 | Dieses Skript installiert Daten in ein GNUmed-Datenbanksystem, | |
353 | mit denen GNUmed fuer Deutschland angepasst wird. | |
354 | ||
355 | Die Datenbankstruktur muss bereits in einer GNUmed-Datenbank | |
356 | installiert sein, ebenso muss mindestens der Nutzer gm-dbo | |
357 | bereits existieren. | |
358 | ==> bootstrapping "demographics-de" ... | |
359 | ==> bootstrapping "clinical-de" ... | |
360 | ==> bootstrapping "reference-de" ... | |
361 | ==> bootstrapping "Uebersetzung" ... | |
362 | ==> setting up auditing ... | |
363 | ... skipped (disabled) | |
364 | ==> setting up encounter/episode FKs and IDXs ... | |
365 | ==> upgrading reference data sets ... | |
366 | ... skipped (no scripts to run) | |
367 | You are about to install the following parts of GNUmed: | |
368 | ------------------------------------------------------- | |
369 | bundle "demographics-es" in <gnumed_v2> (or overridden) on <> | |
370 | ------------------------------------------------------- | |
371 | ||
372 | Este script instala en la base de datos de GNUmed las informaciones | |
373 | especificas para su uso en Espana (provincias). | |
374 | ||
375 | Como requisitos, el esquema debe haber sido previamente instalado | |
376 | en la base de datos "gnumed" y, al menos, el usuario "gm-dbo" debe | |
377 | haber sido creado. | |
378 | ||
379 | ==> bootstrapping "demographics-es" ... | |
380 | ==> setting up auditing ... | |
381 | ... skipped (disabled) | |
382 | ==> setting up encounter/episode FKs and IDXs ... | |
383 | ==> upgrading reference data sets ... | |
384 | ... skipped (no scripts to run) | |
385 | You are about to install the following parts of GNUmed: | |
386 | ------------------------------------------------------- | |
387 | bundle "demographics-ca" in <gnumed_v2> (or overridden) on <> | |
388 | ------------------------------------------------------- | |
389 | This script installs data into a GNUmed database system in | |
390 | order to localise GNUmed for Canada. | |
391 | ||
392 | The core database schema must have been imported into a database | |
393 | "gnumed" already. Also, the user gm-dbo must exist. | |
394 | ||
395 | ==> bootstrapping "demographics-ca" ... | |
396 | ==> setting up auditing ... | |
397 | ... skipped (disabled) | |
398 | ==> setting up encounter/episode FKs and IDXs ... | |
399 | ==> upgrading reference data sets ... | |
400 | ... skipped (no scripts to run) | |
401 | You are about to install the following parts of GNUmed: | |
402 | ------------------------------------------------------- | |
403 | bundle "au-locale" in <gnumed_v2> (or overridden) on <> | |
404 | ------------------------------------------------------- | |
405 | This script installs data into a GNUmed database system in | |
406 | order to localise GNUmed for Australia. | |
407 | ||
408 | The core database schema must have been imported into a database | |
409 | "gnumed" already. Also, the user gm-dbo must exist. | |
410 | ||
411 | ==> bootstrapping "au-locale" ... | |
412 | ==> setting up auditing ... | |
413 | ... skipped (disabled) | |
414 | ==> setting up encounter/episode FKs and IDXs ... | |
415 | ==> upgrading reference data sets ... | |
416 | ... skipped (no scripts to run) | |
417 | You are about to install the following parts of GNUmed: | |
418 | ------------------------------------------------------- | |
419 | bundle "test data" in <gnumed_v2> (or overridden) on <> | |
420 | ------------------------------------------------------- | |
421 | This script installs test data into an existing GNUmed database | |
422 | named "gnumed". Also, the database owner "gm-dbo" must exist | |
423 | already. | |
424 | ==> bootstrapping "test data" ... | |
425 | ==> setting up auditing ... | |
426 | ... skipped (disabled) | |
427 | ==> setting up encounter/episode FKs and IDXs ... | |
428 | ==> upgrading reference data sets ... | |
429 | ... skipped (no scripts to run) | |
430 | ==> setting up auditing ... | |
431 | ... skipped (disabled) | |
432 | ==> setting up encounter/episode FKs and IDXs ... | |
433 | ==> upgrading reference data sets ... | |
434 | ... skipped (no scripts to run) | |
435 | You are about to install the following parts of GNUmed: | |
436 | ------------------------------------------------------- | |
437 | bundle "v2-v3-static" in <gnumed_v3> (or overridden) on <> | |
438 | bundle "v2-v3-dynamic" in <gnumed_v3> (or overridden) on <> | |
439 | ------------------------------------------------------- | |
440 | This will update an existing GNUmed version 2 | |
441 | database to the version 3 schema. It does not do | |
442 | any harm to the data contained within. | |
443 | ||
444 | The existing database is cloned first. The copy is | |
445 | then modified. The original database remains unchanged. | |
446 | ==> bootstrapping "v2-v3-static" ... | |
447 | ==> dropping pre-existing target database [gnumed_v3] ... | |
448 | ==> cloning [gnumed_v2] (21 MB) as target database [gnumed_v3] ... | |
449 | ==> reindexing target database (can take a while) ... | |
450 | ==> transferring users ... | |
451 | ... skipped (unconfigured) | |
452 | ==> bootstrapping "v2-v3-dynamic" ... | |
453 | ==> setting up auditing ... | |
454 | ... skipped (disabled) | |
455 | ==> setting up encounter/episode FKs and IDXs ... | |
456 | ==> upgrading reference data sets ... | |
457 | ... skipped (no scripts to run) | |
458 | You are about to install the following parts of GNUmed: | |
459 | ------------------------------------------------------- | |
460 | bundle "v3-v4-static" in <gnumed_v4> (or overridden) on <> | |
461 | bundle "v3-v4-dynamic" in <gnumed_v4> (or overridden) on <> | |
462 | ------------------------------------------------------- | |
463 | This will update an existing GNUmed version 3 | |
464 | database to the version 4 schema. It does not do | |
465 | any harm to the data contained within. | |
466 | ||
467 | The existing database is cloned first. The copy is | |
468 | then modified. The original database remains unchanged. | |
469 | ==> bootstrapping "v3-v4-static" ... | |
470 | ==> dropping pre-existing target database [gnumed_v4] ... | |
471 | ==> cloning [gnumed_v3] (21 MB) as target database [gnumed_v4] ... | |
472 | ==> reindexing target database (can take a while) ... | |
473 | ==> transferring users ... | |
474 | ... skipped (unconfigured) | |
475 | ==> bootstrapping "v3-v4-dynamic" ... | |
476 | ==> setting up auditing ... | |
477 | ... skipped (disabled) | |
478 | ==> setting up encounter/episode FKs and IDXs ... | |
479 | ==> upgrading reference data sets ... | |
480 | ... skipped (no scripts to run) | |
481 | You are about to install the following parts of GNUmed: | |
482 | ------------------------------------------------------- | |
483 | bundle "v4-v5-static" in <gnumed_v5> (or overridden) on <> | |
484 | bundle "v4-v5-dynamic" in <gnumed_v5> (or overridden) on <> | |
485 | ------------------------------------------------------- | |
486 | This will update an existing GNUmed version 4 | |
487 | database to the version 5 schema. It does not do | |
488 | any harm to the data contained within. | |
489 | ||
490 | The existing database is cloned first. The copy is | |
491 | then modified. The original database remains unchanged. | |
492 | ==> bootstrapping "v4-v5-static" ... | |
493 | ==> dropping pre-existing target database [gnumed_v5] ... | |
494 | ==> cloning [gnumed_v4] (21 MB) as target database [gnumed_v5] ... | |
495 | ==> reindexing target database (can take a while) ... | |
496 | ==> transferring users ... | |
497 | ... skipped (unconfigured) | |
498 | ==> bootstrapping "v4-v5-dynamic" ... | |
499 | ==> setting up auditing ... | |
500 | ... skipped (disabled) | |
501 | ==> setting up encounter/episode FKs and IDXs ... | |
502 | ==> upgrading reference data sets ... | |
503 | ... skipped (no scripts to run) | |
504 | You are about to install the following parts of GNUmed: | |
505 | ------------------------------------------------------- | |
506 | bundle "v5-v6-static" in <gnumed_v6> (or overridden) on <> | |
507 | bundle "v5-v6-dynamic" in <gnumed_v6> (or overridden) on <> | |
508 | ------------------------------------------------------- | |
509 | This will update an existing GNUmed version 5 | |
510 | database to the version 6 schema. It does not do | |
511 | any harm to the data contained within. | |
512 | ||
513 | The existing database is cloned first. The copy is | |
514 | then modified. The original database remains unchanged. | |
515 | ==> bootstrapping "v5-v6-static" ... | |
516 | ==> dropping pre-existing target database [gnumed_v6] ... | |
517 | ==> cloning [gnumed_v5] (21 MB) as target database [gnumed_v6] ... | |
518 | ==> reindexing target database (can take a while) ... | |
519 | ==> transferring users ... | |
520 | ==> bootstrapping "v5-v6-dynamic" ... | |
521 | ==> setting up auditing ... | |
522 | ... skipped (disabled) | |
523 | ==> setting up encounter/episode FKs and IDXs ... | |
524 | ==> upgrading reference data sets ... | |
525 | ... skipped (no scripts to run) | |
526 | You are about to install the following parts of GNUmed: | |
527 | ------------------------------------------------------- | |
528 | bundle "v6-v7-static" in <gnumed_v7> (or overridden) on <> | |
529 | bundle "v6-v7-dynamic" in <gnumed_v7> (or overridden) on <> | |
530 | ------------------------------------------------------- | |
531 | This will update an existing GNUmed version 6 | |
532 | database to the version 7 schema. It does not do | |
533 | any harm to the data contained within. | |
534 | ||
535 | The existing database is cloned first. The copy is | |
536 | then modified. The original database remains unchanged. | |
537 | ==> bootstrapping "v6-v7-static" ... | |
538 | ==> dropping pre-existing target database [gnumed_v7] ... | |
539 | ==> cloning [gnumed_v6] (21 MB) as target database [gnumed_v7] ... | |
540 | ==> reindexing target database (can take a while) ... | |
541 | ==> transferring users ... | |
542 | ==> bootstrapping "v6-v7-dynamic" ... | |
543 | ==> setting up auditing ... | |
544 | ... skipped (disabled) | |
545 | ==> setting up encounter/episode FKs and IDXs ... | |
546 | ==> upgrading reference data sets ... | |
547 | You are about to install the following parts of GNUmed: | |
548 | ------------------------------------------------------- | |
549 | bundle "v7-v8-static" in <gnumed_v8> (or overridden) on <> | |
550 | bundle "v7-v8-dynamic" in <gnumed_v8> (or overridden) on <> | |
551 | ------------------------------------------------------- | |
552 | This will update an existing GNUmed version 7 | |
553 | database to the version 8 schema. It does not do | |
554 | any harm to the data contained within. | |
555 | ||
556 | The existing database is cloned first. The copy is | |
557 | then modified. The original database remains unchanged. | |
558 | ==> bootstrapping "v7-v8-static" ... | |
559 | ==> dropping pre-existing target database [gnumed_v8] ... | |
560 | ==> cloning [gnumed_v7] (21 MB) as target database [gnumed_v8] ... | |
561 | ==> reindexing target database (can take a while) ... | |
562 | ==> transferring users ... | |
563 | ==> bootstrapping "v7-v8-dynamic" ... | |
564 | ==> setting up auditing ... | |
565 | ==> setting up encounter/episode FKs and IDXs ... | |
566 | ==> upgrading reference data sets ... | |
567 | ... skipped (no scripts to run) | |
568 | You are about to install the following parts of GNUmed: | |
569 | ------------------------------------------------------- | |
570 | bundle "v8-v9-static" in <gnumed_v9> (or overridden) on <> | |
571 | bundle "v8-v9-dynamic" in <gnumed_v9> (or overridden) on <> | |
572 | ------------------------------------------------------- | |
573 | This will update an existing GNUmed version 8 | |
574 | database to the version 9 schema. It does not do | |
575 | any harm to the data contained within. | |
576 | ||
577 | The existing database is cloned first. The copy is | |
578 | then modified. The original database remains unchanged. | |
579 | ==> bootstrapping "v8-v9-static" ... | |
580 | ==> dropping pre-existing target database [gnumed_v9] ... | |
581 | ==> cloning [gnumed_v8] (22 MB) as target database [gnumed_v9] ... | |
582 | ==> reindexing target database (can take a while) ... | |
583 | ==> transferring users ... | |
584 | ==> bootstrapping "v8-v9-dynamic" ... | |
585 | ==> setting up auditing ... | |
586 | ==> setting up encounter/episode FKs and IDXs ... | |
587 | ==> upgrading reference data sets ... | |
588 | ... skipped (no scripts to run) | |
589 | You are about to install the following parts of GNUmed: | |
590 | ------------------------------------------------------- | |
591 | bundle "v9-v10-static" in <gnumed_v10> (or overridden) on <> | |
592 | bundle "v9-v10-dynamic" in <gnumed_v10> (or overridden) on <> | |
593 | bundle "v10-fixups" in <gnumed_v10> (or overridden) on <> | |
594 | ------------------------------------------------------- | |
595 | This will update an existing GNUmed version 9 | |
596 | database to the version 10 schema. It does not do | |
597 | any harm to the data contained within. | |
598 | ||
599 | The existing database is cloned first. The copy is | |
600 | then modified. The original database remains unchanged. | |
601 | ==> bootstrapping "v9-v10-static" ... | |
602 | ==> dropping pre-existing target database [gnumed_v10] ... | |
603 | ==> cloning [gnumed_v9] (22 MB) as target database [gnumed_v10] ... | |
604 | ==> reindexing target database (can take a while) ... | |
605 | ==> transferring users ... | |
606 | ==> bootstrapping "v9-v10-dynamic" ... | |
607 | ==> bootstrapping "v10-fixups" ... | |
608 | ==> setting up auditing ... | |
609 | ... skipped (disabled) | |
610 | ==> setting up encounter/episode FKs and IDXs ... | |
611 | ==> upgrading reference data sets ... | |
612 | ... skipped (no scripts to run) | |
613 | You are about to install the following parts of GNUmed: | |
614 | ------------------------------------------------------- | |
615 | bundle "v10_fixups-pre_v11" in <gnumed_v11> (or overridden) on <> | |
616 | bundle "v10-v11-static" in <gnumed_v11> (or overridden) on <> | |
617 | bundle "v10-v11-dynamic" in <gnumed_v11> (or overridden) on <> | |
618 | bundle "v11-fixups" in <gnumed_v11> (or overridden) on <> | |
619 | bundle "v11-test_data" in <gnumed_v11> (or overridden) on <> | |
620 | ------------------------------------------------------- | |
621 | This will update an existing GNUmed version 10 | |
622 | database to the version 11 schema. It does not do | |
623 | any harm to the data contained within. | |
624 | ||
625 | The existing database will be cloned first. The copy is | |
626 | then modified. The original database remains unchanged. | |
627 | ==> bootstrapping "v10_fixups-pre_v11" ... | |
628 | ==> dropping pre-existing target database [gnumed_v11] ... | |
629 | ==> cloning [gnumed_v10] (23 MB) as target database [gnumed_v11] ... | |
630 | ==> reindexing target database (can take a while) ... | |
631 | ==> transferring users ... | |
632 | ==> bootstrapping "v10-v11-static" ... | |
633 | ==> bootstrapping "v10-v11-dynamic" ... | |
634 | ==> bootstrapping "v11-fixups" ... | |
635 | ==> bootstrapping "v11-test_data" ... | |
636 | ==> setting up auditing ... | |
637 | ==> setting up encounter/episode FKs and IDXs ... | |
638 | ==> upgrading reference data sets ... | |
639 | ... skipped (no scripts to run) | |
640 | You are about to install the following parts of GNUmed: | |
641 | ------------------------------------------------------- | |
642 | bundle "v11_fixups-pre_v12" in <gnumed_v12> (or overridden) on <> | |
643 | bundle "v11-v12-static" in <gnumed_v12> (or overridden) on <> | |
644 | bundle "v11-v12-dynamic" in <gnumed_v12> (or overridden) on <> | |
645 | ------------------------------------------------------- | |
646 | This will update an existing GNUmed version 11 | |
647 | database to the version 12 schema. It does not do | |
648 | any harm to the data contained within. | |
649 | ||
650 | The existing database will be cloned first. The copy is | |
651 | then modified. The original database remains unchanged. | |
652 | ==> bootstrapping "v11_fixups-pre_v12" ... | |
653 | ==> dropping pre-existing target database [gnumed_v12] ... | |
654 | ==> cloning [gnumed_v11] (24 MB) as target database [gnumed_v12] ... | |
655 | ==> reindexing target database (can take a while) ... | |
656 | ==> transferring users ... | |
657 | ==> bootstrapping "v11-v12-static" ... | |
658 | ==> bootstrapping "v11-v12-dynamic" ... | |
659 | ==> setting up auditing ... | |
660 | ==> setting up encounter/episode FKs and IDXs ... | |
661 | ==> upgrading reference data sets ... | |
662 | You are about to install the following parts of GNUmed: | |
663 | ------------------------------------------------------- | |
664 | bundle "v12-v13-static" in <gnumed_v13> (or overridden) on <> | |
665 | bundle "v12-v13-dynamic" in <gnumed_v13> (or overridden) on <> | |
666 | ------------------------------------------------------- | |
667 | This will update an existing GNUmed version 12 | |
668 | database to the version 13 schema. It does not do | |
669 | any harm to the data contained within. | |
670 | ||
671 | The existing database will be cloned first. The copy is | |
672 | then modified. The original database remains unchanged. | |
673 | ==> bootstrapping "v12-v13-static" ... | |
674 | ==> dropping pre-existing target database [gnumed_v13] ... | |
675 | ==> cloning [gnumed_v12] (25 MB) as target database [gnumed_v13] ... | |
676 | ==> reindexing target database (can take a while) ... | |
677 | ==> transferring users ... | |
678 | ==> bootstrapping "v12-v13-dynamic" ... | |
679 | ==> setting up auditing ... | |
680 | ==> setting up encounter/episode FKs and IDXs ... | |
681 | ==> upgrading reference data sets ... | |
682 | You are about to install the following parts of GNUmed: | |
683 | ------------------------------------------------------- | |
684 | bundle "pg_8.3_v14-pre_conversion_fixups" in <gnumed_v14> (or overridden) on <> | |
685 | bundle "v13-v14-static" in <gnumed_v14> (or overridden) on <> | |
686 | bundle "v13-v14-dynamic" in <gnumed_v14> (or overridden) on <> | |
687 | ------------------------------------------------------- | |
688 | This will update an existing GNUmed version 13 | |
689 | database to the version 14 schema. It does not do | |
690 | any harm to the data contained within. | |
691 | ||
692 | The existing database will be cloned first. The copy is | |
693 | then modified. The original database remains unchanged. | |
694 | ==> bootstrapping "pg_8.3_v14-pre_conversion_fixups" ... | |
695 | ==> dropping pre-existing target database [gnumed_v14] ... | |
696 | ==> cloning [gnumed_v13] (36 MB) as target database [gnumed_v14] ... | |
697 | ==> reindexing target database (can take a while) ... | |
698 | ==> transferring users ... | |
699 | ==> bootstrapping "v13-v14-static" ... | |
700 | ==> bootstrapping "v13-v14-dynamic" ... | |
701 | ==> setting up auditing ... | |
702 | ==> setting up encounter/episode FKs and IDXs ... | |
703 | ==> upgrading reference data sets ... | |
704 | You are about to install the following parts of GNUmed: | |
705 | ------------------------------------------------------- | |
706 | bundle "v14-v15-static" in <gnumed_v15> (or overridden) on <> | |
707 | bundle "v14-v15-dynamic" in <gnumed_v15> (or overridden) on <> | |
708 | bundle "v15-fixups" in <gnumed_v15> (or overridden) on <> | |
709 | ------------------------------------------------------- | |
710 | This will update an existing GNUmed version 14 | |
711 | database to the version 15 schema. It does not do | |
712 | any harm to the data contained within. | |
713 | ||
714 | The existing database will be cloned first. The copy is | |
715 | then modified. The original database remains unchanged. | |
716 | ==> bootstrapping "v14-v15-static" ... | |
717 | ==> dropping pre-existing target database [gnumed_v15] ... | |
718 | ==> cloning [gnumed_v14] (37 MB) as target database [gnumed_v15] ... | |
719 | ==> reindexing target database (can take a while) ... | |
720 | ==> transferring users ... | |
721 | ==> bootstrapping "v14-v15-dynamic" ... | |
722 | ==> bootstrapping "v15-fixups" ... | |
723 | ==> setting up auditing ... | |
724 | ==> setting up encounter/episode FKs and IDXs ... | |
725 | ==> upgrading reference data sets ... | |
726 | You are about to install the following parts of GNUmed: | |
727 | ------------------------------------------------------- | |
728 | bundle "v15_fixups-pre_v16" in <gnumed_v16> (or overridden) on <> | |
729 | bundle "v15-v16-static" in <gnumed_v16> (or overridden) on <> | |
730 | bundle "v15-v16-dynamic" in <gnumed_v16> (or overridden) on <> | |
731 | bundle "v16-fixups" in <gnumed_v16> (or overridden) on <> | |
732 | ------------------------------------------------------- | |
733 | This will update an existing GNUmed version 15 | |
734 | database to the version 16 schema. It does not do | |
735 | any harm to the data contained within. | |
736 | ||
737 | The existing database will be cloned first. The copy is | |
738 | then modified. The original database remains unchanged. | |
739 | ==> bootstrapping "v15_fixups-pre_v16" ... | |
740 | ==> dropping pre-existing target database [gnumed_v16] ... | |
741 | ==> cloning [gnumed_v15] (41 MB) as target database [gnumed_v16] ... | |
742 | ==> reindexing target database (can take a while) ... | |
743 | ==> transferring users ... | |
744 | ==> bootstrapping "v15-v16-static" ... | |
745 | ==> bootstrapping "v15-v16-dynamic" ... | |
746 | ==> bootstrapping "v16-fixups" ... | |
747 | ==> setting up auditing ... | |
748 | ==> setting up encounter/episode FKs and IDXs ... | |
749 | ==> upgrading reference data sets ... | |
750 | You are about to install the following parts of GNUmed: | |
751 | ------------------------------------------------------- | |
752 | bundle "v16_fixups-pre_v17" in <gnumed_v17> (or overridden) on <> | |
753 | bundle "v16-v17-static" in <gnumed_v17> (or overridden) on <> | |
754 | bundle "v16-v17-dynamic" in <gnumed_v17> (or overridden) on <> | |
755 | bundle "v17-fixups" in <gnumed_v17> (or overridden) on <> | |
756 | ------------------------------------------------------- | |
757 | This will update an existing GNUmed version 16 | |
758 | database to the version 17 schema. It does not do | |
759 | any harm to the data contained within. | |
760 | ||
761 | The existing database will be cloned first. The copy is | |
762 | then modified. The original database remains unchanged. | |
763 | ==> bootstrapping "v16_fixups-pre_v17" ... | |
764 | ==> dropping pre-existing target database [gnumed_v17] ... | |
765 | ==> cloning [gnumed_v16] (44 MB) as target database [gnumed_v17] ... | |
766 | ==> reindexing target database (can take a while) ... | |
767 | ==> transferring users ... | |
768 | ==> bootstrapping "v16-v17-static" ... | |
769 | ==> bootstrapping "v16-v17-dynamic" ... | |
770 | ==> bootstrapping "v17-fixups" ... | |
771 | ==> setting up auditing ... | |
772 | ==> setting up encounter/episode FKs and IDXs ... | |
773 | ==> upgrading reference data sets ... | |
774 | You are about to install the following parts of GNUmed: | |
775 | ------------------------------------------------------- | |
776 | bundle "v17_fixups-pre_v18" in <gnumed_v18> (or overridden) on <> | |
777 | bundle "v17-v18-static" in <gnumed_v18> (or overridden) on <> | |
778 | bundle "v17-v18-dynamic" in <gnumed_v18> (or overridden) on <> | |
779 | bundle "v18-fixups" in <gnumed_v18> (or overridden) on <> | |
780 | ------------------------------------------------------- | |
781 | This will update an existing GNUmed version 17 | |
782 | database to the version 18 schema. It does not do | |
783 | any harm to the data contained within. | |
784 | ||
785 | The existing database will be cloned first. The copy is | |
786 | then modified. The original database remains unchanged. | |
787 | ==> bootstrapping "v17_fixups-pre_v18" ... | |
788 | ==> dropping pre-existing target database [gnumed_v18] ... | |
789 | ==> cloning [gnumed_v17] (45 MB) as target database [gnumed_v18] ... | |
790 | ==> reindexing target database (can take a while) ... | |
791 | ==> transferring users ... | |
792 | ==> bootstrapping "v17-v18-static" ... | |
793 | ==> bootstrapping "v17-v18-dynamic" ... | |
794 | ==> bootstrapping "v18-fixups" ... | |
795 | ==> setting up auditing ... | |
796 | ==> setting up encounter/episode FKs and IDXs ... | |
797 | ==> upgrading reference data sets ... | |
798 | You are about to install the following parts of GNUmed: | |
799 | ------------------------------------------------------- | |
800 | bundle "v18_fixups-pre_v19" in <gnumed_v19> (or overridden) on <> | |
801 | bundle "v18-v19-static" in <gnumed_v19> (or overridden) on <> | |
802 | bundle "v18-v19-dynamic" in <gnumed_v19> (or overridden) on <> | |
803 | bundle "v19-fixups" in <gnumed_v19> (or overridden) on <> | |
804 | ------------------------------------------------------- | |
805 | This will update an existing GNUmed version 18 | |
806 | database to the version 19 schema. It does not do | |
807 | any harm to the data contained within. | |
808 | ||
809 | The existing database will be cloned first. The copy is | |
810 | then modified. The original database remains unchanged. | |
811 | ||
812 | ************************************************************ | |
813 | * Before upgrading your existing v18 database to the * | |
814 | * v19 schema it is very advisable to make sure you * | |
815 | * have created - using the 1.3 client against the v18 * | |
816 | * database -- an organization and a unit thereof to * | |
817 | * serve as your praxis and praxis location. During the * | |
818 | * very first start of the 1.4 client you will be asked * | |
819 | * which organization/unit represents your praxis/location. * | |
820 | ************************************************************ | |
821 | ||
822 | ==> bootstrapping "v18_fixups-pre_v19" ... | |
823 | ==> dropping pre-existing target database [gnumed_v19] ... | |
824 | ==> cloning [gnumed_v18] (52 MB) as target database [gnumed_v19] ... | |
825 | ==> reindexing target database (can take a while) ... | |
826 | ==> transferring users ... | |
827 | ==> bootstrapping "v18-v19-static" ... | |
828 | ==> bootstrapping "v18-v19-dynamic" ... | |
829 | ==> bootstrapping "v19-fixups" ... | |
830 | ==> setting up auditing ... | |
831 | ==> setting up encounter/episode FKs and IDXs ... | |
832 | ==> setting up generic notifications ... | |
833 | ==> upgrading reference data sets ... | |
834 | You are about to install the following parts of GNUmed: | |
835 | ------------------------------------------------------- | |
836 | bundle "v19_fixups-pre_v20" in <gnumed_v20> (or overridden) on <> | |
837 | bundle "v19-v20-static" in <gnumed_v20> (or overridden) on <> | |
838 | bundle "v19-v20-dynamic" in <gnumed_v20> (or overridden) on <> | |
839 | bundle "v20-fixups" in <gnumed_v20> (or overridden) on <> | |
840 | ------------------------------------------------------- | |
841 | This will update an existing GNUmed version 19 | |
842 | database to the version 20 schema. It does not do | |
843 | any harm to the data contained within. | |
844 | ||
845 | The existing database will be cloned first. The copy is | |
846 | then modified. The original database remains unchanged. | |
847 | ==> bootstrapping "v19_fixups-pre_v20" ... | |
848 | ==> dropping pre-existing target database [gnumed_v20] ... | |
849 | ==> cloning [gnumed_v19] (68 MB) as target database [gnumed_v20] ... | |
850 | ==> reindexing target database (can take a while) ... | |
851 | ==> transferring users ... | |
852 | ==> bootstrapping "v19-v20-static" ... | |
853 | ==> bootstrapping "v19-v20-dynamic" ... | |
854 | ==> bootstrapping "v20-fixups" ... | |
855 | ==> setting up auditing ... | |
856 | ==> setting up encounter/episode FKs and IDXs ... | |
857 | ==> setting up encounter/episode FK sanity check triggers ... | |
858 | ==> setting up generic notifications ... | |
859 | ==> upgrading reference data sets ... | |
860 | You are about to install the following parts of GNUmed: | |
861 | ------------------------------------------------------- | |
862 | bundle "v20_fixups-pre_v21" in <gnumed_v21> (or overridden) on <> | |
863 | bundle "v20-v21-static" in <gnumed_v21> (or overridden) on <> | |
864 | bundle "v20-v21-dynamic" in <gnumed_v21> (or overridden) on <> | |
865 | bundle "v21-fixups" in <gnumed_v21> (or overridden) on <> | |
866 | ------------------------------------------------------- | |
867 | This will update an existing GNUmed version 20 | |
868 | database to the version 21 schema. It does not do | |
869 | any harm to the data contained within. | |
870 | ||
871 | The existing database will be cloned first. The copy is | |
872 | then modified. The original database remains unchanged. | |
873 | ==> bootstrapping "v20_fixups-pre_v21" ... | |
874 | ==> dropping pre-existing target database [gnumed_v21] ... | |
875 | ==> cloning [gnumed_v20] (69 MB) as target database [gnumed_v21] ... | |
876 | ==> reindexing target database (can take a while) ... | |
877 | ==> transferring users ... | |
878 | ==> bootstrapping "v20-v21-static" ... | |
879 | ==> bootstrapping "v20-v21-dynamic" ... | |
880 | ==> bootstrapping "v21-fixups" ... | |
881 | ==> setting up auditing ... | |
882 | ==> setting up encounter/episode FKs and IDXs ... | |
883 | ==> setting up encounter/episode FK sanity check triggers ... | |
884 | ==> setting up generic notifications ... | |
885 | ==> upgrading reference data sets ... | |
886 | ==> verifying target database schema ... | |
887 | ==> checking migrated data for plausibility ... | |
888 | Done bootstrapping GNUmed database: We very likely succeeded. | |
889 | log: /home/ncq/Projekte/gm-git/gnumed/gnumed/server/bootstrap/bootstrap-latest.log | |
890 | *** Error in `python': free(): invalid pointer: 0x00770b14 *** | |
891 | ======= Backtrace: ========= | |
892 | /lib/i386-linux-gnu/libc.so.6(+0x6738a)[0xb7ccc38a] | |
893 | /lib/i386-linux-gnu/libc.so.6(+0x6dfc7)[0xb7cd2fc7] | |
894 | /lib/i386-linux-gnu/libc.so.6(+0x6e806)[0xb7cd3806] | |
895 | python(PyObject_Free+0xfb)[0x44affb] | |
896 | python(+0x110b51)[0x534b51] | |
897 | python(+0x110b51)[0x534b51] | |
898 | python(+0x110b51)[0x534b51] | |
899 | python(+0xf3ea7)[0x517ea7] | |
900 | python(PyDict_SetItem+0x201)[0x4d4f81] | |
901 | python(_PyModule_Clear+0x150)[0x539630] | |
902 | python(PyImport_Cleanup+0x61d)[0x53927d] | |
903 | python(Py_Finalize+0x9d)[0x53635d] | |
904 | python(Py_Exit+0x14)[0x55cb24] | |
905 | python(+0x136102)[0x55a102] | |
906 | python(PyErr_PrintEx+0x35)[0x559975] | |
907 | python(+0x3dd41)[0x461d41] | |
908 | python(Py_Main+0x753)[0x4d2c83] | |
909 | python(main+0x1b)[0x4d251b] | |
910 | /lib/i386-linux-gnu/libc.so.6(__libc_start_main+0xf6)[0xb7c7d286] | |
911 | python(+0xae3f3)[0x4d23f3] | |
912 | ======= Memory map: ======== | |
913 | 00424000-00763000 r-xp 00000000 08:01 6285092 /usr/bin/python2.7 | |
914 | 00763000-00764000 r--p 0033e000 08:01 6285092 /usr/bin/python2.7 | |
915 | 00764000-007c4000 rw-p 0033f000 08:01 6285092 /usr/bin/python2.7 | |
916 | 007c4000-007d9000 rw-p 00000000 00:00 0 | |
917 | 026f1000-02921000 rw-p 00000000 00:00 0 [heap] | |
918 | b6800000-b6821000 rw-p 00000000 00:00 0 | |
919 | b6821000-b6900000 ---p 00000000 00:00 0 | |
920 | b6995000-b69b0000 r-xp 00000000 08:01 8151085 /lib/i386-linux-gnu/libgcc_s.so.1 | |
921 | b69b0000-b69b1000 r--p 0001a000 08:01 8151085 /lib/i386-linux-gnu/libgcc_s.so.1 | |
922 | b69b1000-b69b2000 rw-p 0001b000 08:01 8151085 /lib/i386-linux-gnu/libgcc_s.so.1 | |
923 | b69f5000-b6b35000 rw-p 00000000 00:00 0 | |
924 | b6b35000-b6b40000 r-xp 00000000 08:01 8151337 /lib/i386-linux-gnu/libnss_files-2.24.so | |
925 | b6b40000-b6b41000 r--p 0000a000 08:01 8151337 /lib/i386-linux-gnu/libnss_files-2.24.so | |
926 | b6b41000-b6b42000 rw-p 0000b000 08:01 8151337 /lib/i386-linux-gnu/libnss_files-2.24.so | |
927 | b6b42000-b6b48000 rw-p 00000000 00:00 0 | |
928 | b6b48000-b6b53000 r-xp 00000000 08:01 8151339 /lib/i386-linux-gnu/libnss_nis-2.24.so | |
929 | b6b53000-b6b54000 r--p 0000a000 08:01 8151339 /lib/i386-linux-gnu/libnss_nis-2.24.so | |
930 | b6b54000-b6b55000 rw-p 0000b000 08:01 8151339 /lib/i386-linux-gnu/libnss_nis-2.24.so | |
931 | b6b64000-b6b6b000 r--p 00000000 08:01 6286752 /usr/share/locale/de/LC_MESSAGES/libpq5-10.mo | |
932 | b6b6b000-b6b72000 r--s 00000000 08:01 6903281 /usr/lib/i386-linux-gnu/gconv/gconv-modules.cache | |
933 | b6b72000-b6b98000 r--p 00000000 08:01 6288754 /usr/share/locale/de/LC_MESSAGES/libc.mo | |
934 | b6b98000-b6c98000 rw-p 00000000 00:00 0 | |
935 | b6c9e000-b6cb4000 r-xp 00000000 08:01 8151334 /lib/i386-linux-gnu/libnsl-2.24.so | |
936 | b6cb4000-b6cb5000 r--p 00016000 08:01 8151334 /lib/i386-linux-gnu/libnsl-2.24.so | |
937 | b6cb5000-b6cb6000 rw-p 00017000 08:01 8151334 /lib/i386-linux-gnu/libnsl-2.24.so | |
938 | b6cb6000-b6cb8000 rw-p 00000000 00:00 0 | |
939 | b6cb8000-b6cc0000 r-xp 00000000 08:01 8151335 /lib/i386-linux-gnu/libnss_compat-2.24.so | |
940 | b6cc0000-b6cc1000 r--p 00007000 08:01 8151335 /lib/i386-linux-gnu/libnss_compat-2.24.so | |
941 | b6cc1000-b6cc2000 rw-p 00008000 08:01 8151335 /lib/i386-linux-gnu/libnss_compat-2.24.so | |
942 | b6cc2000-b6d02000 rw-p 00000000 00:00 0 | |
943 | b6d02000-b6d09000 r-xp 00000000 08:01 6899491 /usr/lib/i386-linux-gnu/libffi.so.6.0.4 | |
944 | b6d09000-b6d0a000 r--p 00006000 08:01 6899491 /usr/lib/i386-linux-gnu/libffi.so.6.0.4 | |
945 | b6d0a000-b6d0b000 rw-p 00007000 08:01 6899491 /usr/lib/i386-linux-gnu/libffi.so.6.0.4 | |
946 | b6d0b000-b6d96000 r-xp 00000000 08:01 6899509 /usr/lib/i386-linux-gnu/libgmp.so.10.3.2 | |
947 | b6d96000-b6d97000 r--p 0008a000 08:01 6899509 /usr/lib/i386-linux-gnu/libgmp.so.10.3.2 | |
948 | b6d97000-b6d98000 rw-p 0008b000 08:01 6899509 /usr/lib/i386-linux-gnu/libgmp.so.10.3.2 | |
949 | b6d98000-b6dcc000 r-xp 00000000 08:01 6899139 /usr/lib/i386-linux-gnu/libhogweed.so.4.3 | |
950 | b6dcc000-b6dcd000 r--p 00033000 08:01 6899139 /usr/lib/i386-linux-gnu/libhogweed.so.4.3 | |
951 | b6dcd000-b6dce000 rw-p 00034000 08:01 6899139 /usr/lib/i386-linux-gnu/libhogweed.so.4.3 | |
952 | b6dce000-b6e08000 r-xp 00000000 08:01 6897991 /usr/lib/i386-linux-gnu/libnettle.so.6.3 | |
953 | b6e08000-b6e09000 ---p 0003a000 08:01 6897991 /usr/lib/i386-linux-gnu/libnettle.so.6.3 | |
954 | b6e09000-b6e0a000 r--p 0003a000 08:01 6897991 /usr/lib/i386-linux-gnu/libnettle.so.6.3 | |
955 | b6e0a000-b6e0b000 rw-p 0003b000 08:01 6897991 /usr/lib/i386-linux-gnu/libnettle.so.6.3 | |
956 | b6e0b000-b6e1e000 r-xp 00000000 08:01 6898338 /usr/lib/i386-linux-gnu/libtasn1.so.6.5.4 | |
957 | b6e1e000-b6e1f000 r--p 00012000 08:01 6898338 /usr/lib/i386-linux-gnu/libtasn1.so.6.5.4 | |
958 | b6e1f000-b6e20000 rw-p 00013000 08:01 6898338 /usr/lib/i386-linux-gnu/libtasn1.so.6.5.4 | |
959 | b6e20000-b6f8c000 r-xp 00000000 08:01 6899693 /usr/lib/i386-linux-gnu/libunistring.so.2.0.0 | |
960 | b6f8c000-b6f8d000 ---p 0016c000 08:01 6899693 /usr/lib/i386-linux-gnu/libunistring.so.2.0.0 | |
961 | b6f8d000-b6f8f000 r--p 0016c000 08:01 6899693 /usr/lib/i386-linux-gnu/libunistring.so.2.0.0 | |
962 | b6f8f000-b6f90000 rw-p 0016e000 08:01 6899693 /usr/lib/i386-linux-gnu/libunistring.so.2.0.0 | |
963 | b6f90000-b6fac000 r-xp 00000000 08:01 6899147 /usr/lib/i386-linux-gnu/libidn2.so.0.3.1 | |
964 | b6fac000-b6fad000 r--p 0001b000 08:01 6899147 /usr/lib/i386-linux-gnu/libidn2.so.0.3.1 | |
965 | b6fad000-b6fae000 rw-p 0001c000 08:01 6899147 /usr/lib/i386-linux-gnu/libidn2.so.0.3.1 | |
966 | b6fae000-b70fe000 r-xp 00000000 08:01 6899036 /usr/lib/i386-linux-gnu/libp11-kit.so.0.3.0 | |
967 | b70fe000-b7104000 r--p 0014f000 08:01 6899036 /usr/lib/i386-linux-gnu/libp11-kit.so.0.3.0 | |
968 | b7104000-b7109000 rw-p 00155000 08:01 6899036 /usr/lib/i386-linux-gnu/libp11-kit.so.0.3.0 | |
969 | b7109000-b710a000 rw-p 00000000 00:00 0 | |
970 | b710a000-b7299000 r-xp 00000000 08:01 6898093 /usr/lib/i386-linux-gnu/libgnutls.so.30.14.7 | |
971 | b7299000-b72a1000 r--p 0018e000 08:01 6898093 /usr/lib/i386-linux-gnu/libgnutls.so.30.14.7 | |
972 | b72a1000-b72a2000 rw-p 00196000 08:01 6898093 /usr/lib/i386-linux-gnu/libgnutls.so.30.14.7 | |
973 | b72a2000-b72a3000 rw-p 00000000 00:00 0 | |
974 | b72a3000-b72bf000 r-xp 00000000 08:01 6897853 /usr/lib/i386-linux-gnu/libsasl2.so.2.0.25 | |
975 | b72bf000-b72c0000 r--p 0001b000 08:01 6897853 /usr/lib/i386-linux-gnu/libsasl2.so.2.0.25 | |
976 | b72c0000-b72c1000 rw-p 0001c000 08:01 6897853 /usr/lib/i386-linux-gnu/libsasl2.so.2.0.25 | |
977 | b72c1000-b72d5000 r-xp 00000000 08:01 8151343 /lib/i386-linux-gnu/libresolv-2.24.so | |
978 | b72d5000-b72d6000 r--p 00013000 08:01 8151343 /lib/i386-linux-gnu/libresolv-2.24.so | |
979 | b72d6000-b72d7000 rw-p 00014000 08:01 8151343 /lib/i386-linux-gnu/libresolv-2.24.so | |
980 | b72d7000-b72d9000 rw-p 00000000 00:00 0 | |
981 | b72d9000-b730b000 r-xp 00000000 08:01 6898091 /usr/lib/i386-linux-gnu/libk5crypto.so.3.1 | |
982 | b730b000-b730c000 ---p 00032000 08:01 6898091 /usr/lib/i386-linux-gnu/libk5crypto.so.3.1 | |
983 | b730c000-b730d000 r--p 00032000 08:01 6898091 /usr/lib/i386-linux-gnu/libk5crypto.so.3.1 | |
984 | b730d000-b730e000 rw-p 00033000 08:01 6898091 /usr/lib/i386-linux-gnu/libk5crypto.so.3.1 | |
985 | b730e000-b730f000 rw-p 00000000 00:00 0 | |
986 | b730f000-b73e2000 r-xp 00000000 08:01 6898964 /usr/lib/i386-linux-gnu/libkrb5.so.3.3 | |
987 | b73e2000-b73e3000 ---p 000d3000 08:01 6898964 /usr/lib/i386-linux-gnu/libkrb5.so.3.3 | |
988 | b73e3000-b73e9000 r--p 000d3000 08:01 6898964 /usr/lib/i386-linux-gnu/libkrb5.so.3.3 | |
989 | b73e9000-b73eb000 rw-p 000d9000 08:01 6898964 /usr/lib/i386-linux-gnu/libkrb5.so.3.3 | |
990 | b73eb000-b7441000 r-xp 00000000 08:01 6899719 /usr/lib/i386-linux-gnu/libldap_r-2.4.so.2.10.8 | |
991 | b7441000-b7442000 ---p 00056000 08:01 6899719 /usr/lib/i386-linux-gnu/libldap_r-2.4.so.2.10.8 | |
992 | b7442000-b7443000 r--p 00056000 08:01 6899719 /usr/lib/i386-linux-gnu/libldap_r-2.4.so.2.10.8 | |
993 | b7443000-b7444000 rw-p 00057000 08:01 6899719 /usr/lib/i386-linux-gnu/libldap_r-2.4.so.2.10.8 | |
994 | b7444000-b7445000 rw-p 00000000 00:00 0 | |
995 | b7445000-b7495000 r-xp 00000000 08:01 6898215 /usr/lib/i386-linux-gnu/libgssapi_krb5.so.2.2 | |
996 | b7495000-b7496000 r--p 0004f000 08:01 6898215 /usr/lib/i386-linux-gnu/libgssapi_krb5.so.2.2 | |
997 | b7496000-b7497000 rw-p 00050000 08:01 6898215 /usr/lib/i386-linux-gnu/libgssapi_krb5.so.2.2 | |
998 | b7497000-b74e1000 r-xp 00000000 08:01 6899474 /usr/lib/i386-linux-gnu/libpq.so.5.10 | |
999 | b74e1000-b74e3000 r--p 00049000 08:01 6899474 /usr/lib/i386-linux-gnu/libpq.so.5.10 | |
1000 | b74e3000-b74e4000 rw-p 0004b000 08:01 6899474 /usr/lib/i386-linux-gnu/libpq.so.5.10 | |
1001 | b74e8000-b74ed000 r-xp 00000000 08:01 6365428 /usr/lib/python2.7/dist-packages/faulthandler.i386-linux-gnu.so | |
1002 | b74ed000-b74ee000 r--p 00004000 08:01 6365428 /usr/lib/python2.7/dist-packages/faulthandler.i386-linux-gnu.so | |
1003 | b74ee000-b74ef000 rw-p 00005000 08:01 6365428 /usr/lib/python2.7/dist-packages/faulthandler.i386-linux-gnu.so | |
1004 | b74ef000-b74f6000 r-xp 00000000 08:01 6367548 /usr/lib/python2.7/lib-dynload/_csv.i386-linux-gnu.so | |
1005 | b74f6000-b74f7000 r--p 00006000 08:01 6367548 /usr/lib/python2.7/lib-dynload/_csv.i386-linux-gnu.so | |
1006 | b74f7000-b74f9000 rw-p 00007000 08:01 6367548 /usr/lib/python2.7/lib-dynload/_csv.i386-linux-gnu.so | |
1007 | b74f9000-b750c000 r-xp 00000000 08:01 6367559 /usr/lib/python2.7/lib-dynload/_json.i386-linux-gnu.so | |
1008 | b750c000-b750d000 r--p 00012000 08:01 6367559 /usr/lib/python2.7/lib-dynload/_json.i386-linux-gnu.so | |
1009 | b750d000-b750e000 rw-p 00013000 08:01 6367559 /usr/lib/python2.7/lib-dynload/_json.i386-linux-gnu.so | |
1010 | b750e000-b7523000 r-xp 00000000 08:01 6367569 /usr/lib/python2.7/lib-dynload/_ssl.i386-linux-gnu.so | |
1011 | b7523000-b7524000 r--p 00014000 08:01 6367569 /usr/lib/python2.7/lib-dynload/_ssl.i386-linux-gnu.so | |
1012 | b7524000-b7527000 rw-p 00015000 08:01 6367569 /usr/lib/python2.7/lib-dynload/_ssl.i386-linux-gnu.so | |
1013 | b7527000-b7559000 r-xp 00000000 08:01 6479968 /usr/lib/python2.7/dist-packages/psycopg2/_psycopg.i386-linux-gnu.so | |
1014 | b7559000-b755a000 r--p 00031000 08:01 6479968 /usr/lib/python2.7/dist-packages/psycopg2/_psycopg.i386-linux-gnu.so | |
1015 | b755a000-b755e000 rw-p 00032000 08:01 6479968 /usr/lib/python2.7/dist-packages/psycopg2/_psycopg.i386-linux-gnu.so | |
1016 | b755e000-b756e000 r-xp 00000000 08:01 8151113 /lib/i386-linux-gnu/libbz2.so.1.0.4 | |
1017 | b756e000-b756f000 r--p 0000f000 08:01 8151113 /lib/i386-linux-gnu/libbz2.so.1.0.4 | |
1018 | b756f000-b7570000 rw-p 00010000 08:01 8151113 /lib/i386-linux-gnu/libbz2.so.1.0.4 | |
1019 | b7576000-b7584000 r-xp 00000000 08:01 6897979 /usr/lib/i386-linux-gnu/liblber-2.4.so.2.10.8 | |
1020 | b7584000-b7585000 r--p 0000d000 08:01 6897979 /usr/lib/i386-linux-gnu/liblber-2.4.so.2.10.8 | |
1021 | b7585000-b7586000 rw-p 0000e000 08:01 6897979 /usr/lib/i386-linux-gnu/liblber-2.4.so.2.10.8 | |
1022 | b7586000-b7589000 r-xp 00000000 08:01 8151178 /lib/i386-linux-gnu/libkeyutils.so.1.5 | |
1023 | b7589000-b758a000 r--p 00002000 08:01 8151178 /lib/i386-linux-gnu/libkeyutils.so.1.5 | |
1024 | b758a000-b758b000 rw-p 00003000 08:01 8151178 /lib/i386-linux-gnu/libkeyutils.so.1.5 | |
1025 | b758b000-b7596000 r-xp 00000000 08:01 6899192 /usr/lib/i386-linux-gnu/libkrb5support.so.0.1 | |
1026 | b7596000-b7597000 r--p 0000a000 08:01 6899192 /usr/lib/i386-linux-gnu/libkrb5support.so.0.1 | |
1027 | b7597000-b7598000 rw-p 0000b000 08:01 6899192 /usr/lib/i386-linux-gnu/libkrb5support.so.0.1 | |
1028 | b7598000-b759f000 r-xp 00000000 08:01 8151344 /lib/i386-linux-gnu/librt-2.24.so | |
1029 | b759f000-b75a0000 r--p 00006000 08:01 8151344 /lib/i386-linux-gnu/librt-2.24.so | |
1030 | b75a0000-b75a1000 rw-p 00007000 08:01 8151344 /lib/i386-linux-gnu/librt-2.24.so | |
1031 | b75a1000-b75b1000 r-xp 00000000 08:01 6570027 /usr/lib/python2.7/dist-packages/mx/DateTime/mxDateTime/mxDateTime.so | |
1032 | b75b1000-b75b2000 r--p 0000f000 08:01 6570027 /usr/lib/python2.7/dist-packages/mx/DateTime/mxDateTime/mxDateTime.so | |
1033 | b75b2000-b75b3000 rw-p 00010000 08:01 6570027 /usr/lib/python2.7/dist-packages/mx/DateTime/mxDateTime/mxDateTime.so | |
1034 | b75b3000-b77fe000 r-xp 00000000 08:01 6897994 /usr/lib/i386-linux-gnu/libcrypto.so.1.1 | |
1035 | b77fe000-b77ff000 ---p 0024b000 08:01 6897994 /usr/lib/i386-linux-gnu/libcrypto.so.1.1 | |
1036 | b77ff000-b7810000 r--p 0024b000 08:01 6897994 /usr/lib/i386-linux-gnu/libcrypto.so.1.1 | |
1037 | b7810000-b7817000 rw-p 0025c000 08:01 6897994 /usr/lib/i386-linux-gnu/libcrypto.so.1.1 | |
1038 | b7817000-b781a000 rw-p 00000000 00:00 0 | |
1039 | b781a000-b7881000 r-xp 00000000 08:01 6899137 /usr/lib/i386-linux-gnu/libssl.so.1.1 | |
1040 | b7881000-b7884000 r--p 00066000 08:01 6899137 /usr/lib/i386-linux-gnu/libssl.so.1.1 | |
1041 | b7884000-b7888000 rw-p 00069000 08:01 6899137 /usr/lib/i386-linux-gnu/libssl.so.1.1 | |
1042 | b7888000-b7988000 rw-p 00000000 00:00 0 | |
1043 | b798a000-b798d000 r-xp 00000000 08:01 8151240 /lib/i386-linux-gnu/libcom_err.so.2.1 | |
1044 | b798d000-b798e000 r--p 00002000 08:01 8151240 /lib/i386-linux-gnu/libcom_err.so.2.1 | |
1045 | b798e000-b798f000 rw-p 00003000 08:01 8151240 /lib/i386-linux-gnu/libcom_err.so.2.1 | |
1046 | b798f000-b7998000 r-xp 00000000 08:01 6367575 /usr/lib/python2.7/lib-dynload/bz2.i386-linux-gnu.so | |
1047 | b7998000-b7999000 r--p 00008000 08:01 6367575 /usr/lib/python2.7/lib-dynload/bz2.i386-linux-gnu.so | |
1048 | b7999000-b799b000 rw-p 00009000 08:01 6367575 /usr/lib/python2.7/lib-dynload/bz2.i386-linux-gnu.so | |
1049 | b799b000-b79fc000 rw-p 00000000 00:00 0 | |
1050 | b79fc000-b7a00000 r-xp 00000000 08:01 6367555 /usr/lib/python2.7/lib-dynload/_hashlib.i386-linux-gnu.so | |
1051 | b7a00000-b7a01000 r--p 00003000 08:01 6367555 /usr/lib/python2.7/lib-dynload/_hashlib.i386-linux-gnu.so | |
1052 | b7a01000-b7a02000 rw-p 00004000 08:01 6367555 /usr/lib/python2.7/lib-dynload/_hashlib.i386-linux-gnu.so | |
1053 | b7a02000-b7a05000 r-xp 00000000 08:01 6367622 /usr/lib/python2.7/lib-dynload/termios.i386-linux-gnu.so | |
1054 | b7a05000-b7a06000 r--p 00002000 08:01 6367622 /usr/lib/python2.7/lib-dynload/termios.i386-linux-gnu.so | |
1055 | b7a06000-b7a08000 rw-p 00003000 08:01 6367622 /usr/lib/python2.7/lib-dynload/termios.i386-linux-gnu.so | |
1056 | b7a08000-b7a48000 rw-p 00000000 00:00 0 | |
1057 | b7a48000-b7be3000 r--p 00000000 08:01 6299936 /usr/lib/locale/locale-archive | |
1058 | b7be3000-b7c65000 rw-p 00000000 00:00 0 | |
1059 | b7c65000-b7e16000 r-xp 00000000 08:01 8151265 /lib/i386-linux-gnu/libc-2.24.so | |
1060 | b7e16000-b7e18000 r--p 001b0000 08:01 8151265 /lib/i386-linux-gnu/libc-2.24.so | |
1061 | b7e18000-b7e19000 rw-p 001b2000 08:01 8151265 /lib/i386-linux-gnu/libc-2.24.so | |
1062 | b7e19000-b7e1c000 rw-p 00000000 00:00 0 | |
1063 | b7e1c000-b7e6f000 r-xp 00000000 08:01 8151332 /lib/i386-linux-gnu/libm-2.24.so | |
1064 | b7e6f000-b7e70000 r--p 00052000 08:01 8151332 /lib/i386-linux-gnu/libm-2.24.so | |
1065 | b7e70000-b7e71000 rw-p 00053000 08:01 8151332 /lib/i386-linux-gnu/libm-2.24.so | |
1066 | b7e71000-b7e8a000 r-xp 00000000 08:01 8151148 /lib/i386-linux-gnu/libz.so.1.2.8 | |
1067 | b7e8a000-b7e8b000 r--p 00018000 08:01 8151148 /lib/i386-linux-gnu/libz.so.1.2.8 | |
1068 | b7e8b000-b7e8c000 rw-p 00019000 08:01 8151148 /lib/i386-linux-gnu/libz.so.1.2.8 | |
1069 | b7e8c000-b7e8e000 r-xp 00000000 08:01 8151355 /lib/i386-linux-gnu/libutil-2.24.so | |
1070 | b7e8e000-b7e8f000 r--p 00001000 08:01 8151355 /lib/i386-linux-gnu/libutil-2.24.so | |
1071 | b7e8f000-b7e90000 rw-p 00002000 08:01 8151355 /lib/i386-linux-gnu/libutil-2.24.so | |
1072 | b7e90000-b7e93000 r-xp 00000000 08:01 8151331 /lib/i386-linux-gnu/libdl-2.24.so | |
1073 | b7e93000-b7e94000 r--p 00002000 08:01 8151331 /lib/i386-linux-gnu/libdl-2.24.so | |
1074 | b7e94000-b7e95000 rw-p 00003000 08:01 8151331 /lib/i386-linux-gnu/libdl-2.24.so | |
1075 | b7e95000-b7eae000 r-xp 00000000 08:01 8151342 /lib/i386-linux-gnu/libpthread-2.24.so | |
1076 | b7eae000-b7eaf000 r--p 00018000 08:01 8151342 /lib/i386-linux-gnu/libpthread-2.24.so | |
1077 | b7eaf000-b7eb0000 rw-p 00019000 08:01 8151342 /lib/i386-linux-gnu/libpthread-2.24.so | |
1078 | b7eb0000-b7eb2000 rw-p 00000000 00:00 0 | |
1079 | b7eb4000-b7ef8000 rw-p 00000000 00:00 0 | |
1080 | b7ef8000-b7efb000 r--p 00000000 00:00 0 [vvar] | |
1081 | b7efb000-b7efd000 r-xp 00000000 00:00 0 [vdso] | |
1082 | b7efd000-b7f20000 r-xp 00000000 08:01 8151050 /lib/i386-linux-gnu/ld-2.24.so | |
1083 | b7f20000-b7f21000 r--p 00022000 08:01 8151050 /lib/i386-linux-gnu/ld-2.24.so | |
1084 | b7f21000-b7f22000 rw-p 00023000 08:01 8151050 /lib/i386-linux-gnu/ld-2.24.so | |
1085 | bf9f5000-bfa16000 rw-p 00000000 00:00 0 [stack] | |
1086 | Fatal Python error: Aborted | |
1087 | ||
1088 | Current thread 0xb7c63d00 (most recent call first): | |
1089 | ./bootstrap-latest.sh: Zeile 80: 20984 Abgebrochen ./bootstrap_gm_db_system.py --log-file=${LOG} --conf-file=${CONF} --${QUIET} | |
1090 | Bootstrapping "gnumed_v21" did not finish successfully (134). Aborting. | |
1091 | ||
1092 | Sie haben neue Post in /var/mail/ncq. | |
1093 | ncq@hermes:~/Projekte/gm-git/gnumed/gnumed/server/bootstrap$ exit | |
1094 | exit | |
1095 | ||
1096 | Script done on 2017-10-16 23:18:46+0200 |
77 | 77 | LOG="${GM_LOG_BASE}/bootstrap-latest.log" |
78 | 78 | CONF="bootstrap-latest.conf" |
79 | 79 | ./bootstrap_gm_db_system.py --log-file=${LOG} --conf-file=${CONF} --${QUIET} |
80 | if test "$?" != "0" ; then | |
81 | echo "Bootstrapping \"gnumed_v${VER}\" did not finish successfully. Aborting." | |
80 | #gdb --args /usr/bin/python2.7-dbg ./bootstrap_gm_db_system.py --log-file=${LOG} --conf-file=${CONF} --${QUIET} | |
81 | RESULT="$?" | |
82 | if test "${RESULT}" != "0" ; then | |
83 | echo "Bootstrapping \"gnumed_v${VER}\" did not finish successfully (${RESULT}). Aborting." | |
82 | 84 | read |
83 | 85 | exit 1 |
84 | 86 | fi |
0 | 0 | #!/usr/bin/env python |
1 | ||
2 | """GNUmed schema installation. | |
1 | ##!/usr/bin/python2.7-dbg | |
2 | ||
3 | u"""GNUmed schema installation. | |
3 | 4 | |
4 | 5 | This script bootstraps a GNUmed database system. |
5 | 6 | |
24 | 25 | --log-file= |
25 | 26 | --conf-file= |
26 | 27 | |
27 | Requires psycopg 2.7 ! | |
28 | Requires psycopg 2.7.3 ! | |
28 | 29 | """ |
29 | 30 | #================================================================== |
30 | 31 | # TODO |
81 | 82 | except ImportError: |
82 | 83 | print """Please make sure the GNUmed Python modules are in the Python path !""" |
83 | 84 | raise |
84 | from Gnumed.pycommon import gmCfg2, gmPsql, gmPG2, gmTools, gmI18N | |
85 | from Gnumed.pycommon import gmCfg2 | |
86 | from Gnumed.pycommon import gmPsql | |
87 | from Gnumed.pycommon import gmPG2 | |
88 | from Gnumed.pycommon import gmTools | |
89 | from Gnumed.pycommon import gmI18N | |
85 | 90 | from Gnumed.pycommon.gmExceptions import ConstructorError |
86 | 91 | |
87 | 92 | |
91 | 96 | |
92 | 97 | |
93 | 98 | _log = logging.getLogger('gm.bootstrapper') |
99 | ||
100 | try: | |
101 | import faulthandler | |
102 | #faulthandler.enable(file = gmLog2._logfile) | |
103 | faulthandler.enable() | |
104 | except ImportError: | |
105 | _log.error(u'<faulthandler> not available') | |
106 | ||
94 | 107 | _cfg = gmCfg2.gmCfgData() |
95 | 108 | |
96 | 109 | |
97 | _interactive = False | |
110 | _interactive = None | |
98 | 111 | _bootstrapped_servers = {} |
99 | 112 | _bootstrapped_dbs = {} |
100 | 113 | _dbowner = None |
204 | 217 | try: |
205 | 218 | cursor.execute(cmd, args) |
206 | 219 | except: |
207 | _log.exception(">>>[%s]<<< failed for user [%s]", cmd, user) | |
220 | _log.exception(u">>>[%s]<<< failed for user [%s]", cmd, user) | |
208 | 221 | return None |
209 | 222 | res = cursor.fetchone() |
210 | 223 | if cursor.rowcount == 1: |
211 | _log.info("user [%s] exists", user) | |
212 | return True | |
213 | _log.info("user [%s] does not exist", user) | |
224 | _log.info(u"user [%s] exists", user) | |
225 | return True | |
226 | _log.info(u"user [%s] does not exist", user) | |
214 | 227 | return None |
215 | 228 | #------------------------------------------------------------------ |
216 | 229 | def db_group_exists(cursor=None, group=None): |
219 | 232 | try: |
220 | 233 | cursor.execute(cmd, args) |
221 | 234 | except: |
222 | _log.exception(">>>[%s]<<< failed for group [%s]", cmd, group) | |
235 | _log.exception(u">>>[%s]<<< failed for group [%s]", cmd, group) | |
223 | 236 | return False |
224 | 237 | rows = cursor.fetchall() |
225 | 238 | if len(rows) > 0: |
226 | _log.info("group [%s] exists" % group) | |
227 | return True | |
228 | _log.info("group [%s] does not exist" % group) | |
239 | _log.info(u"group [%s] exists" % group) | |
240 | return True | |
241 | _log.info(u"group [%s] does not exist" % group) | |
229 | 242 | return False |
230 | 243 | #------------------------------------------------------------------ |
231 | 244 | def create_db_group(cursor=None, group=None): |
238 | 251 | try: |
239 | 252 | cursor.execute(cmd) |
240 | 253 | except: |
241 | _log.exception(">>>[%s]<<< failed for group [%s]", cmd, group) | |
254 | _log.exception(u">>>[%s]<<< failed for group [%s]", cmd, group) | |
242 | 255 | return False |
243 | 256 | |
244 | 257 | # paranoia is good |
265 | 278 | passwd = '' |
266 | 279 | |
267 | 280 | dsn = gmPG2.make_psycopg2_dsn(database=db, host=host, port=port, user=user, password=passwd) |
268 | _log.info("trying DB connection to %s on %s as %s", db, host or 'localhost', user) | |
281 | _log.info(u"trying DB connection to %s on %s as %s", db, host or 'localhost', user) | |
269 | 282 | try: |
270 | 283 | conn = gmPG2.get_connection(dsn=dsn, readonly=False, pooled=False, verbose=True, connection_name = conn_name) |
271 | 284 | except: |
276 | 289 | cached_passwd[user] = passwd |
277 | 290 | conn_ref_count.append(conn) |
278 | 291 | |
279 | _log.info('successfully connected') | |
292 | _log.info(u'successfully connected') | |
280 | 293 | return conn |
281 | 294 | |
282 | 295 | #================================================================== |
301 | 314 | # this means the user does not need a password |
302 | 315 | # but connects via IDENT or TRUST |
303 | 316 | if self.password is None: |
304 | _log.info('password not defined, assuming connect via IDENT/TRUST') | |
317 | _log.info(u'password not defined, assuming connect via IDENT/TRUST') | |
305 | 318 | # defined but empty: |
306 | 319 | # this means to ask the user if interactive |
307 | 320 | elif self.password == '': |
316 | 329 | #================================================================== |
317 | 330 | class db_server: |
318 | 331 | def __init__(self, aSrv_alias, auth_group): |
319 | _log.info("bootstrapping server [%s]" % aSrv_alias) | |
332 | _log.info(u"bootstrapping server [%s]" % aSrv_alias) | |
320 | 333 | |
321 | 334 | global _bootstrapped_servers |
322 | 335 | |
323 | 336 | if _bootstrapped_servers.has_key(aSrv_alias): |
324 | _log.info("server [%s] already bootstrapped" % aSrv_alias) | |
337 | _log.info(u"server [%s] already bootstrapped" % aSrv_alias) | |
325 | 338 | return None |
326 | 339 | |
327 | 340 | self.alias = aSrv_alias |
334 | 347 | |
335 | 348 | _bootstrapped_servers[self.alias] = self |
336 | 349 | |
337 | _log.info('done bootstrapping server [%s]', aSrv_alias) | |
350 | _log.info(u'done bootstrapping server [%s]', aSrv_alias) | |
338 | 351 | #-------------------------------------------------------------- |
339 | 352 | def __bootstrap(self): |
340 | 353 | self.superuser = user(anAlias = cfg_get(self.section, "super user alias")) |
341 | 354 | |
342 | 355 | # connect to server level template database |
343 | 356 | if not self.__connect_superuser_to_srv_template(): |
344 | _log.error("Cannot connect to server template database.") | |
357 | _log.error(u"Cannot connect to server template database.") | |
345 | 358 | return None |
346 | 359 | |
347 | 360 | # add users/groups |
348 | 361 | if not self.__bootstrap_db_users(): |
349 | _log.error("Cannot bootstrap database users.") | |
362 | _log.error(u"Cannot bootstrap database users.") | |
350 | 363 | return None |
351 | 364 | |
352 | 365 | self.conn.close() |
353 | 366 | return True |
354 | 367 | #-------------------------------------------------------------- |
355 | 368 | def __connect_superuser_to_srv_template(self): |
356 | _log.info("connecting to server template database") | |
369 | _log.info(u"connecting to server template database") | |
357 | 370 | |
358 | 371 | # sanity checks |
359 | 372 | self.template_db = cfg_get(self.section, "template database") |
360 | 373 | if self.template_db is None: |
361 | _log.error("Need to know the template database name.") | |
374 | _log.error(u"Need to know the template database name.") | |
362 | 375 | return None |
363 | 376 | |
364 | 377 | self.name = cfg_get(self.section, "name") |
365 | 378 | if self.name is None: |
366 | _log.error("Need to know the server name.") | |
379 | _log.error(u"Need to know the server name.") | |
367 | 380 | return None |
368 | 381 | |
369 | 382 | env_var = 'GM_DB_PORT' |
370 | 383 | self.port = os.getenv(env_var) |
371 | 384 | if self.port is None: |
372 | _log.info('environment variable [%s] is not set, using database port from config file' % env_var) | |
385 | _log.info(u'environment variable [%s] is not set, using database port from config file' % env_var) | |
373 | 386 | self.port = cfg_get(self.section, "port") |
374 | 387 | else: |
375 | _log.info('using database port [%s] from environment variable [%s]' % (self.port, env_var)) | |
388 | _log.info(u'using database port [%s] from environment variable [%s]' % (self.port, env_var)) | |
376 | 389 | if self.port is None: |
377 | _log.error("Need to know the database server port address.") | |
390 | _log.error(u"Need to know the database server port address.") | |
378 | 391 | return None |
379 | 392 | |
380 | 393 | if self.conn is not None: |
383 | 396 | |
384 | 397 | self.conn = connect(self.name, self.port, self.template_db, self.superuser.name, self.superuser.password, conn_name = u'root@template.server') |
385 | 398 | if self.conn is None: |
386 | _log.error('Cannot connect.') | |
399 | _log.error(u'Cannot connect.') | |
387 | 400 | return None |
388 | 401 | |
389 | 402 | self.conn.cookie = 'db_server.__connect_superuser_to_srv_template' |
393 | 406 | curs.execute(u"select setting from pg_settings where name = 'lc_ctype'") |
394 | 407 | data = curs.fetchall() |
395 | 408 | lc_ctype = data[0][0] |
396 | _log.info('template database LC_CTYPE is [%s]', lc_ctype) | |
409 | _log.info(u'template database LC_CTYPE is [%s]', lc_ctype) | |
397 | 410 | lc_ctype = lc_ctype.lower() |
398 | 411 | if lc_ctype in ['c', 'posix']: |
399 | 412 | _log.warning('while this cluster setting allows to store databases') |
401 | 414 | _log.warning('sorting etc, hence it is not recommended for use') |
402 | 415 | _log.warning('(although it will, technically, work)') |
403 | 416 | elif not (lc_ctype.endswith('.utf-8') or lc_ctype.endswith('.utf8')): |
404 | _log.error('LC_CTYPE does not end in .UTF-8 or .UTF8') | |
417 | _log.error(u'LC_CTYPE does not end in .UTF-8 or .UTF8') | |
405 | 418 | curs.execute(u"show server_encoding") |
406 | 419 | data = curs.fetchall() |
407 | 420 | srv_enc = data[0][0] |
408 | _log.info('server_encoding is [%s]', srv_enc) | |
421 | _log.info(u'server_encoding is [%s]', srv_enc) | |
409 | 422 | srv_enc = srv_enc.lower() |
410 | 423 | if not srv_enc in ['utf8', 'utf-8']: |
411 | _log.error('cluster encoding incompatible with utf8 encoded databases but') | |
412 | _log.error('for GNUmed installation the cluster must accept this encoding') | |
413 | _log.error('you may need to re-initdb or create a new cluster') | |
424 | _log.error(u'cluster encoding incompatible with utf8 encoded databases but') | |
425 | _log.error(u'for GNUmed installation the cluster must accept this encoding') | |
426 | _log.error(u'you may need to re-initdb or create a new cluster') | |
414 | 427 | return None |
415 | _log.info('server encoding seems compatible despite not being reported in LC_CTYPE') | |
428 | _log.info(u'server encoding seems compatible despite not being reported in LC_CTYPE') | |
416 | 429 | |
417 | 430 | # make sure we get english messages |
418 | 431 | curs.execute(u"set lc_messages to 'C'") |
419 | 432 | curs.close() |
420 | 433 | |
421 | _log.info("successfully connected to template database [%s]" % self.template_db) | |
434 | _log.info(u"successfully connected to template database [%s]" % self.template_db) | |
422 | 435 | return True |
423 | 436 | #-------------------------------------------------------------- |
424 | 437 | # user and group related |
425 | 438 | #-------------------------------------------------------------- |
426 | 439 | def __bootstrap_db_users(self): |
427 | _log.info("bootstrapping database users and groups") | |
440 | _log.info(u"bootstrapping database users and groups") | |
428 | 441 | |
429 | 442 | # insert standard groups |
430 | 443 | if not self.__create_groups(): |
431 | _log.error("Cannot create GNUmed standard groups.") | |
444 | _log.error(u"Cannot create GNUmed standard groups.") | |
432 | 445 | return None |
433 | 446 | |
434 | 447 | # create GNUmed owner |
435 | 448 | if self.__create_dbowner() is None: |
436 | _log.error("Cannot install GNUmed database owner.") | |
449 | _log.error(u"Cannot install GNUmed database owner.") | |
437 | 450 | return None |
438 | 451 | |
439 | 452 | # if not _import_schema(group=self.section, schema_opt='schema', conn=self.conn): |
440 | # _log.error("Cannot import schema definition for server [%s] into database [%s]." % (self.name, self.template_db)) | |
453 | # _log.error(u"Cannot import schema definition for server [%s] into database [%s]." % (self.name, self.template_db)) | |
441 | 454 | # return None |
442 | 455 | |
443 | 456 | return True |
447 | 460 | |
448 | 461 | dbowner_alias = cfg_get("GnuMed defaults", "database owner alias") |
449 | 462 | if dbowner_alias is None: |
450 | _log.error("Cannot load GNUmed database owner name from config file.") | |
463 | _log.error(u"Cannot load GNUmed database owner name from config file.") | |
451 | 464 | return None |
452 | 465 | |
453 | 466 | cursor = self.conn.cursor() |
468 | 481 | try: |
469 | 482 | cursor.execute(cmd) |
470 | 483 | except: |
471 | _log.error(">>>[%s]<<< failed." % cmd) | |
472 | _log.exception("Cannot add GNUmed database owner [%s] to groups [gm-logins] and [%s]." % (name, self.auth_group)) | |
484 | _log.error(u">>>[%s]<<< failed." % cmd) | |
485 | _log.exception(u"Cannot add GNUmed database owner [%s] to groups [gm-logins] and [%s]." % (name, self.auth_group)) | |
473 | 486 | cursor.close() |
474 | 487 | return False |
475 | 488 | self.conn.commit() |
478 | 491 | return True |
479 | 492 | |
480 | 493 | print_msg (( |
481 | """The database owner [%s] will be created. | |
494 | u"""The database owner [%s] will be created. | |
482 | 495 | |
483 | 496 | You will have to provide a new password for it |
484 | 497 | unless it is pre-defined in the configuration file. |
491 | 504 | try: |
492 | 505 | cursor.execute(cmd) |
493 | 506 | except: |
494 | _log.error(">>>[%s]<<< failed." % cmd) | |
495 | _log.exception("Cannot create GNUmed database owner [%s]." % _dbowner.name) | |
507 | _log.error(u">>>[%s]<<< failed." % cmd) | |
508 | _log.exception(u"Cannot create GNUmed database owner [%s]." % _dbowner.name) | |
496 | 509 | cursor.close() |
497 | 510 | return None |
498 | 511 | |
514 | 527 | |
515 | 528 | groups = cfg_get(section, "groups") |
516 | 529 | if groups is None: |
517 | _log.error("Cannot load GNUmed group names from config file (section [%s])." % section) | |
530 | _log.error(u"Cannot load GNUmed group names from config file (section [%s])." % section) | |
518 | 531 | groups = [self.auth_group] |
519 | 532 | else: |
520 | 533 | groups.append(self.auth_group) |
531 | 544 | #================================================================== |
532 | 545 | class database: |
533 | 546 | def __init__(self, aDB_alias): |
534 | _log.info("bootstrapping database [%s]" % aDB_alias) | |
547 | _log.info(u"bootstrapping database [%s]" % aDB_alias) | |
535 | 548 | |
536 | 549 | self.section = "database %s" % aDB_alias |
537 | 550 | |
540 | 553 | if overrider is not None: |
541 | 554 | self.name = os.getenv(overrider) |
542 | 555 | if self.name is None: |
543 | _log.info('environment variable [%s] is not set, using database name from config file' % overrider) | |
556 | _log.info(u'environment variable [%s] is not set, using database name from config file' % overrider) | |
544 | 557 | self.name = cfg_get(self.section, 'name') |
545 | 558 | else: |
546 | 559 | self.name = cfg_get(self.section, 'name') |
547 | 560 | |
548 | 561 | if self.name is None or str(self.name).strip() == '': |
549 | _log.error("Need to know database name.") | |
562 | _log.error(u"Need to know database name.") | |
550 | 563 | raise ConstructorError, "database.__init__(): Cannot bootstrap database." |
551 | 564 | |
552 | 565 | # already bootstrapped ? |
553 | 566 | global _bootstrapped_dbs |
554 | 567 | if _bootstrapped_dbs.has_key(aDB_alias): |
555 | 568 | if _bootstrapped_dbs[aDB_alias].name == self.name: |
556 | _log.info("database [%s] already bootstrapped", self.name) | |
569 | _log.info(u"database [%s] already bootstrapped", self.name) | |
557 | 570 | return None |
558 | 571 | |
559 | 572 | # no, so bootstrap from scratch |
560 | _log.info('bootstrapping database [%s] alias "%s"', self.name, aDB_alias) | |
573 | _log.info(u'bootstrapping database [%s] alias "%s"', self.name, aDB_alias) | |
561 | 574 | |
562 | 575 | for db in _bootstrapped_dbs.values(): |
563 | 576 | if db.conn.closed == 0: |
567 | 580 | |
568 | 581 | self.server_alias = cfg_get(self.section, "server alias") |
569 | 582 | if self.server_alias is None: |
570 | _log.error("Server alias missing.") | |
583 | _log.error(u"Server alias missing.") | |
571 | 584 | raise ConstructorError, "database.__init__(): Cannot bootstrap database." |
572 | 585 | |
573 | 586 | self.template_db = cfg_get(self.section, "template database") |
574 | 587 | if self.template_db is None: |
575 | _log.error("Template database name missing.") | |
588 | _log.error(u"Template database name missing.") | |
576 | 589 | raise ConstructorError, "database.__init__(): Cannot bootstrap database." |
577 | 590 | |
578 | 591 | # make sure server is bootstrapped |
595 | 608 | _dbowner = user(anAlias = cfg_get("GnuMed defaults", "database owner alias")) |
596 | 609 | |
597 | 610 | if _dbowner is None: |
598 | _log.error("Cannot load GNUmed database owner name from config file.") | |
599 | return None | |
600 | ||
601 | # get owner | |
611 | _log.error(u"Cannot load GNUmed database owner name from config file.") | |
612 | return None | |
613 | ||
602 | 614 | self.owner = _dbowner |
603 | 615 | |
604 | 616 | # connect as owner to template |
605 | 617 | if not self.__connect_superuser_to_template(): |
606 | _log.error("Cannot connect to template database.") | |
618 | _log.error(u"Cannot connect to template database.") | |
607 | 619 | return False |
608 | 620 | |
609 | 621 | # make sure db exists |
610 | 622 | if not self.__create_db(): |
611 | _log.error("Cannot create database.") | |
623 | _log.error(u"Cannot create database.") | |
612 | 624 | return False |
613 | 625 | |
614 | 626 | # reconnect as superuser to db |
615 | 627 | if not self.__connect_superuser_to_db(): |
616 | _log.error("Cannot connect to database.") | |
628 | _log.error(u"Cannot connect to database.") | |
617 | 629 | return None |
618 | 630 | |
619 | 631 | # create authentication group |
620 | _log.info('creating database-specific authentication group role') | |
632 | _log.info(u'creating database-specific authentication group role') | |
621 | 633 | curs = self.conn.cursor() |
622 | 634 | if not create_db_group(cursor = curs, group = self.name): |
623 | 635 | curs.close() |
624 | _log.error('cannot create authentication group role') | |
636 | _log.error(u'cannot create authentication group role') | |
625 | 637 | return False |
626 | 638 | self.conn.commit() |
627 | 639 | curs.close() |
630 | 642 | curs = self.conn.cursor() |
631 | 643 | if not db_group_exists(cursor = curs, group = self.name): |
632 | 644 | curs.close() |
633 | _log.error('cannot find authentication group role') | |
645 | _log.error(u'cannot find authentication group role') | |
634 | 646 | return False |
635 | 647 | curs.close() |
636 | 648 | |
637 | 649 | # reindex db so upgrade doesn't fail on broken index |
638 | 650 | if not self.reindex_all(): |
639 | _log.error('cannot REINDEX cloned target database') | |
651 | _log.error(u'cannot REINDEX cloned target database') | |
640 | 652 | return False |
641 | 653 | |
642 | 654 | tmp = cfg_get(self.section, 'superuser schema') |
643 | 655 | if tmp is not None: |
644 | 656 | if not _import_schema(group=self.section, schema_opt='superuser schema', conn=self.conn): |
645 | _log.error("cannot import schema definition for database [%s]" % (self.name)) | |
657 | _log.error(u"cannot import schema definition for database [%s]" % (self.name)) | |
646 | 658 | return False |
647 | 659 | del tmp |
648 | 660 | |
649 | 661 | # transfer users |
650 | 662 | if not self.transfer_users(): |
651 | _log.error("Cannot transfer users from old to new database.") | |
663 | _log.error(u"Cannot transfer users from old to new database.") | |
652 | 664 | return False |
653 | 665 | |
654 | 666 | # reconnect as owner to db |
655 | 667 | if not self.__connect_owner_to_db(): |
656 | _log.error("Cannot connect to database.") | |
668 | _log.error(u"Cannot connect to database.") | |
657 | 669 | return None |
658 | 670 | if not _import_schema(group=self.section, schema_opt='schema', conn=self.conn): |
659 | _log.error("cannot import schema definition for database [%s]" % (self.name)) | |
671 | _log.error(u"cannot import schema definition for database [%s]" % (self.name)) | |
660 | 672 | return None |
661 | 673 | |
662 | 674 | # don't close this here, the connection will |
710 | 722 | # we need English messages to detect errors |
711 | 723 | curs.execute(u"set lc_messages to 'C'") |
712 | 724 | curs.execute(u"alter database %s set lc_messages to 'C'" % self.name) |
713 | # we need inheritance or else things will fail miserably | |
714 | curs.execute("alter database %s set sql_inheritance to on" % self.name) | |
715 | 725 | # we want READ ONLY default transactions for maximum patient data safety |
716 | 726 | curs.execute("alter database %s set default_transaction_read_only to on" % self.name) |
717 | 727 | # we want checking of function bodies |
718 | 728 | curs.execute("alter database %s set check_function_bodies to on" % self.name) |
729 | # we want checking of data checksums if available | |
730 | curs.execute("alter database %s set ignore_checksum_failure to off" % self.name) | |
719 | 731 | curs.close() |
720 | 732 | self.conn.commit() |
721 | 733 | |
722 | # we want checking of data checksums if available | |
723 | # remove exception handler when 9.3 is default | |
734 | # we need inheritance or else things will fail miserably | |
724 | 735 | curs = self.conn.cursor() |
725 | 736 | try: |
726 | curs.execute("alter database %s set ignore_checksum_failure to off" % self.name) | |
737 | curs.execute("alter database %s set sql_inheritance to DEFAULT" % self.name) | |
727 | 738 | except: |
728 | _log.exception('PostgreSQL version < 9.3 does not support <ignore_checksum_failure>') | |
739 | _log.exception(u'PG 10 hardwired for sql_inheritance') | |
729 | 740 | curs.close() |
741 | self.conn.commit() | |
730 | 742 | |
731 | 743 | # we want to track commit timestamps if available |
732 | 744 | # remove exception handler when 9.5 is default |
734 | 746 | try: |
735 | 747 | curs.execute("alter database %s set track_commit_timestamp to on" % self.name) |
736 | 748 | except: |
737 | _log.exception('PostgreSQL version < 9.5 does not support <track_commit_timestamp> OR <track_commit_timestamp> cannot be set at runtime') | |
749 | _log.exception(u'PostgreSQL version < 9.5 does not support <track_commit_timestamp> OR <track_commit_timestamp> cannot be set at runtime') | |
738 | 750 | curs.close() |
739 | ||
740 | 751 | self.conn.commit() |
741 | 752 | |
742 | 753 | curs = self.conn.cursor() |
748 | 759 | #-------------------------------------------------------------- |
749 | 760 | def __connect_owner_to_db(self): |
750 | 761 | |
762 | _log.debug(u'__connect_owner_to_db') | |
763 | ||
751 | 764 | # reconnect as superuser to db |
752 | 765 | if not self.__connect_superuser_to_db(): |
753 | _log.error("Cannot connect to database.") | |
766 | _log.error(u"Cannot connect to database.") | |
754 | 767 | return False |
755 | 768 | |
756 | 769 | self.conn.cookie = 'database.__connect_owner_to_db via database.__connect_superuser_to_db' |
770 | ||
771 | _log.debug(u'setting session authorization to user %s', self.owner.name) | |
757 | 772 | |
758 | 773 | curs = self.conn.cursor() |
759 | 774 | cmd = "set session authorization %(usr)s" |
770 | 785 | try: |
771 | 786 | aCursor.execute(cmd) |
772 | 787 | except: |
773 | _log.exception(">>>[%s]<<< failed." % cmd) | |
788 | _log.exception(u">>>[%s]<<< failed." % cmd) | |
774 | 789 | return None |
775 | 790 | |
776 | 791 | res = aCursor.fetchall() |
777 | 792 | tmp = aCursor.rowcount |
778 | 793 | aCursor.close() |
779 | 794 | if tmp == 1: |
780 | _log.info("Database [%s] exists." % self.name) | |
795 | _log.info(u"Database [%s] exists." % self.name) | |
781 | 796 | return True |
782 | 797 | |
783 | _log.info("Database [%s] does not exist." % self.name) | |
798 | _log.info(u"Database [%s] does not exist." % self.name) | |
784 | 799 | return None |
785 | 800 | #-------------------------------------------------------------- |
786 | 801 | def __create_db(self): |
792 | 807 | else: |
793 | 808 | converted, version = gmTools.input2int(template_version.lstrip('v'), 0) |
794 | 809 | if not converted: |
795 | _log.error('invalid template database definition: %s', template_version) | |
810 | _log.error(u'invalid template database definition: %s', template_version) | |
796 | 811 | return False |
797 | 812 | if not gmPG2.database_schema_compatible(link_obj = self.conn, version = version): |
798 | _log.error('invalid [%s] schema structure in GNUmed template database [%s]', template_version, self.template_db) | |
813 | _log.error(u'invalid [%s] schema structure in GNUmed template database [%s]', template_version, self.template_db) | |
799 | 814 | return False |
800 | 815 | |
801 | 816 | # check for target database |
803 | 818 | drop_existing = bool(int(cfg_get(self.section, 'drop target database'))) |
804 | 819 | if drop_existing: |
805 | 820 | print_msg("==> dropping pre-existing target database [%s] ..." % self.name) |
806 | _log.info('trying to drop target database') | |
821 | _log.info(u'trying to drop target database') | |
807 | 822 | cmd = 'DROP DATABASE "%s"' % self.name |
808 | _log.debug('committing existing connection before setting autocommit') | |
823 | _log.debug(u'committing existing connection before setting autocommit') | |
809 | 824 | self.conn.commit() |
810 | _log.debug('setting autocommit to TRUE') | |
825 | _log.debug(u'setting autocommit to TRUE') | |
811 | 826 | self.conn.autocommit = True |
812 | 827 | self.conn.readonly = False |
813 | 828 | cursor = self.conn.cursor() |
814 | 829 | try: |
815 | 830 | cursor.execute(u'SET default_transaction_read_only TO OFF') |
816 | _log.debug('running SQL: %s', cmd) | |
831 | _log.debug(u'running SQL: %s', cmd) | |
817 | 832 | cursor.execute(cmd) |
818 | 833 | except: |
819 | _log.exception(">>>[%s]<<< failed" % cmd) | |
834 | _log.exception(u">>>[%s]<<< failed" % cmd) | |
820 | 835 | _log.debug(u'conn state after failed DROP: %s', gmPG2.capture_conn_state(self.conn)) |
821 | 836 | return False |
822 | 837 | finally: |
827 | 842 | if use_existing: |
828 | 843 | # FIXME: verify that database is owned by "gm-dbo" |
829 | 844 | print_msg("==> using pre-existing target database [%s] ..." % self.name) |
830 | _log.info('using existing database [%s]', self.name) | |
845 | _log.info(u'using existing database [%s]', self.name) | |
831 | 846 | return True |
832 | 847 | else: |
833 | _log.info('not using existing database [%s]', self.name) | |
848 | _log.info(u'not using existing database [%s]', self.name) | |
834 | 849 | return False |
835 | 850 | |
836 | 851 | tablespace = cfg_get(self.section, 'tablespace') |
868 | 883 | cursor.execute(u'SET default_transaction_read_only TO OFF') |
869 | 884 | cursor.execute(create_db_cmd) |
870 | 885 | except: |
871 | _log.exception(">>>[%s]<<< failed" % create_db_cmd) | |
886 | _log.exception(u">>>[%s]<<< failed" % create_db_cmd) | |
872 | 887 | return False |
873 | 888 | finally: |
874 | 889 | cursor.close() |
876 | 891 | |
877 | 892 | if not self.__db_exists(): |
878 | 893 | return None |
879 | _log.info("Successfully created GNUmed database [%s]." % self.name) | |
894 | _log.info(u"Successfully created GNUmed database [%s]." % self.name) | |
880 | 895 | |
881 | 896 | return True |
882 | 897 | |
893 | 908 | |
894 | 909 | no_of_queries, remainder = divmod(len(plausibility_queries), 2) |
895 | 910 | if remainder != 0: |
896 | _log.error('odd number of plausibility queries defined, aborting') | |
911 | _log.error(u'odd number of plausibility queries defined, aborting') | |
897 | 912 | print_msg(" ... failed (configuration error)") |
898 | 913 | return False |
899 | 914 | |
920 | 935 | for idx in range(no_of_queries): |
921 | 936 | check_def = plausibility_queries[idx*2] |
922 | 937 | if check_def.startswith('--'): |
923 | _log.debug('skipped: %s', check_def) | |
938 | _log.debug(u'skipped: %s', check_def) | |
924 | 939 | continue |
925 | 940 | |
926 | 941 | tag = u'?' |
975 | 990 | target_conn.close() |
976 | 991 | |
977 | 992 | return all_tests_successful |
993 | ||
978 | 994 | #-------------------------------------------------------------- |
979 | 995 | def check_holy_auth_line(self): |
980 | 996 | |
988 | 1004 | self.server.superuser.name, |
989 | 1005 | self.server.superuser.password |
990 | 1006 | ) |
991 | conn.cookie = 'holy auth check connection' | |
1007 | conn.cookie = u'holy auth check connection' | |
992 | 1008 | |
993 | 1009 | cmd = u"select setting from pg_settings where name = 'hba_file'" |
994 | 1010 | rows, idx = gmPG2.run_ro_queries(link_obj = conn, queries = [{'cmd': cmd}]) |
995 | 1011 | conn.close() |
996 | 1012 | if len(rows) == 0: |
997 | _log.info('cannot check pg_hba.conf for authentication information - not detectable in pg_settings') | |
1013 | _log.info(u'cannot check pg_hba.conf for authentication information - not detectable in pg_settings') | |
998 | 1014 | return |
999 | 1015 | |
1000 | 1016 | hba_file = rows[0][0] |
1001 | _log.info('hba file: %s', hba_file) | |
1017 | _log.info(u'hba file: %s', hba_file) | |
1002 | 1018 | |
1003 | 1019 | try: |
1004 | 1020 | f = io.open(hba_file, mode = 'rt').close() |
1005 | 1021 | except Exception: |
1006 | _log.exception('cannot check pg_hba.conf for authentication information - not readable') | |
1022 | _log.exception(u'cannot check pg_hba.conf for authentication information - not readable') | |
1007 | 1023 | return |
1008 | 1024 | |
1009 | 1025 | found_holy_line = False |
1010 | 1026 | for line in fileinput.input(hba_file): |
1011 | 1027 | if regex.match(holy_pattern, line) is not None: |
1012 | 1028 | found_holy_line = True |
1013 | _log.info('found standard GNUmed authentication directive in pg_hba.conf') | |
1014 | _log.info('[%s]', line) | |
1015 | _log.info('it may still be in the wrong place, though, so double-check if clients cannot connect') | |
1029 | _log.info(u'found standard GNUmed authentication directive in pg_hba.conf') | |
1030 | _log.info(u'[%s]', line) | |
1031 | _log.info(u'it may still be in the wrong place, though, so double-check if clients cannot connect') | |
1016 | 1032 | break |
1017 | 1033 | |
1018 | 1034 | if not found_holy_line: |
1019 | _log.info('did not find active standard GNUmed authentication directive in pg_hba.conf') | |
1020 | _log.info('regex: %s' % holy_pattern) | |
1035 | _log.info(u'did not find active standard GNUmed authentication directive in pg_hba.conf') | |
1036 | _log.info(u'regex: %s' % holy_pattern) | |
1021 | 1037 | |
1022 | 1038 | found_holy_line_inactive = False |
1023 | 1039 | for line in fileinput.input(hba_file): |
1024 | 1040 | if regex.match(holy_pattern_inactive, line) is not None: |
1025 | 1041 | found_holy_line_inactive = True |
1026 | _log.info('found inactive standard GNUmed authentication directive in pg_hba.conf') | |
1027 | _log.info('[%s]', line) | |
1028 | _log.info('it may still be in the wrong place, though, so double-check if clients cannot connect') | |
1042 | _log.info(u'found inactive standard GNUmed authentication directive in pg_hba.conf') | |
1043 | _log.info(u'[%s]', line) | |
1044 | _log.info(u'it may still be in the wrong place, though, so double-check if clients cannot connect') | |
1029 | 1045 | break |
1030 | 1046 | if not found_holy_line_inactive: |
1031 | _log.info('did not find inactive standard GNUmed authentication directive in pg_hba.conf either') | |
1032 | _log.info('regex: %s' % holy_pattern_inactive) | |
1033 | ||
1034 | _log.info('bootstrapping is likely to have succeeded but clients probably cannot connect yet') | |
1047 | _log.info(u'did not find inactive standard GNUmed authentication directive in pg_hba.conf either') | |
1048 | _log.info(u'regex: %s' % holy_pattern_inactive) | |
1049 | ||
1050 | _log.info(u'bootstrapping is likely to have succeeded but clients probably cannot connect yet') | |
1035 | 1051 | print_msg('==> sanity checking PostgreSQL authentication settings ...') |
1036 | 1052 | print_msg('') |
1037 | 1053 | print_msg('Note that even after successfully bootstrapping the GNUmed ') |
1059 | 1075 | |
1060 | 1076 | import_scripts = cfg_get(self.section, "data import scripts") |
1061 | 1077 | if (import_scripts is None) or (len(import_scripts) == 0): |
1062 | _log.info('skipped data import: no scripts to run') | |
1078 | _log.info(u'skipped data import: no scripts to run') | |
1063 | 1079 | print_msg(" ... skipped (no scripts to run)") |
1064 | 1080 | return True |
1065 | 1081 | |
1074 | 1090 | script = gmTools.import_module_from_directory(module_path = script_base_dir, module_name = import_script, always_remove_path = True) |
1075 | 1091 | except ImportError: |
1076 | 1092 | print_msg(" ... failed (cannot load script [%s])" % import_script) |
1077 | _log.error('cannot load data set import script [%s/%s]' % (script_base_dir, import_script)) | |
1093 | _log.error(u'cannot load data set import script [%s/%s]' % (script_base_dir, import_script)) | |
1078 | 1094 | return False |
1079 | 1095 | |
1080 | 1096 | try: |
1081 | 1097 | script.run(conn = self.conn) |
1082 | 1098 | except: |
1083 | 1099 | print_msg(" ... failed (cannot run script [%s])" % import_script) |
1084 | _log.exception('cannot run import script [%s]' % import_script) | |
1100 | _log.exception(u'cannot run import script [%s]' % import_script) | |
1085 | 1101 | return False |
1086 | 1102 | |
1087 | 1103 | if import_script.endswith('.py'): |
1092 | 1108 | del script |
1093 | 1109 | gc.collect() |
1094 | 1110 | except: |
1095 | _log.exception('cannot remove data import script module [%s], hoping for the best', import_script) | |
1111 | _log.exception(u'cannot remove data import script module [%s], hoping for the best', import_script) | |
1096 | 1112 | |
1097 | 1113 | return True |
1098 | 1114 | |
1104 | 1120 | target_version = cfg_get(self.section, 'target version') |
1105 | 1121 | if target_version == 'devel': |
1106 | 1122 | print_msg(" ... skipped (devel version)") |
1107 | _log.info('result schema hash: %s', gmPG2.get_schema_hash(link_obj = self.conn)) | |
1123 | _log.info(u'result schema hash: %s', gmPG2.get_schema_hash(link_obj = self.conn)) | |
1108 | 1124 | _log.warning('testing/development only, not failing due to invalid target database identity hash') |
1109 | 1125 | return True |
1110 | 1126 | converted, version = gmTools.input2int(target_version.lstrip('v'), 2) |
1111 | 1127 | if not converted: |
1112 | _log.error('cannot convert target database version: %s', target_version) | |
1128 | _log.error(u'cannot convert target database version: %s', target_version) | |
1113 | 1129 | print_msg(" ... failed (invalid target version specification)") |
1114 | 1130 | return False |
1115 | 1131 | if gmPG2.database_schema_compatible(link_obj = self.conn, version = version): |
1116 | _log.info('database identity hash properly verified') | |
1132 | _log.info(u'database identity hash properly verified') | |
1117 | 1133 | return True |
1118 | _log.error('target database identity hash invalid') | |
1134 | _log.error(u'target database identity hash invalid') | |
1119 | 1135 | print_msg(" ... failed (hash mismatch)") |
1120 | 1136 | return False |
1121 | 1137 | |
1134 | 1150 | print_msg(" ... skipped") |
1135 | 1151 | return True |
1136 | 1152 | |
1137 | _log.info('REINDEXing cloned target database so upgrade does not fail in case of a broken index') | |
1138 | _log.info('this may potentially take "quite a long time" depending on how much data there is in the database') | |
1139 | _log.info('you may want to monitor the PostgreSQL log for signs of progress') | |
1153 | _log.info(u'REINDEXing cloned target database so upgrade does not fail in case of a broken index') | |
1154 | _log.info(u'this may potentially take "quite a long time" depending on how much data there is in the database') | |
1155 | _log.info(u'you may want to monitor the PostgreSQL log for signs of progress') | |
1140 | 1156 | |
1141 | 1157 | self.conn.commit() |
1142 | 1158 | self.conn.set_session(readonly = False, autocommit = True) |
1146 | 1162 | try: |
1147 | 1163 | curs_outer.execute(cmd) |
1148 | 1164 | except: |
1149 | _log.exception(">>>[%s]<<< failed" % cmd) | |
1165 | _log.exception(u">>>[%s]<<< failed" % cmd) | |
1150 | 1166 | # re-attempt w/o VERBOSE |
1151 | _log.info('attempting REINDEXing without VERBOSE') | |
1167 | _log.info(u'attempting REINDEXing without VERBOSE') | |
1152 | 1168 | curs_inner = self.conn.cursor() |
1153 | 1169 | cmd = 'REINDEX DATABASE %s' % self.name |
1154 | 1170 | try: |
1155 | 1171 | curs_inner.execute(cmd) |
1156 | 1172 | except: |
1157 | _log.exception(">>>[%s]<<< failed" % cmd) | |
1173 | _log.exception(u">>>[%s]<<< failed" % cmd) | |
1158 | 1174 | return False |
1159 | 1175 | finally: |
1160 | 1176 | curs_inner.close() |
1170 | 1186 | print_msg("==> transferring users ...") |
1171 | 1187 | do_user_transfer = cfg_get(self.section, 'transfer users') |
1172 | 1188 | if do_user_transfer is None: |
1173 | _log.info('user transfer not defined') | |
1189 | _log.info(u'user transfer not defined') | |
1174 | 1190 | print_msg(" ... skipped (unconfigured)") |
1175 | 1191 | return True |
1176 | 1192 | do_user_transfer = int(do_user_transfer) |
1177 | 1193 | if not do_user_transfer: |
1178 | _log.info('configured to not transfer users') | |
1194 | _log.info(u'configured to not transfer users') | |
1179 | 1195 | print_msg(" ... skipped (disabled)") |
1180 | 1196 | return True |
1181 | 1197 | |
1184 | 1200 | rows, idx = gmPG2.run_rw_queries(link_obj = self.conn, queries = [{'cmd': cmd}], end_tx = True, return_data = True) |
1185 | 1201 | except gmPG2.dbapi.ProgrammingError: |
1186 | 1202 | # maybe an old database |
1187 | _log.info('problem running gm.transfer_users(), trying gm_transfer_users()') | |
1203 | _log.info(u'problem running gm.transfer_users(), trying gm_transfer_users()') | |
1188 | 1204 | cmd = u"select gm_transfer_users('%s'::text)" % self.template_db |
1189 | 1205 | rows, idx = gmPG2.run_rw_queries(link_obj = self.conn, queries = [{'cmd': cmd}], end_tx = True, return_data = True) |
1190 | 1206 | |
1191 | 1207 | if rows[0][0]: |
1192 | _log.info('users properly transferred from [%s] to [%s]' % (self.template_db, self.name)) | |
1208 | _log.info(u'users properly transferred from [%s] to [%s]' % (self.template_db, self.name)) | |
1193 | 1209 | return True |
1194 | _log.error('error transferring user from [%s] to [%s]' % (self.template_db, self.name)) | |
1210 | _log.error(u'error transferring user from [%s] to [%s]' % (self.template_db, self.name)) | |
1195 | 1211 | print_msg(" ... failed") |
1196 | 1212 | return False |
1197 | 1213 | |
1227 | 1243 | audit_schema = gmAuditSchemaGenerator.create_audit_ddl(curs) |
1228 | 1244 | curs.close() |
1229 | 1245 | if audit_schema is None: |
1230 | _log.error('cannot generate audit trail schema for GNUmed database [%s]' % self.name) | |
1246 | _log.error(u'cannot generate audit trail schema for GNUmed database [%s]' % self.name) | |
1231 | 1247 | return None |
1232 | 1248 | # write schema to file |
1233 | 1249 | tmpfile = os.path.join(tempfile.gettempdir(), 'audit-trail-schema.sql') |
1239 | 1255 | # import auditing schema |
1240 | 1256 | psql = gmPsql.Psql(self.conn) |
1241 | 1257 | if psql.run(tmpfile) != 0: |
1242 | _log.error("cannot import audit schema definition for database [%s]" % (self.name)) | |
1258 | _log.error(u"cannot import audit schema definition for database [%s]" % (self.name)) | |
1243 | 1259 | return None |
1244 | 1260 | |
1245 | 1261 | if _keep_temp_files: |
1248 | 1264 | try: |
1249 | 1265 | os.remove(tmpfile) |
1250 | 1266 | except Exception: |
1251 | _log.exception('cannot remove audit trail schema file [%s]' % tmpfile) | |
1267 | _log.exception(u'cannot remove audit trail schema file [%s]' % tmpfile) | |
1252 | 1268 | return True |
1253 | 1269 | |
1254 | 1270 | #-------------------------------------------------------------- |
1257 | 1273 | # setup clin.clin_root_item child tables FK's |
1258 | 1274 | print_msg("==> setting up encounter/episode FKs and IDXs ...") |
1259 | 1275 | child_tables = gmPG2.get_child_tables(link_obj = self.conn, schema = 'clin', table = 'clin_root_item') |
1260 | _log.info('clin.clin_root_item child tables:') | |
1276 | _log.info(u'clin.clin_root_item child tables:') | |
1261 | 1277 | for child in child_tables: |
1262 | _log.info('%s.%s', child['namespace'], child['table']) | |
1278 | _log.info(u'%s.%s', child['namespace'], child['table']) | |
1263 | 1279 | for child in child_tables: |
1264 | 1280 | # .fk_episode |
1265 | 1281 | FKs = gmPG2.get_foreign_key_names ( |
1272 | 1288 | target_column = 'pk', |
1273 | 1289 | ) |
1274 | 1290 | if len(FKs) > 0: |
1275 | _log.info('%s FK(s) exist:', len(FKs)) | |
1291 | _log.info(u'%s FK(s) exist:', len(FKs)) | |
1276 | 1292 | for idx in range(len(FKs)): |
1277 | 1293 | FK = FKs[idx] |
1278 | 1294 | _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']) |
1279 | 1295 | else: |
1280 | _log.info('adding FK: %s.%s.fk_episode -> clin.episode.pk', child['namespace'], child['table']) | |
1296 | _log.info(u'adding FK: %s.%s.fk_episode -> clin.episode.pk', child['namespace'], child['table']) | |
1281 | 1297 | cmd = SQL_add_foreign_key % { |
1282 | 1298 | 'src_schema': child['namespace'], |
1283 | 1299 | 'src_tbl': child['table'], |
1315 | 1331 | target_column = 'pk' |
1316 | 1332 | ) |
1317 | 1333 | if len(FKs) > 0: |
1318 | _log.info('%s FK(s) exist:', len(FKs)) | |
1334 | _log.info(u'%s FK(s) exist:', len(FKs)) | |
1319 | 1335 | for idx in range(len(FKs)): |
1320 | 1336 | FK = FKs[idx] |
1321 | 1337 | _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']) |
1322 | 1338 | else: |
1323 | _log.info('adding FK: %s.%s.fk_encounter -> clin.encounter.pk', child['namespace'], child['table']) | |
1339 | _log.info(u'adding FK: %s.%s.fk_encounter -> clin.encounter.pk', child['namespace'], child['table']) | |
1324 | 1340 | cmd = SQL_add_foreign_key % { |
1325 | 1341 | 'src_schema': child['namespace'], |
1326 | 1342 | 'src_tbl': child['table'], |
1352 | 1368 | # re-create fk_encounter/fk_episode sanity check triggers on all tables |
1353 | 1369 | if gmPG2.function_exists(link_obj = curs, schema = u'gm', function = u'create_all_enc_epi_sanity_check_triggers'): |
1354 | 1370 | print_msg("==> setting up encounter/episode FK sanity check triggers ...") |
1355 | _log.debug('attempting to set up sanity check triggers on all tables linking to encounter AND episode') | |
1371 | _log.debug(u'attempting to set up sanity check triggers on all tables linking to encounter AND episode') | |
1356 | 1372 | cmd = u'select gm.create_all_enc_epi_sanity_check_triggers()' |
1357 | 1373 | curs.execute(cmd) |
1358 | 1374 | result = curs.fetchone() |
1359 | 1375 | if result[0] is False: |
1360 | _log.error('error creating sanity check triggers on all tables linking to clin.encounter AND clin.episode') | |
1376 | _log.error(u'error creating sanity check triggers on all tables linking to clin.encounter AND clin.episode') | |
1361 | 1377 | curs.close() |
1362 | 1378 | return None |
1363 | 1379 | |
1364 | 1380 | # always re-create generic super signal (if exists) |
1365 | 1381 | if gmPG2.function_exists(link_obj = curs, schema = u'gm', function = u'create_all_table_mod_triggers'): |
1366 | 1382 | print_msg("==> setting up generic notifications ...") |
1367 | _log.debug('attempting to create generic modification announcement triggers on all registered tables') | |
1383 | _log.debug(u'attempting to create generic modification announcement triggers on all registered tables') | |
1368 | 1384 | |
1369 | 1385 | cmd = u"SELECT gm.create_all_table_mod_triggers(True::boolean)" |
1370 | 1386 | curs.execute(cmd) |
1371 | 1387 | result = curs.fetchone() |
1372 | 1388 | curs.close() |
1373 | 1389 | if result[0] is False: |
1374 | _log.error('cannot create generic modification announcement triggers on all tables') | |
1390 | _log.error(u'cannot create generic modification announcement triggers on all tables') | |
1375 | 1391 | return None |
1376 | 1392 | |
1377 | 1393 | self.conn.commit() |
1388 | 1404 | self.section = "bundle %s" % aBundleAlias |
1389 | 1405 | #-------------------------------------------------------------- |
1390 | 1406 | def bootstrap(self): |
1391 | _log.info("bootstrapping bundle [%s]" % self.alias) | |
1407 | _log.info(u"bootstrapping bundle [%s]" % self.alias) | |
1392 | 1408 | |
1393 | 1409 | # load bundle definition |
1394 | 1410 | database_alias = cfg_get(self.section, "database alias") |
1395 | 1411 | if database_alias is None: |
1396 | _log.error("Need to know database name to install bundle [%s]." % self.alias) | |
1412 | _log.error(u"Need to know database name to install bundle [%s]." % self.alias) | |
1397 | 1413 | return None |
1398 | 1414 | # bootstrap database |
1399 | 1415 | try: |
1405 | 1421 | |
1406 | 1422 | # check PostgreSQL version |
1407 | 1423 | if not self.__verify_pg_version(): |
1408 | _log.error("Wrong PostgreSQL version.") | |
1424 | _log.error(u"Wrong PostgreSQL version.") | |
1409 | 1425 | return None |
1410 | 1426 | |
1411 | 1427 | # import schema |
1412 | 1428 | if not _import_schema(group=self.section, schema_opt='schema', conn=self.db.conn): |
1413 | _log.error("Cannot import schema definition for bundle [%s] into database [%s]." % (self.alias, database_alias)) | |
1429 | _log.error(u"Cannot import schema definition for bundle [%s] into database [%s]." % (self.alias, database_alias)) | |
1414 | 1430 | return None |
1415 | 1431 | |
1416 | 1432 | return True |
1420 | 1436 | |
1421 | 1437 | required_version = cfg_get(self.section, "minimum postgresql version") |
1422 | 1438 | if required_version is None: |
1423 | _log.error("Cannot load minimum required PostgreSQL version from config file.") | |
1424 | return None | |
1425 | ||
1426 | _log.info("minimum required PostgreSQL version: %s" % required_version) | |
1439 | _log.error(u"Cannot load minimum required PostgreSQL version from config file.") | |
1440 | return None | |
1441 | ||
1442 | _log.info(u"minimum required PostgreSQL version: %s" % required_version) | |
1427 | 1443 | |
1428 | 1444 | converted, pg_ver = gmTools.input2decimal(gmPG2.postgresql_version) |
1429 | 1445 | if not converted: |
1430 | _log.error('error checking PostgreSQL version') | |
1446 | _log.error(u'error checking PostgreSQL version') | |
1431 | 1447 | return None |
1432 | 1448 | converted, req_version = gmTools.input2decimal(required_version) |
1433 | 1449 | if not converted: |
1434 | _log.error('error checking PostgreSQL version') | |
1435 | _log.error('required: %s', required_version) | |
1450 | _log.error(u'error checking PostgreSQL version') | |
1451 | _log.error(u'required: %s', required_version) | |
1436 | 1452 | return None |
1437 | 1453 | if pg_ver < req_version: |
1438 | _log.error("Reported live PostgreSQL version [%s] is smaller than the required minimum version [%s]." % (gmPG2.postgresql_version, required_version)) | |
1439 | return None | |
1440 | ||
1441 | _log.info("installed PostgreSQL version: %s - this is fine with me" % gmPG2.postgresql_version) | |
1454 | _log.error(u"Reported live PostgreSQL version [%s] is smaller than the required minimum version [%s]." % (gmPG2.postgresql_version, required_version)) | |
1455 | return None | |
1456 | ||
1457 | _log.info(u"installed PostgreSQL version: %s - this is fine with me" % gmPG2.postgresql_version) | |
1442 | 1458 | return True |
1443 | 1459 | #================================================================== |
1444 | 1460 | def bootstrap_bundles(): |
1483 | 1499 | try: |
1484 | 1500 | aCurs.execute(aQuery) |
1485 | 1501 | except: |
1486 | _log.exception(">>>%s<<< failed" % aQuery) | |
1502 | _log.exception(u">>>%s<<< failed" % aQuery) | |
1487 | 1503 | return False |
1488 | 1504 | else: |
1489 | 1505 | try: |
1490 | 1506 | aCurs.execute(aQuery, args) |
1491 | 1507 | except: |
1492 | _log.exception(">>>%s<<< failed" % aQuery) | |
1508 | _log.exception(u">>>%s<<< failed" % aQuery) | |
1493 | 1509 | _log.error(str(args)) |
1494 | 1510 | return False |
1495 | 1511 | return True |
1512 | ||
1496 | 1513 | #------------------------------------------------------------------ |
1497 | 1514 | def ask_for_confirmation(): |
1498 | 1515 | bundles = cfg_get("installation", "bundles") |
1500 | 1517 | return True |
1501 | 1518 | if len(bundles) == 0: |
1502 | 1519 | return True |
1520 | ||
1503 | 1521 | if not _interactive: |
1504 | 1522 | print_msg("You are about to install the following parts of GNUmed:") |
1505 | 1523 | print_msg("-------------------------------------------------------") |
1514 | 1532 | if desc is not None: |
1515 | 1533 | for line in desc: |
1516 | 1534 | print_msg(line) |
1517 | else: | |
1518 | print "You are about to install the following parts of GNUmed:" | |
1519 | print "-------------------------------------------------------" | |
1520 | for bundle in bundles: | |
1521 | db_alias = cfg_get("bundle %s" % bundle, "database alias") | |
1522 | db_name = cfg_get("database %s" % db_alias, "name") | |
1523 | srv_alias = cfg_get("database %s" % db_alias, "server alias") | |
1524 | srv_name = cfg_get("server %s" % srv_alias, "name") | |
1525 | print 'bundle "%s" in <%s> (or overridden) on <%s>' % (bundle, db_name, srv_name) | |
1526 | print "-------------------------------------------------------" | |
1527 | desc = cfg_get("installation", "description") | |
1528 | if desc is not None: | |
1529 | for line in desc: | |
1530 | print line | |
1531 | ||
1532 | print "Do you really want to install this database setup ?" | |
1533 | answer = raw_input("Type yes or no: ") | |
1534 | if answer == "yes": | |
1535 | return True | |
1536 | else: | |
1537 | return None | |
1538 | return True | |
1535 | return True | |
1536 | ||
1537 | print "You are about to install the following parts of GNUmed:" | |
1538 | print "-------------------------------------------------------" | |
1539 | for bundle in bundles: | |
1540 | db_alias = cfg_get("bundle %s" % bundle, "database alias") | |
1541 | db_name = cfg_get("database %s" % db_alias, "name") | |
1542 | srv_alias = cfg_get("database %s" % db_alias, "server alias") | |
1543 | srv_name = cfg_get("server %s" % srv_alias, "name") | |
1544 | print 'bundle "%s" in <%s> (or overridden) on <%s>' % (bundle, db_name, srv_name) | |
1545 | print "-------------------------------------------------------" | |
1546 | desc = cfg_get("installation", "description") | |
1547 | if desc is not None: | |
1548 | for line in desc: | |
1549 | print line | |
1550 | ||
1551 | print "Do you really want to install this database setup ?" | |
1552 | answer = raw_input("Type yes or no: ") | |
1553 | if answer == "yes": | |
1554 | return True | |
1555 | return None | |
1539 | 1556 | |
1540 | 1557 | #-------------------------------------------------------------- |
1541 | 1558 | def _import_schema (group=None, schema_opt="schema", conn=None): |
1542 | 1559 | # load schema |
1543 | 1560 | schema_files = cfg_get(group, schema_opt) |
1544 | 1561 | if schema_files is None: |
1545 | _log.error("Need to know schema definition to install it.") | |
1562 | _log.error(u"Need to know schema definition to install it.") | |
1546 | 1563 | return None |
1547 | 1564 | |
1548 | 1565 | schema_base_dir = cfg_get(group, "schema base directory") |
1568 | 1585 | continue |
1569 | 1586 | full_path = os.path.join(schema_base_dir, filename) |
1570 | 1587 | if psql.run(full_path) == 0: |
1571 | #_log.info('success') | |
1588 | #_log.info(u'success') | |
1572 | 1589 | continue |
1573 | 1590 | _log.error(u'failure') |
1574 | 1591 | return None |
1585 | 1602 | print ' ', gmLog2._logfile_name |
1586 | 1603 | print '' |
1587 | 1604 | |
1588 | _log.error(aMsg) | |
1589 | _log.info("shutdown") | |
1605 | _log.error(unicode(aMsg, errors = 'replace')) | |
1606 | _log.info(u'shutdown') | |
1590 | 1607 | sys.exit(1) |
1608 | ||
1591 | 1609 | #------------------------------------------------------------------ |
1592 | 1610 | def print_msg(msg=None): |
1593 | 1611 | if quiet: |
1594 | 1612 | return |
1595 | 1613 | print msg |
1614 | ||
1596 | 1615 | #----------------------------------------------------------------- |
1597 | 1616 | def become_pg_demon_user(): |
1598 | 1617 | """Become "postgres" user. |
1614 | 1633 | |
1615 | 1634 | try: |
1616 | 1635 | running_as = pwd.getpwuid(os.getuid())[0] |
1617 | _log.info('running as user [%s]' % running_as) | |
1636 | _log.info(u'running as user [%s]' % running_as) | |
1618 | 1637 | except: |
1619 | 1638 | running_as = None |
1620 | 1639 | |
1634 | 1653 | return None |
1635 | 1654 | |
1636 | 1655 | if os.getuid() == 0: # we are the super-user |
1637 | _log.info('switching to UNIX user [%s]' % pg_demon_user_passwd_line[0]) | |
1656 | _log.info(u'switching to UNIX user [%s]' % pg_demon_user_passwd_line[0]) | |
1638 | 1657 | os.setuid(pg_demon_user_passwd_line[2]) |
1639 | 1658 | gmPG2.log_auth_environment() |
1640 | 1659 | |
1641 | 1660 | elif running_as == pg_demon_user_passwd_line[0]: # we are the postgres user already |
1642 | _log.info('I already am the UNIX user [%s]' % pg_demon_user_passwd_line[0]) | |
1661 | _log.info(u'I already am the UNIX user [%s]' % pg_demon_user_passwd_line[0]) | |
1643 | 1662 | |
1644 | 1663 | else: |
1645 | 1664 | _log.warning('not running as root or postgres, cannot become postmaster demon user') |
1646 | 1665 | _log.warning('may have trouble connecting as gm-dbo if IDENT auth is forced upon us') |
1647 | 1666 | if _interactive: |
1648 | 1667 | print_msg("WARNING: This script may not work if not running as the system administrator.") |
1668 | ||
1649 | 1669 | #============================================================================== |
1650 | 1670 | def cfg_get(group=None, option=None): |
1651 | 1671 | return _cfg.get ( |
1653 | 1673 | option = option, |
1654 | 1674 | source_order = [('file', 'return')] |
1655 | 1675 | ) |
1676 | ||
1656 | 1677 | #================================================================== |
1657 | 1678 | def handle_cfg(): |
1658 | 1679 | """Bootstrap the source 'file' in _cfg.""" |
1659 | 1680 | |
1660 | _log.info('config file: %s', _cfg.source_files['file']) | |
1681 | _log.info(u'config file: %s', _cfg.source_files['file']) | |
1661 | 1682 | |
1662 | 1683 | become_pg_demon_user() |
1663 | 1684 | |
1664 | tmp = cfg_get("installation", "interactive") | |
1665 | 1685 | global _interactive |
1666 | if tmp == "yes": | |
1667 | _interactive = True | |
1668 | elif tmp == "no": | |
1669 | _interactive = False | |
1686 | ||
1687 | if _interactive is None: | |
1688 | tmp = cfg_get("installation", "interactive") | |
1689 | if tmp == "no": | |
1690 | _interactive = False | |
1691 | else: | |
1692 | _interactive = True | |
1670 | 1693 | |
1671 | 1694 | tmp = cfg_get('installation', 'keep temp files') |
1672 | 1695 | if tmp == "yes": |
1703 | 1726 | # get initial conf file from CLI |
1704 | 1727 | cfg_file = _cfg.get(option = '--conf-file', source_order = [('cli', 'return')]) |
1705 | 1728 | if cfg_file is None: |
1706 | _log.error("no config file specified on command line") | |
1729 | _log.error(u"no config file specified on command line") | |
1707 | 1730 | exit_with_msg('Cannot bootstrap without config file. Use --conf-file=<FILE>.') |
1708 | 1731 | |
1709 | _log.info('initial config file: %s', cfg_file) | |
1732 | _log.info(u'initial config file: %s', cfg_file) | |
1710 | 1733 | |
1711 | 1734 | # read that conf file |
1712 | 1735 | _cfg.add_file_source ( |
1722 | 1745 | ) |
1723 | 1746 | |
1724 | 1747 | if cfg_files is None: |
1725 | _log.info('single-shot config file') | |
1748 | _log.info(u'single-shot config file') | |
1726 | 1749 | handle_cfg() |
1727 | 1750 | else: |
1728 | _log.info('aggregation of config files') | |
1751 | _log.info(u'aggregation of config files') | |
1752 | tmp = cfg_get("installation", "interactive") | |
1753 | global _interactive | |
1754 | if tmp == "no": | |
1755 | _interactive = False | |
1756 | else: | |
1757 | _interactive = True | |
1729 | 1758 | for cfg_file in cfg_files: |
1730 | 1759 | # read that conf file |
1731 | 1760 | _cfg.add_file_source ( |
1749 | 1778 | |
1750 | 1779 | db.check_holy_auth_line() |
1751 | 1780 | |
1781 | _log.info(u"shutdown") | |
1782 | print("Done bootstrapping GNUmed database: We very likely succeeded.") | |
1783 | print 'log:', gmLog2._logfile_name | |
1784 | ||
1785 | #================================================================== | |
1786 | if __name__ != "__main__": | |
1787 | print "This currently is not intended to be used as a module." | |
1788 | sys.exit(1) | |
1789 | ||
1790 | ||
1791 | gmI18N.activate_locale() | |
1792 | gmLog2.set_string_encoding() | |
1793 | ||
1794 | _log.info(u'startup') | |
1795 | ||
1796 | try: | |
1797 | main() | |
1798 | except StandardError: | |
1799 | _log.exception(u'unhandled exception caught, shutting down connections') | |
1800 | exit_with_msg(u'Bootstrapping failed: unhandled exception occurred') | |
1801 | finally: | |
1752 | 1802 | for conn in conn_ref_count: |
1753 | 1803 | if conn.closed == 0: |
1754 | _log.warning('open connection detected: %s', conn.cookie) | |
1755 | _log.warning('%s', conn) | |
1756 | _log.warning('closing connection') | |
1804 | _log.warning(u'open connection detected: %s', conn.cookie) | |
1805 | _log.warning(u'%s', conn) | |
1806 | _log.warning(u'closing connection') | |
1757 | 1807 | conn.close() |
1758 | ||
1759 | _log.info("shutdown") | |
1760 | print("Done bootstrapping GNUmed database: We very likely succeeded.") | |
1761 | print 'log:', gmLog2._logfile_name | |
1762 | ||
1763 | #================================================================== | |
1764 | if __name__ == "__main__": | |
1765 | ||
1766 | gmI18N.activate_locale() | |
1767 | gmLog2.set_string_encoding() | |
1768 | ||
1769 | _log.info("startup") | |
1770 | ||
1771 | try: | |
1772 | main() | |
1773 | except Exception: | |
1774 | for c in conn_ref_count: | |
1775 | if c.closed == 0: | |
1776 | print 'closing open connection from:', c.cookie | |
1777 | print c | |
1778 | c.close() | |
1779 | _log.exception('unhandled exception caught') | |
1780 | exit_with_msg("Bootstrapping failed: unhandled exception occurred") | |
1781 | ||
1782 | sys.exit(0) | |
1783 | else: | |
1784 | print "This currently is not intended to be used as a module." | |
1785 | sys.exit(1) | |
1808 | del conn | |
1809 | del conn_ref_count | |
1810 | ||
1811 | _log.info(u'after main, before sys.exit(0)') | |
1812 | ||
1813 | sys.exit(0) | |
1814 | ||
1786 | 1815 | |
1787 | 1816 | #================================================================== |
1788 | 1817 | # pipe = popen2.Popen3(cmd, 1==1) |
1799 | 1828 | # tmp = pipe.fromchild.read() |
1800 | 1829 | # lines = tmp.split("\n") |
1801 | 1830 | # for line in lines: |
1802 | # _log.debug("child stdout: [%s]" % line, gmLog.lCooked) | |
1831 | # _log.debug(u"child stdout: [%s]" % line, gmLog.lCooked) | |
1803 | 1832 | # tmp = pipe.childerr.read() |
1804 | 1833 | # lines = tmp.split("\n") |
1805 | 1834 | # for line in lines: |
1806 | # _log.error("child stderr: [%s]" % line, gmLog.lCooked) | |
1835 | # _log.error(u"child stderr: [%s]" % line, gmLog.lCooked) | |
1807 | 1836 | |
1808 | 1837 | # pipe.fromchild.close() |
1809 | 1838 | # pipe.childerr.close() |
1810 | 1839 | # del pipe |
1811 | 1840 | |
1812 | 1841 | #================================================================== |
1813 |
26 | 26 | minimum postgresql version = 9.2 |
27 | 27 | schema base directory = ../sql/v20-v21/fixups/ |
28 | 28 | schema = $schema$ |
29 | v21-db-sql_inheritance-fixup.sql | |
30 | v21-audit-add_table_for_audit-fixup.sql | |
31 | v21-i18n-lang_funcs-fixup.sql | |
29 | 32 | v21-previously-missing-array_agg-fixup.sql |
30 | 33 | v21-dem-view_grants-fixup.sql |
31 | 34 | ../dynamic/v21-release_notes-dynamic.sql |
37 | 40 | v21-ref-auto_hint-smoking_status-fixup.sql |
38 | 41 | v21-ref-GKV_CU-fixup.sql |
39 | 42 | v21-clin-get_hints_for_patient-fixup.sql |
43 | v21-clin-v_substance_intakes-fixup.sql | |
40 | 44 | v21-notifications-dynamic.sql |
41 | 45 | v21-clin-uppercase_soap_cat-fixup.sql |
42 | 46 | v21-dem-identity-fixup.sql |
118 | 118 | minimum postgresql version = 9.2 |
119 | 119 | schema base directory = ../sql/v20-v21/fixups/ |
120 | 120 | schema = $schema$ |
121 | v21-db-sql_inheritance-fixup.sql | |
122 | v21-audit-add_table_for_audit-fixup.sql | |
123 | v21-i18n-lang_funcs-fixup.sql | |
121 | 124 | v21-previously-missing-array_agg-fixup.sql |
122 | 125 | v21-dem-view_grants-fixup.sql |
123 | 126 | v21-ref-auto_hint-tetanus_STIKO.sql |
128 | 131 | v21-ref-auto_hint-smoking_status-fixup.sql |
129 | 132 | v21-ref-GKV_CU-fixup.sql |
130 | 133 | v21-clin-get_hints_for_patient-fixup.sql |
134 | v21-clin-v_substance_intakes-fixup.sql | |
131 | 135 | v21-notifications-dynamic.sql |
132 | 136 | v21-clin-uppercase_soap_cat-fixup.sql |
133 | 137 | v21-dem-identity-fixup.sql |
111 | 111 | <body> |
112 | 112 | |
113 | 113 | <!-- Primary Index --> |
114 | <p><br><br>Dumped on 2017-08-31</p> | |
114 | <p><br><br>Dumped on 2017-10-28</p> | |
115 | 115 | <h1><a name="index">Index of database - gnumed_v21</a></h1> |
116 | 116 | <ul> |
117 | 117 |
50 | 50 | echo "alter database ${TARGET_DB} set lc_messages to 'C';" >> $SQL_FILE |
51 | 51 | echo "alter database ${TARGET_DB} set password_encryption to 'on';" >> $SQL_FILE |
52 | 52 | echo "alter database ${TARGET_DB} set synchronous_commit to 'on';" >> $SQL_FILE |
53 | echo "alter database ${TARGET_DB} set sql_inheritance to 'on';" >> $SQL_FILE | |
54 | 53 | echo "alter database ${TARGET_DB} set check_function_bodies to 'on';" >> $SQL_FILE |
54 | echo "-- starting with 9.3:" >> $SQL_FILE | |
55 | echo "alter database ${TARGET_DB} set ignore_checksum_failure to 'off';" >> $SQL_FILE | |
56 | ||
55 | 57 | echo "" >> $SQL_FILE |
56 | echo "-- starting with 9.3 (remove when 9.3 is required):" >> $SQL_FILE | |
57 | echo "\unset ON_ERROR_STOP" >> $SQL_FILE | |
58 | echo "alter database ${TARGET_DB} set ignore_checksum_failure to 'off'; -- comment out if the script fails" >> $SQL_FILE | |
59 | echo "\set ON_ERROR_STOP 1" >> $SQL_FILE | |
60 | echo "" >> $SQL_FILE | |
61 | echo "-- < PG 9.0 only:" >> $SQL_FILE | |
62 | echo "--\unset ON_ERROR_STOP" >> $SQL_FILE | |
63 | echo "--alter database ${TARGET_DB} set regex_flavor to 'advanced';" >> $SQL_FILE | |
64 | echo "--\set ON_ERROR_STOP 1" >> $SQL_FILE | |
58 | echo "-- PG < 10 only:" >> $SQL_FILE | |
59 | echo "--alter database ${TARGET_DB} set sql_inheritance to 'on';" >> $SQL_FILE | |
65 | 60 | |
66 | 61 | echo "" >> $SQL_FILE |
67 | 62 | echo "-- the following can only be set at server start" >> $SQL_FILE |
45 | 45 | if (prop == 'mimetype') and (val != worst_case): |
46 | 46 | return val |
47 | 47 | except ImportError: |
48 | _log.debug('module <extractor> (python wrapper for libextractor) not installed') | |
49 | ||
48 | _log.debug(u'module <extractor> (python wrapper for libextractor) not installed') | |
49 | except OSError as exc: | |
50 | # winerror 126, errno 22 | |
51 | if exc.errno == 22: | |
52 | _log.exception(u'module <extractor> (python wrapper for libextractor) not installed') | |
53 | else: | |
54 | raise | |
50 | 55 | ret_code = -1 |
51 | 56 | |
52 | 57 | # 2) use "file" system command |
384 | 389 | |
385 | 390 | #_get_system_startfile_cmd(filename) |
386 | 391 | #print(_system_startfile_cmd) |
387 | #print(guess_mimetype(filename)) | |
392 | print(guess_mimetype(filename)) | |
388 | 393 | #print(get_viewer_cmd(guess_mimetype(filename), filename)) |
389 | 394 | #print(guess_ext_by_mimetype(mimetype=filename)) |
390 | 395 | #call_viewer_on_file(aFile = filename, block=None) |
391 | status, desc = describe_file(filename) | |
392 | print status | |
393 | print desc | |
396 | ||
397 | #status, desc = describe_file(filename) | |
398 | #print status | |
399 | #print desc |
1548 | 1548 | conn_status = u'%s (%s)' % (conn.status, map_psyco_conn_status2str[conn.status]) |
1549 | 1549 | if conn.closed != 0: |
1550 | 1550 | conn_status = u'undefined (%s)' % conn_status |
1551 | try: | |
1552 | conn_deferrable = conn.deferrable | |
1553 | except AttributeError: | |
1554 | conn_deferrable = u'unavailable' | |
1551 | 1555 | |
1552 | 1556 | d = { |
1553 | 1557 | u'identity': id(conn), |
1559 | 1563 | u'autocommit': conn.autocommit, |
1560 | 1564 | u'isolation level (psyco)': isolation_level, |
1561 | 1565 | u'async': conn.async, |
1562 | u'deferrable': conn.deferrable, | |
1566 | u'deferrable': conn_deferrable, | |
1563 | 1567 | u'transaction status': u'%s (%s)' % (tx_status, map_psyco_tx_status2str[tx_status]), |
1564 | 1568 | u'connection status': conn_status, |
1565 | 1569 | u'executing async op': conn.isexecuting(), |
1596 | 1600 | isolation_level = u'tx aborted or unknown, cannot retrieve' |
1597 | 1601 | else: |
1598 | 1602 | isolation_level = conn.isolation_level |
1603 | try: | |
1604 | conn_deferrable = conn.deferrable | |
1605 | except AttributeError: | |
1606 | conn_deferrable = u'unavailable' | |
1599 | 1607 | |
1600 | 1608 | if cursor.query is None: |
1601 | 1609 | query = u'<no query>' |
1637 | 1645 | isolation_level, |
1638 | 1646 | conn.encoding, |
1639 | 1647 | conn.async, |
1640 | conn.deferrable, | |
1648 | conn_deferrable, | |
1641 | 1649 | conn.readonly, |
1642 | 1650 | map_psyco_tx_status2str[tx_status], |
1643 | 1651 | map_psyco_conn_status2str[conn.status], |
1852 | 1860 | if verbose: |
1853 | 1861 | _log.debug(capture_cursor_state(curs)) |
1854 | 1862 | for notice in notices_accessor.notices: |
1855 | _log.debug(notice.strip(u'\n').strip(u'\r')) | |
1863 | _log.debug(unicode(notice, 'utf8', 'replace').strip(u'\n').strip(u'\r')) | |
1856 | 1864 | del notices_accessor.notices[:] |
1857 | 1865 | # DB related exceptions |
1858 | 1866 | except dbapi.Error as pg_exc: |
1867 | 1875 | continue |
1868 | 1876 | _log.error(u'PG diags %s: %s', prop, val) |
1869 | 1877 | for notice in notices_accessor.notices: |
1870 | _log.error(notice.strip(u'\n').strip(u'\r')) | |
1878 | _log.error(unicode(notice, 'utf8', 'replace').strip(u'\n').strip(u'\r')) | |
1871 | 1879 | del notices_accessor.notices[:] |
1872 | 1880 | pg_exc = make_pg_exception_fields_unicode(pg_exc) |
1873 | 1881 | _log.error(u'PG error code: %s', pg_exc.pgcode) |
1911 | 1919 | _log.exception('error running query in RW connection') |
1912 | 1920 | _log.error(capture_cursor_state(curs)) |
1913 | 1921 | for notice in notices_accessor.notices: |
1914 | _log.debug(notice.strip(u'\n').strip(u'\r')) | |
1922 | _log.debug(unicode(notice, 'utf8', 'replace').strip(u'\n').strip(u'\r')) | |
1915 | 1923 | del notices_accessor.notices[:] |
1916 | 1924 | gmLog2.log_stack_trace() |
1917 | 1925 | try: |
2288 | 2296 | |
2289 | 2297 | options2check = { |
2290 | 2298 | # setting: [expected value, risk, fatal?] |
2291 | u'allow_system_table_mods': [u'off', u'system breakage', False], | |
2292 | u'check_function_bodies': [u'on', u'suboptimal error detection', False], | |
2293 | u'datestyle': [u'ISO', u'faulty timestamp parsing', True], | |
2294 | u'default_transaction_isolation': [u'read committed', u'faulty database reads', True], | |
2295 | u'default_transaction_read_only': [u'on', u'accidental database writes', False], | |
2296 | u'fsync': [u'on', u'data loss/corruption', True], | |
2297 | u'full_page_writes': [u'on', u'data loss/corruption', False], | |
2298 | u'lc_messages': [u'C', u'suboptimal error detection', False], | |
2299 | u'password_encryption': [u'on', u'breach of confidentiality', False], | |
2300 | #u'regex_flavor': [u'advanced', u'query breakage', False], # 9.0 doesn't support this anymore, default now advanced anyway | |
2301 | u'synchronous_commit': [u'on', u'data loss/corruption', False], | |
2302 | u'sql_inheritance': [u'on', u'query breakage, data loss/corruption', True], | |
2303 | u'ignore_checksum_failure': [u'off', u'data loss/corruption', False], # starting with PG 9.3 | |
2304 | u'track_commit_timestamp': [u'on', u'suboptimal auditing', False] # starting with PG 9.3 | |
2299 | u'allow_system_table_mods': [[u'off'], u'system breakage', False], | |
2300 | u'check_function_bodies': [[u'on'], u'suboptimal error detection', False], | |
2301 | u'datestyle': [[u'ISO'], u'faulty timestamp parsing', True], | |
2302 | u'default_transaction_isolation': [[u'read committed'], u'faulty database reads', True], | |
2303 | u'default_transaction_read_only': [[u'on'], u'accidental database writes', False], | |
2304 | u'fsync': [[u'on'], u'data loss/corruption', True], | |
2305 | u'full_page_writes': [[u'on'], u'data loss/corruption', False], | |
2306 | u'lc_messages': [[u'C'], u'suboptimal error detection', False], | |
2307 | u'password_encryption': [[u'on', u'md5', u'scram-sha-256'], u'breach of confidentiality', False], | |
2308 | #u'regex_flavor': [[u'advanced'], u'query breakage', False], # 9.0 doesn't support this anymore, default now advanced anyway | |
2309 | u'synchronous_commit': [[u'on'], u'data loss/corruption', False], | |
2310 | u'sql_inheritance': [[u'on'], u'query breakage, data loss/corruption', True], # IF returned (<PG10): better be ON, if NOT returned (PG10): hardwired | |
2311 | u'ignore_checksum_failure': [[u'off'], u'data loss/corruption', False], # starting with PG 9.3 | |
2312 | u'track_commit_timestamp': [[u'on'], u'suboptimal auditing', False] # starting with PG 9.3 | |
2305 | 2313 | } |
2306 | 2314 | |
2307 | 2315 | from Gnumed.pycommon import gmCfg2 |
2308 | 2316 | _cfg = gmCfg2.gmCfgData() |
2309 | 2317 | if _cfg.get(option = u'hipaa'): |
2310 | options2check[u'log_connections'] = [u'on', u'non-compliance with HIPAA', True] | |
2311 | options2check[u'log_disconnections'] = [u'on', u'non-compliance with HIPAA', True] | |
2318 | options2check[u'log_connections'] = [[u'on'], u'non-compliance with HIPAA', True] | |
2319 | options2check[u'log_disconnections'] = [[u'on'], u'non-compliance with HIPAA', True] | |
2312 | 2320 | else: |
2313 | options2check[u'log_connections'] = [u'on', u'non-compliance with HIPAA', None] | |
2314 | options2check[u'log_disconnections'] = [u'on', u'non-compliance with HIPAA', None] | |
2321 | options2check[u'log_connections'] = [[u'on'], u'non-compliance with HIPAA', None] | |
2322 | options2check[u'log_disconnections'] = [[u'on'], u'non-compliance with HIPAA', None] | |
2315 | 2323 | |
2316 | 2324 | cmd = u"SELECT name, setting from pg_settings where name in %(settings)s" |
2317 | 2325 | rows, idx = run_ro_queries ( |
2326 | 2334 | for row in rows: |
2327 | 2335 | option = row['name'] |
2328 | 2336 | value_found = row['setting'] |
2329 | value_expected = options2check[option][0] | |
2337 | values_expected = options2check[option][0] | |
2330 | 2338 | risk = options2check[option][1] |
2331 | 2339 | fatal_setting = options2check[option][2] |
2332 | if value_found != value_expected: | |
2340 | if value_found not in values_expected: | |
2333 | 2341 | if fatal_setting is True: |
2334 | 2342 | found_error = True |
2335 | 2343 | elif fatal_setting is False: |
2341 | 2349 | raise ValueError(u'invalid database configuration sanity check') |
2342 | 2350 | msg.append(_(' option [%s]: %s') % (option, value_found)) |
2343 | 2351 | msg.append(_(' risk: %s') % risk) |
2344 | _log.warning('PG option [%s] set to [%s], expected [%s], risk: <%s>' % (option, value_found, value_expected, risk)) | |
2352 | _log.warning('PG option [%s] set to [%s], expected %s, risk: <%s>' % (option, value_found, values_expected, risk)) | |
2345 | 2353 | |
2346 | 2354 | if found_error: |
2347 | 2355 | return 2, u'\n'.join(msg) |
2489 | 2497 | |
2490 | 2498 | def getquoted(self): |
2491 | 2499 | return _timestamp_template % self.__dt.isoformat() |
2492 | ||
2493 | ## remove for 0.9 | |
2494 | ## ---------------------------------------------------------------------- | |
2495 | ##class cAdapterMxDateTime(object): | |
2496 | ## | |
2497 | ## def __init__(self, dt): | |
2498 | ## if dt.tz == '???': | |
2499 | ## _log.info('[%s]: no time zone string available in (%s), assuming local time zone', self.__class__.__name__, dt) | |
2500 | ## self.__dt = dt | |
2501 | ## | |
2502 | ## def getquoted(self): | |
2503 | ## # under some locale settings the mx.DateTime ISO formatter | |
2504 | ## # will insert "," into the ISO string, | |
2505 | ## # while this is allowed per the ISO8601 spec PostgreSQL | |
2506 | ## # cannot currently handle that, | |
2507 | ## # so map those "," to "." to make things work: | |
2508 | ## return mxDT.ISO.str(self.__dt).replace(',', '.') | |
2509 | ## | |
2510 | ## ---------------------------------------------------------------------- | |
2511 | ## PostgreSQL -> Python | |
2512 | ## ---------------------------------------------------------------------- | |
2513 | 2500 | |
2514 | 2501 | #======================================================================= |
2515 | 2502 | # main |
8 | 8 | __license__ = "GPL v2 or later (details at http://www.gnu.org)" |
9 | 9 | |
10 | 10 | # stdlib |
11 | import sys, os, string, re, urllib2, logging, io | |
11 | import sys | |
12 | import os | |
13 | import re | |
14 | import logging | |
15 | import io | |
12 | 16 | |
13 | 17 | |
14 | 18 | _log = logging.getLogger('gm.bootstrapper') |
15 | 19 | |
16 | 20 | unformattable_error_id = 12345 |
17 | #=================================================================== | |
18 | def shellrun (cmd): | |
19 | """ | |
20 | runs the shell command and returns a string | |
21 | """ | |
22 | stdin, stdout = os.popen4 (cmd.group (1)) | |
23 | r = stdout.read () | |
24 | stdout.close() | |
25 | stdin.close() | |
26 | return r | |
27 | #------------------------------------------------------------------- | |
28 | def shell(str): | |
29 | """ | |
30 | performs backtick shell extension in a string | |
31 | """ | |
32 | return re.sub (r"`(.*)`", shellrun, str) | |
33 | 21 | |
34 | 22 | #=================================================================== |
35 | 23 | class Psql: |
39 | 27 | db : the interpreter to connect to, must be a DBAPI compliant interface |
40 | 28 | """ |
41 | 29 | self.conn = conn |
42 | self.vars = {'ON_ERROR_STOP':None} | |
30 | self.vars = {'ON_ERROR_STOP': None} | |
43 | 31 | |
44 | 32 | #--------------------------------------------------------------- |
45 | def match (self, str): | |
46 | match = re.match (str, self.line) | |
33 | def match(self, pattern): | |
34 | match = re.match(pattern, self.line) | |
47 | 35 | if match is None: |
48 | ret = 0 | |
49 | else: | |
50 | ret = 1 | |
51 | self.groups = match.groups () | |
52 | return ret | |
36 | return 0 | |
37 | ||
38 | self.groups = match.groups() | |
39 | return 1 | |
53 | 40 | |
54 | 41 | #--------------------------------------------------------------- |
55 | 42 | def fmt_msg(self, aMsg): |
73 | 60 | filename: a file, containg semicolon-separated SQL commands |
74 | 61 | """ |
75 | 62 | _log.debug('processing [%s]', filename) |
76 | if re.match ("http://.*", filename) or re.match ("ftp://.*", filename) or re.match ("gopher://.*", filename): | |
77 | try: | |
78 | self.file = urllib2.urlopen (filename) | |
79 | except URLError: | |
80 | _log.error(u"cannot access [%s]", filename) | |
81 | return 1 | |
63 | curs = self.conn.cursor() | |
64 | curs.execute(u'show session authorization') | |
65 | start_auth = curs.fetchall()[0][0] | |
66 | curs.close() | |
67 | _log.debug(u'session auth: %s', start_auth) | |
68 | ||
69 | if os.access (filename, os.R_OK): | |
70 | sql_file = io.open(filename, mode = 'rt', encoding = 'utf8') | |
82 | 71 | else: |
83 | if os.access (filename, os.R_OK): | |
84 | self.file = io.open(filename, mode = 'rt', encoding = 'utf8') | |
85 | else: | |
86 | _log.error(u"cannot open file [%s]", filename) | |
87 | return 1 | |
72 | _log.error(u"cannot open file [%s]", filename) | |
73 | return 1 | |
88 | 74 | |
89 | 75 | self.lineno = 0 |
90 | 76 | self.filename = filename |
93 | 79 | curr_cmd = '' |
94 | 80 | curs = self.conn.cursor() |
95 | 81 | |
96 | for self.line in self.file.readlines(): | |
82 | for self.line in sql_file.readlines(): | |
97 | 83 | self.lineno += 1 |
98 | 84 | if len(self.line.strip()) == 0: |
99 | 85 | continue |
100 | 86 | |
101 | # \echo | |
102 | if self.match (r"^\\echo (.*)"): | |
103 | _log.info(self.fmt_msg(shell(self.groups[0]))) | |
104 | continue | |
105 | ||
106 | # \qecho | |
107 | if self.match (r"^\\qecho (.*)"): | |
108 | _log.info(self.fmt_msg(shell (self.groups[0]))) | |
109 | continue | |
110 | ||
111 | # \q | |
112 | if self.match (r"^\\q"): | |
113 | _log.warning(self.fmt_msg(u"script terminated by \\q")) | |
114 | return 0 | |
115 | ||
116 | 87 | # \set |
117 | if self.match (r"^\\set (\S+) (\S+)"): | |
118 | self.vars[self.groups[0]] = shell (self.groups[1]) | |
88 | if self.match(r"^\\set (\S+) (\S+)"): | |
89 | _log.debug(u'"\set" found: %s', self.groups) | |
90 | self.vars[self.groups[0]] = self.groups[1] | |
119 | 91 | if self.groups[0] == 'ON_ERROR_STOP': |
120 | self.vars['ON_ERROR_STOP'] = int (self.vars['ON_ERROR_STOP']) | |
92 | # adjusting from string to int so that "1" -> 1 -> True | |
93 | self.vars['ON_ERROR_STOP'] = int(self.vars['ON_ERROR_STOP']) | |
121 | 94 | continue |
122 | 95 | |
123 | 96 | # \unset |
141 | 114 | if this_char == "'": |
142 | 115 | in_string = not in_string |
143 | 116 | |
144 | # detect -- style comments | |
117 | # detect "--"-style comments | |
145 | 118 | if this_char == '-' and next_char == '-' and not in_string: |
146 | 119 | break |
147 | 120 | |
151 | 124 | if this_char == ')' and not in_string: |
152 | 125 | bracketlevel -= 1 |
153 | 126 | |
154 | # found end of command, not inside string, not inside bracket ? | |
155 | if not (not in_string and (bracketlevel == 0) and (this_char == ';')): | |
127 | # have we: | |
128 | # - found end of command ? | |
129 | # - are not inside a string ? | |
130 | # - are not inside bracket pair ? | |
131 | if not ((in_string is False) and (bracketlevel == 0) and (this_char == ';')): | |
156 | 132 | curr_cmd += this_char |
157 | 133 | else: |
158 | try: | |
159 | if curr_cmd.strip() != '': | |
160 | curs.execute (curr_cmd) | |
161 | except Exception as error: | |
162 | _log.exception(curr_cmd) | |
163 | if re.match (r"^NOTICE:.*", str(error)): | |
164 | _log.warning(self.fmt_msg(error)) | |
165 | else: | |
166 | _log.error(self.fmt_msg(error)) | |
167 | if hasattr(error, 'diag'): | |
168 | for prop in dir(error.diag): | |
169 | if prop.startswith(u'__'): | |
170 | continue | |
171 | val = getattr(error.diag, prop) | |
172 | if val is None: | |
173 | continue | |
174 | _log.error(u'PG diags %s: %s', prop, val) | |
175 | if self.vars['ON_ERROR_STOP']: | |
176 | self.conn.commit() | |
177 | curs.close() | |
178 | return 1 | |
134 | if curr_cmd.strip() != '': | |
135 | try: | |
136 | curs.execute(curr_cmd) | |
137 | try: | |
138 | data = curs.fetchall() | |
139 | _log.debug(u'cursor data: %s', data) | |
140 | except StandardError: # actually: psycopg2.ProgrammingError but no handle | |
141 | pass | |
142 | except Exception as error: | |
143 | _log.exception(curr_cmd) | |
144 | if re.match(r"^NOTICE:.*", str(error)): | |
145 | _log.warning(self.fmt_msg(error)) | |
146 | else: | |
147 | _log.error(self.fmt_msg(error)) | |
148 | if hasattr(error, 'diag'): | |
149 | for prop in dir(error.diag): | |
150 | if prop.startswith(u'__'): | |
151 | continue | |
152 | val = getattr(error.diag, prop) | |
153 | if val is None: | |
154 | continue | |
155 | _log.error(u'PG diags %s: %s', prop, val) | |
156 | if self.vars['ON_ERROR_STOP']: | |
157 | self.conn.commit() | |
158 | curs.close() | |
159 | return 1 | |
179 | 160 | |
180 | 161 | self.conn.commit() |
181 | 162 | curs.close() |
183 | 164 | curr_cmd = '' |
184 | 165 | |
185 | 166 | this_char = next_char |
186 | ||
187 | 167 | # end of loop over chars |
188 | 168 | |
189 | 169 | # end of loop over lines |
190 | 170 | self.conn.commit() |
171 | curs.execute(u'show session authorization') | |
172 | end_auth = curs.fetchall()[0][0] | |
191 | 173 | curs.close() |
174 | _log.debug(u'session auth after sql file processing: %s', end_auth) | |
175 | if start_auth != end_auth: | |
176 | _log.error('session auth changed before/after processing sql file') | |
177 | ||
192 | 178 | return 0 |
193 | 179 | |
194 | 180 | #=================================================================== |
202 | 188 | sys.exit() |
203 | 189 | |
204 | 190 | #from pyPgSQL import PgSQL |
205 | conn = PgSQL.connect (user='gm-dbo', database = 'gnumed') | |
206 | psql = Psql (conn) | |
207 | psql.run (sys.argv[1]) | |
208 | conn.close () | |
191 | conn = PgSQL.connect(user='gm-dbo', database = 'gnumed') | |
192 | psql = Psql(conn) | |
193 | psql.run(sys.argv[1]) | |
194 | conn.close() |
47 | 47 | |
48 | 48 | -- =================================================================== |
49 | 49 | create or replace function audit.add_table_for_audit(name, name) |
50 | returns unknown | |
50 | returns boolean | |
51 | 51 | language 'plpgsql' |
52 | 52 | security definer |
53 | 53 | as ' |
86 | 86 | |
87 | 87 | |
88 | 88 | create or replace function audit.add_table_for_audit(name) |
89 | returns unknown | |
89 | returns boolean | |
90 | 90 | language SQL |
91 | 91 | security definer |
92 | 92 | as ' |
161 | 161 | |
162 | 162 | -- ============================================= |
163 | 163 | create or replace function i18n.set_curr_lang(text) |
164 | returns unknown | |
164 | returns boolean | |
165 | 165 | language 'plpgsql' |
166 | 166 | security definer |
167 | 167 | as ' |
185 | 185 | |
186 | 186 | -- ============================================= |
187 | 187 | create or replace function i18n.force_curr_lang(text) |
188 | returns unknown | |
188 | returns boolean | |
189 | 189 | language 'plpgsql' |
190 | 190 | security definer |
191 | 191 | as ' |
259 | 259 | -- ============================================= |
260 | 260 | -- do simple schema revision tracking |
261 | 261 | select log_script_insertion('$RCSfile: gmI18N-dynamic.sql,v $', '$Revision: 1.5 $'); |
262 | ||
263 | -- ============================================= | |
264 | -- $Log: gmI18N-dynamic.sql,v $ | |
265 | -- Revision 1.5 2006-07-24 14:18:52 ncq | |
266 | -- - add comment | |
267 | -- | |
268 | -- Revision 1.4 2006/07/01 15:22:03 ncq | |
269 | -- - do not hard-fail set_curr_lang() | |
270 | -- | |
271 | -- Revision 1.3 2006/02/06 13:18:27 ncq | |
272 | -- - quote user when column name | |
273 | -- | |
274 | -- Revision 1.2 2006/01/10 08:44:22 ncq | |
275 | -- - drop index does not require "on" | |
276 | -- | |
277 | -- Revision 1.1 2006/01/09 13:42:29 ncq | |
278 | -- - factor out dynamic stuff | |
279 | -- - move into schema "i18n" (except for _()) | |
280 | -- | |
281 | -- Revision 1.23 2005/09/19 16:38:51 ncq | |
282 | -- - adjust to removed is_core from gm_schema_revision | |
283 | -- | |
284 | -- Revision 1.22 2005/07/14 21:31:42 ncq | |
285 | -- - partially use improved schema revision tracking | |
286 | -- | |
287 | -- Revision 1.21 2005/07/04 11:42:24 ncq | |
288 | -- - fix _(text, text) | |
289 | -- | |
290 | -- Revision 1.20 2005/03/31 20:08:38 ncq | |
291 | -- - add i18n_upd_tx() for safe update of translations | |
292 | -- | |
293 | -- Revision 1.19 2005/03/01 20:38:19 ncq | |
294 | -- - varchar -> text | |
295 | -- | |
296 | -- Revision 1.18 2005/02/03 20:28:25 ncq | |
297 | -- - improved comments | |
298 | -- - added _(text, text) | |
299 | -- | |
300 | -- Revision 1.17 2005/02/01 16:52:50 ncq | |
301 | -- - added force_curr_lang() | |
302 | -- | |
303 | -- Revision 1.16 2004/07/17 20:57:53 ncq | |
304 | -- - don't use user/_user workaround anymore as we dropped supporting | |
305 | -- it (but we did NOT drop supporting readonly connections on > 7.3) | |
306 | -- | |
307 | -- Revision 1.15 2003/12/29 15:40:42 uid66147 | |
308 | -- - added not null | |
309 | -- - added v_missing_translations | |
310 | -- | |
311 | -- Revision 1.14 2003/06/10 09:58:11 ncq | |
312 | -- - i18n() inserts strings into i18n_keys, not _(), fix comment to that effect | |
313 | -- | |
314 | -- Revision 1.13 2003/05/12 12:43:39 ncq | |
315 | -- - gmI18N, gmServices and gmSchemaRevision are imported globally at the | |
316 | -- database level now, don't include them in individual schema file anymore | |
317 | -- | |
318 | -- Revision 1.12 2003/05/02 15:06:44 ncq | |
319 | -- - fix comment | |
320 | -- | |
321 | -- Revision 1.11 2003/04/23 08:36:00 michaelb | |
322 | -- made i18n_curr_lang longer still (11 to 15) | |
323 | -- | |
324 | -- Revision 1.9 2003/02/04 13:22:01 ncq | |
325 | -- - refined set_curr_lang to only work if translations available | |
326 | -- - also auto-set for both "user" and "_user" | |
327 | -- | |
328 | -- Revision 1.8 2003/02/04 12:22:52 ncq | |
329 | -- - valid until in create user cannot do a sub-query :-( | |
330 | -- - columns "owner" should really be of type "name" if defaulting to "CURRENT_USER" | |
331 | -- - new functions set_curr_lang(*) | |
332 | -- | |
333 | -- Revision 1.7 2003/01/24 14:16:18 ncq | |
334 | -- - don't drop functions repeatedly since that will kill views created earlier | |
335 | -- | |
336 | -- Revision 1.6 2003/01/20 20:21:53 ncq | |
337 | -- - keep the last useful bit from i18n.sql as documentation | |
338 | -- | |
339 | -- Revision 1.5 2003/01/20 19:42:47 ncq | |
340 | -- - simplified creation of translating view a lot | |
341 | -- | |
342 | -- Revision 1.4 2003/01/17 00:24:33 ncq | |
343 | -- - add a few access right definitions | |
344 | -- | |
345 | -- Revision 1.3 2003/01/05 13:05:51 ncq | |
346 | -- - schema_revision -> gm_schema_revision | |
347 | -- | |
348 | -- Revision 1.2 2003/01/04 10:30:26 ncq | |
349 | -- - better documentation | |
350 | -- - insert default english "translation" into i18n_translations | |
351 | -- | |
352 | -- Revision 1.1 2003/01/01 17:41:57 ncq | |
353 | -- - improved database i18n | |
354 | -- |
57 | 57 | -- ============================================= |
58 | 58 | -- do simple schema revision tracking |
59 | 59 | select log_script_insertion('$RCSfile: gmI18N.sql,v $', '$Revision: 1.25 $'); |
60 | ||
61 | -- ============================================= | |
62 | -- $Log: gmI18N.sql,v $ | |
63 | -- Revision 1.25 2006-02-10 14:06:40 ncq | |
64 | -- - proper script insertion logging | |
65 | -- | |
66 | -- Revision 1.24 2006/01/09 13:42:29 ncq | |
67 | -- - factor out dynamic stuff | |
68 | -- - move into schema "i18n" (except for _()) | |
69 | -- | |
70 | -- Revision 1.23 2005/09/19 16:38:51 ncq | |
71 | -- - adjust to removed is_core from gm_schema_revision | |
72 | -- | |
73 | -- Revision 1.22 2005/07/14 21:31:42 ncq | |
74 | -- - partially use improved schema revision tracking | |
75 | -- | |
76 | -- Revision 1.21 2005/07/04 11:42:24 ncq | |
77 | -- - fix _(text, text) | |
78 | -- | |
79 | -- Revision 1.20 2005/03/31 20:08:38 ncq | |
80 | -- - add i18n_upd_tx() for safe update of translations | |
81 | -- | |
82 | -- Revision 1.19 2005/03/01 20:38:19 ncq | |
83 | -- - varchar -> text | |
84 | -- | |
85 | -- Revision 1.18 2005/02/03 20:28:25 ncq | |
86 | -- - improved comments | |
87 | -- - added _(text, text) | |
88 | -- | |
89 | -- Revision 1.17 2005/02/01 16:52:50 ncq | |
90 | -- - added force_curr_lang() | |
91 | -- | |
92 | -- Revision 1.16 2004/07/17 20:57:53 ncq | |
93 | -- - don't use user/_user workaround anymore as we dropped supporting | |
94 | -- it (but we did NOT drop supporting readonly connections on > 7.3) | |
95 | -- | |
96 | -- Revision 1.15 2003/12/29 15:40:42 uid66147 | |
97 | -- - added not null | |
98 | -- - added v_missing_translations | |
99 | -- | |
100 | -- Revision 1.14 2003/06/10 09:58:11 ncq | |
101 | -- - i18n() inserts strings into i18n_keys, not _(), fix comment to that effect | |
102 | -- | |
103 | -- Revision 1.13 2003/05/12 12:43:39 ncq | |
104 | -- - gmI18N, gmServices and gmSchemaRevision are imported globally at the | |
105 | -- database level now, don't include them in individual schema file anymore | |
106 | -- | |
107 | -- Revision 1.12 2003/05/02 15:06:44 ncq | |
108 | -- - fix comment | |
109 | -- | |
110 | -- Revision 1.11 2003/04/23 08:36:00 michaelb | |
111 | -- made i18n_curr_lang longer still (11 to 15) | |
112 | -- | |
113 | -- Revision 1.9 2003/02/04 13:22:01 ncq | |
114 | -- - refined set_curr_lang to only work if translations available | |
115 | -- - also auto-set for both "user" and "_user" | |
116 | -- | |
117 | -- Revision 1.8 2003/02/04 12:22:52 ncq | |
118 | -- - valid until in create user cannot do a sub-query :-( | |
119 | -- - columns "owner" should really be of type "name" if defaulting to "CURRENT_USER" | |
120 | -- - new functions set_curr_lang(*) | |
121 | -- | |
122 | -- Revision 1.7 2003/01/24 14:16:18 ncq | |
123 | -- - don't drop functions repeatedly since that will kill views created earlier | |
124 | -- | |
125 | -- Revision 1.6 2003/01/20 20:21:53 ncq | |
126 | -- - keep the last useful bit from i18n.sql as documentation | |
127 | -- | |
128 | -- Revision 1.5 2003/01/20 19:42:47 ncq | |
129 | -- - simplified creation of translating view a lot | |
130 | -- | |
131 | -- Revision 1.4 2003/01/17 00:24:33 ncq | |
132 | -- - add a few access right definitions | |
133 | -- | |
134 | -- Revision 1.3 2003/01/05 13:05:51 ncq | |
135 | -- - schema_revision -> gm_schema_revision | |
136 | -- | |
137 | -- Revision 1.2 2003/01/04 10:30:26 ncq | |
138 | -- - better documentation | |
139 | -- - insert default english "translation" into i18n_translations | |
140 | -- | |
141 | -- Revision 1.1 2003/01/01 17:41:57 ncq | |
142 | -- - improved database i18n | |
143 | -- |
19 | 19 | |
20 | 20 | |
21 | 21 | create or replace function i18n.force_curr_lang(text, name) |
22 | returns unknown | |
22 | returns boolean | |
23 | 23 | language 'plpgsql' |
24 | 24 | security definer |
25 | 25 | as E' |
40 | 40 | |
41 | 41 | -- ============================================= |
42 | 42 | create or replace function i18n.force_curr_lang(text) |
43 | returns unknown | |
43 | returns boolean | |
44 | 44 | language 'plpgsql' |
45 | 45 | as ' |
46 | 46 | DECLARE |
120 | 120 | (select fk_patient from clin.encounter where pk = c_si.fk_encounter) |
121 | 121 | as pk_patient, |
122 | 122 | c_si.soap_cat, |
123 | null | |
123 | null::text | |
124 | 124 | as brand, |
125 | 125 | c_si.preparation, |
126 | 126 | r_cs.description |
130 | 130 | as unit, |
131 | 131 | r_cs.atc_code |
132 | 132 | as atc_substance, |
133 | null | |
133 | null::text | |
134 | 134 | as atc_brand, |
135 | null | |
135 | null::text | |
136 | 136 | as external_code_brand, |
137 | null | |
137 | null::text | |
138 | 138 | as external_code_type_brand, |
139 | 139 | |
140 | 140 | c_si.clin_when |
150 | 150 | as episode, |
151 | 151 | c_si.narrative |
152 | 152 | as notes, |
153 | null | |
153 | null::boolean | |
154 | 154 | as fake_brand, |
155 | 155 | -- currently active ? |
156 | 156 | case |
176 | 176 | else null |
177 | 177 | end::boolean |
178 | 178 | as seems_inactive, |
179 | null | |
179 | null::integer | |
180 | 180 | as pk_brand, |
181 | null | |
181 | null::integer | |
182 | 182 | as pk_data_source, |
183 | 183 | r_cs.pk |
184 | 184 | as pk_substance, |
185 | null | |
185 | null::integer | |
186 | 186 | as pk_drug_component, |
187 | 187 | c_si.fk_encounter |
188 | 188 | as pk_encounter, |
13 | 13 | ALTER DATABASE gnumed_v16 |
14 | 14 | SET default_transaction_isolation to 'read committed'; |
15 | 15 | |
16 | ALTER DATABASE gnumed_v16 | |
17 | SET sql_inheritance to 'on'; | |
16 | -- does not exist on PG10 anymore, so can't be set if bootstrapping on PG10 | |
17 | --ALTER DATABASE gnumed_v16 | |
18 | -- SET sql_inheritance to 'on'; | |
18 | 19 | |
19 | 20 | -- -------------------------------------------------------------- |
20 | 21 | select gm.log_script_insertion('v16-db-default_settings.sql', 'v16'); |
21 | ||
22 | -- ==============================================================⏎ |
122 | 122 | (select fk_patient from clin.encounter where pk = c_si.fk_encounter) |
123 | 123 | as pk_patient, |
124 | 124 | c_si.soap_cat, |
125 | null | |
125 | null::text | |
126 | 126 | as brand, |
127 | 127 | c_si.preparation, |
128 | 128 | r_cs.description |
132 | 132 | as unit, |
133 | 133 | r_cs.atc_code |
134 | 134 | as atc_substance, |
135 | null | |
135 | null::text | |
136 | 136 | as atc_brand, |
137 | null | |
137 | null::text | |
138 | 138 | as external_code_brand, |
139 | null | |
139 | null::text | |
140 | 140 | as external_code_type_brand, |
141 | 141 | |
142 | 142 | c_si.clin_when |
154 | 154 | as health_issue, |
155 | 155 | c_si.narrative |
156 | 156 | as notes, |
157 | null | |
157 | null::boolean | |
158 | 158 | as fake_brand, |
159 | 159 | -- currently active ? |
160 | 160 | case |
180 | 180 | else null |
181 | 181 | end::boolean |
182 | 182 | as seems_inactive, |
183 | null | |
183 | null::integer | |
184 | 184 | as pk_brand, |
185 | null | |
185 | null::integer | |
186 | 186 | as pk_data_source, |
187 | 187 | r_cs.pk |
188 | 188 | as pk_substance, |
189 | null | |
189 | null::integer | |
190 | 190 | as pk_drug_component, |
191 | 191 | c_si.fk_encounter |
192 | 192 | as pk_encounter, |
7 | 7 | \set ON_ERROR_STOP 1 |
8 | 8 | |
9 | 9 | -- -------------------------------------------------------------- |
10 | \unset ON_ERROR_STOP | |
11 | 10 | -- very old: |
12 | alter table blobs.doc_obj drop constraint "$1" cascade; | |
11 | alter table blobs.doc_obj drop constraint if exists "$1" cascade; | |
13 | 12 | -- medium age: |
14 | alter table blobs.doc_obj drop constraint doc_obj_doc_id_fkey cascade; | |
13 | alter table blobs.doc_obj drop constraint if exists doc_obj_doc_id_fkey cascade; | |
15 | 14 | -- current: |
16 | alter table blobs.doc_obj drop constraint doc_obj_fk_doc_fkey cascade; | |
17 | \set ON_ERROR_STOP 1 | |
15 | alter table blobs.doc_obj drop constraint if exists doc_obj_fk_doc_fkey cascade; | |
18 | 16 | |
19 | 17 | -- recreate: |
20 | 18 | alter table blobs.doc_obj |
5 | 5 | -- |
6 | 6 | -- ============================================================== |
7 | 7 | \set ON_ERROR_STOP 1 |
8 | set check_function_bodies to on; | |
9 | ||
10 | --set default_transaction_read_only to off; | |
11 | 8 | |
12 | 9 | -- -------------------------------------------------------------- |
13 | 10 | \unset ON_ERROR_STOP |
14 | 14 | |
15 | 15 | \unset ON_ERROR_STOP |
16 | 16 | |
17 | set client_encoding 'utf8'; | |
17 | set client_encoding to 'utf8'; | |
18 | 18 | |
19 | 19 | select i18n.upd_tx(quote_literal(E'fr'), quote_literal(E'British Columbia'), quote_literal(E'Colombie-Britannique')); |
20 | 20 | select i18n.upd_tx(quote_literal(E'fr'), quote_literal(E'New Brunswick'), quote_literal(E'Nouveau-Brunswick')); |
14 | 14 | |
15 | 15 | \unset ON_ERROR_STOP |
16 | 16 | |
17 | set client_encoding 'utf8'; | |
17 | set client_encoding to 'utf8'; | |
18 | 18 | |
19 | 19 | select i18n.upd_tx(quote_literal(E'ru'), quote_literal(E'cause of death'), quote_literal(E'причина смерти')); |
20 | 20 | select i18n.upd_tx(quote_literal(E'ru_RU'), quote_literal(E'Abakan'), quote_literal(E'Абакан')); |
128 | 128 | (select fk_patient from clin.encounter where pk = c_si.fk_encounter) |
129 | 129 | as pk_patient, |
130 | 130 | c_si.soap_cat, |
131 | null | |
131 | null::text | |
132 | 132 | as brand, |
133 | 133 | c_si.preparation, |
134 | 134 | r_cs.description |
138 | 138 | as unit, |
139 | 139 | r_cs.atc_code |
140 | 140 | as atc_substance, |
141 | null | |
141 | null::text | |
142 | 142 | as atc_brand, |
143 | null | |
143 | null::text | |
144 | 144 | as external_code_brand, |
145 | null | |
145 | null::text | |
146 | 146 | as external_code_type_brand, |
147 | 147 | |
148 | 148 | c_si.clin_when |
160 | 160 | as health_issue, |
161 | 161 | c_si.narrative |
162 | 162 | as notes, |
163 | null | |
163 | null::boolean | |
164 | 164 | as fake_brand, |
165 | 165 | -- currently active ? |
166 | 166 | case |
186 | 186 | else null |
187 | 187 | end::boolean |
188 | 188 | as seems_inactive, |
189 | null | |
189 | null::integer | |
190 | 190 | as pk_brand, |
191 | null | |
191 | null::integer | |
192 | 192 | as pk_data_source, |
193 | 193 | r_cs.pk |
194 | 194 | as pk_substance, |
195 | null | |
195 | null::integer | |
196 | 196 | as pk_drug_component, |
197 | 197 | c_si.fk_encounter |
198 | 198 | as pk_encounter, |
138 | 138 | (select fk_patient from clin.encounter where pk = c_si.fk_encounter) |
139 | 139 | as pk_patient, |
140 | 140 | c_si.soap_cat, |
141 | null | |
141 | null::text | |
142 | 142 | as brand, |
143 | 143 | c_si.preparation, |
144 | 144 | r_cs.description |
148 | 148 | as unit, |
149 | 149 | r_cs.atc_code |
150 | 150 | as atc_substance, |
151 | null | |
151 | null::text | |
152 | 152 | as atc_brand, |
153 | null | |
153 | null::text | |
154 | 154 | as external_code_brand, |
155 | null | |
155 | null::text | |
156 | 156 | as external_code_type_brand, |
157 | 157 | |
158 | 158 | -- uncertainty of start |
191 | 191 | as health_issue, |
192 | 192 | c_si.narrative |
193 | 193 | as notes, |
194 | null | |
194 | null::boolean | |
195 | 195 | as fake_brand, |
196 | 196 | -- currently active ? |
197 | 197 | case |
217 | 217 | else null |
218 | 218 | end::boolean |
219 | 219 | as seems_inactive, |
220 | null | |
220 | null::integer | |
221 | 221 | as pk_brand, |
222 | null | |
222 | null::integer | |
223 | 223 | as pk_data_source, |
224 | 224 | r_cs.pk |
225 | 225 | as pk_substance, |
226 | null | |
226 | null::integer | |
227 | 227 | as pk_drug_component, |
228 | 228 | c_si.fk_encounter |
229 | 229 | as pk_encounter, |
415 | 415 | ; |
416 | 416 | |
417 | 417 | -- -------------------------------------------------------------- |
418 | select gm.log_script_insertion('v21-clin-v_substance_intakes.sql', '21.0'); | |
418 | select gm.log_script_insertion('v21-clin-v_substance_intakes.sql', '21.15'); |
16 | 16 | ) VALUES ( |
17 | 17 | (select pk from dem.staff where db_user = 'any-doc'), |
18 | 18 | (select pk_type from dem.v_inbox_item_type where type = 'memo' and category = 'administrative'), |
19 | 'Release Notes for GNUmed 1.6.14 (database v21.14)', | |
20 | 'GNUmed 1.6.14 Release Notes: | |
19 | 'Release Notes for GNUmed 1.6.15 (database v21.15)', | |
20 | 'GNUmed 1.6.15 Release Notes: | |
21 | 21 | |
22 | 1.6.14 | |
22 | 1.6.15 | |
23 | 23 | |
24 | FIX: exception when having issues with calculating eGFR in medication plugin | |
25 | FIX: exception on disabling identity [thanks Marc] | |
26 | FIX: exception on adding archived documents to export area | |
27 | FIX: Orthanc DICOM patient ID modification | |
28 | FIX: faulty file drop target declarations | |
24 | FIX: exception on tooltipping patient overview inbox item | |
25 | FIX: exception in cursor/connection state logging w/ older psycopg2s | |
26 | FIX: exception on import error inside portable app | |
29 | 27 | |
30 | IMPROVED: saving of export area items | |
31 | IMPROVED: patient display in provider inbox | |
32 | IMPROVED: copy document to export area from document plugin | |
33 | IMPROVED: Orthanc modification dialog title | |
34 | IMPROVED: imported documents deletion confirmation | |
35 | IMPROVED: patient media metadata | |
28 | IMPROVED: use Dicom[RequestingPhysician] if available | |
29 | IMPROVED: user visible rendering of raw DICOM strings | |
30 | IMPROVED: baptize SCRAM for PG passwords in settings check | |
31 | ||
32 | 21.15 | |
33 | ||
34 | FIX: handle SQL_INHERITANCE in a way compatible with PG10 | |
35 | FIX: untyped UNIONs not tolerated by PG10 anymore | |
36 | FIX: RETURNS UNKNOWN functions not tolerated by PG10 anymore | |
37 | ||
38 | IMPROVED: script to adjust db settings | |
36 | 39 | '); |
37 | 40 | |
38 | 41 | -- -------------------------------------------------------------- |
39 | select gm.log_script_insertion('v21-release_notes-dynamic.sql', '21.14'); | |
42 | select gm.log_script_insertion('v21-release_notes-dynamic.sql', '21.15'); |
0 | -- GNUmed auditing functionality | |
1 | -- =================================================================== | |
2 | -- license: GPL v2 or later | |
3 | -- author: Karsten Hilbert | |
4 | ||
5 | -- =================================================================== | |
6 | -- force terminate + exit(3) on errors if non-interactive | |
7 | \set ON_ERROR_STOP 1 | |
8 | ||
9 | -- -------------------------------------------------------------- | |
10 | create or replace function audit.add_table_for_audit(name, name) | |
11 | returns boolean | |
12 | language 'plpgsql' | |
13 | security definer | |
14 | as ' | |
15 | DECLARE | |
16 | _relnamespace alias for $1; | |
17 | _relname ALIAS FOR $2; | |
18 | dummy RECORD; | |
19 | tmp text; | |
20 | BEGIN | |
21 | -- does table exist ? | |
22 | select relname into dummy from pg_class where | |
23 | relname = _relname and | |
24 | relnamespace = (select oid from pg_namespace where nspname = _relnamespace) | |
25 | ; | |
26 | if not found then | |
27 | tmp := _relnamespace || ''.'' || _relname; | |
28 | raise exception ''audit.add_table_for_audit: Table [%] does not exist.'', tmp; | |
29 | return false; | |
30 | end if; | |
31 | -- already queued for auditing ? | |
32 | select 1 into dummy from audit.audited_tables where table_name = _relname and schema = _relnamespace; | |
33 | if found then | |
34 | return true; | |
35 | end if; | |
36 | -- add definition | |
37 | insert into audit.audited_tables ( | |
38 | schema, table_name | |
39 | ) values ( | |
40 | _relnamespace, _relname | |
41 | ); | |
42 | return true; | |
43 | END;'; | |
44 | ||
45 | comment on function audit.add_table_for_audit (name, name) is | |
46 | 'sanity-checking convenience function for marking tables for auditing'; | |
47 | ||
48 | ||
49 | create or replace function audit.add_table_for_audit(name) | |
50 | returns boolean | |
51 | language SQL | |
52 | security definer | |
53 | as ' | |
54 | select audit.add_table_for_audit(''public'', $1);'; | |
55 | ||
56 | comment on function audit.add_table_for_audit(name) is | |
57 | 'sanity-checking convenience function for marking tables | |
58 | for auditing, schema is always "public"'; | |
59 | ||
60 | -- -------------------------------------------------------------- | |
61 | select gm.log_script_insertion('v21-audit-add_table_for_audit-fixup.sql', '21.15'); |
0 | -- ============================================================== | |
1 | -- GNUmed database schema change script | |
2 | -- | |
3 | -- License: GPL v2 or later | |
4 | -- Author: karsten.hilbert@gmx.net | |
5 | -- | |
6 | -- ============================================================== | |
7 | \set ON_ERROR_STOP 1 | |
8 | --set default_transaction_read_only to off; | |
9 | ||
10 | -- -------------------------------------------------------------- | |
11 | drop view if exists clin.v_nonbrand_intakes cascade; | |
12 | ||
13 | create view clin.v_nonbrand_intakes as | |
14 | select | |
15 | c_si.pk | |
16 | as pk_substance_intake, | |
17 | (select fk_patient from clin.encounter where pk = c_si.fk_encounter) | |
18 | as pk_patient, | |
19 | c_si.soap_cat, | |
20 | null::text | |
21 | as brand, | |
22 | c_si.preparation, | |
23 | r_cs.description | |
24 | as substance, | |
25 | r_cs.amount, | |
26 | r_cs.unit | |
27 | as unit, | |
28 | r_cs.atc_code | |
29 | as atc_substance, | |
30 | null::text | |
31 | as atc_brand, | |
32 | null::text | |
33 | as external_code_brand, | |
34 | null::text | |
35 | as external_code_type_brand, | |
36 | ||
37 | -- uncertainty of start | |
38 | case | |
39 | when c_si.comment_on_start = '?' then null | |
40 | else c_si.clin_when | |
41 | end::timestamp with time zone | |
42 | as started, | |
43 | c_si.comment_on_start, | |
44 | case | |
45 | when c_si.comment_on_start = '?' then true | |
46 | else false | |
47 | end::boolean | |
48 | as start_is_unknown, | |
49 | case | |
50 | when c_si.comment_on_start is null then false | |
51 | else true | |
52 | end::boolean | |
53 | as start_is_approximate, | |
54 | c_si.intake_is_approved_of, | |
55 | c_si.harmful_use_type, | |
56 | CASE | |
57 | WHEN c_si.harmful_use_type IS NULL THEN NULL::timestamp with time zone | |
58 | ELSE c_enc.started | |
59 | END | |
60 | AS last_checked_when, | |
61 | c_si.schedule, | |
62 | c_si.duration, | |
63 | c_si.discontinued, | |
64 | c_si.discontinue_reason, | |
65 | c_si.is_long_term, | |
66 | c_si.aim, | |
67 | cep.description | |
68 | as episode, | |
69 | c_hi.description | |
70 | as health_issue, | |
71 | c_si.narrative | |
72 | as notes, | |
73 | null::boolean | |
74 | as fake_brand, | |
75 | -- currently active ? | |
76 | case | |
77 | -- no discontinue date documented so assumed active | |
78 | when c_si.discontinued is null then true | |
79 | -- else not active (constraints guarantee that .discontinued > clin_when and < current_timestamp) | |
80 | else false | |
81 | end::boolean | |
82 | as is_currently_active, | |
83 | -- seems inactive ? | |
84 | case | |
85 | when c_si.discontinued is not null then true | |
86 | -- from here on discontinued is NULL | |
87 | when c_si.clin_when is null then | |
88 | case | |
89 | when c_si.is_long_term is true then false | |
90 | else null | |
91 | end | |
92 | -- from here clin_when is NOT null | |
93 | when (c_si.clin_when > current_timestamp) is true then true | |
94 | when ((c_si.clin_when + c_si.duration) < current_timestamp) is true then true | |
95 | when ((c_si.clin_when + c_si.duration) > current_timestamp) is true then false | |
96 | else null | |
97 | end::boolean | |
98 | as seems_inactive, | |
99 | null::integer | |
100 | as pk_brand, | |
101 | null::integer | |
102 | as pk_data_source, | |
103 | r_cs.pk | |
104 | as pk_substance, | |
105 | null::integer | |
106 | as pk_drug_component, | |
107 | c_si.fk_encounter | |
108 | as pk_encounter, | |
109 | c_si.fk_episode | |
110 | as pk_episode, | |
111 | cep.fk_health_issue | |
112 | as pk_health_issue, | |
113 | c_si.modified_when, | |
114 | c_si.modified_by, | |
115 | c_si.row_version | |
116 | as row_version, | |
117 | c_si.xmin | |
118 | as xmin_substance_intake | |
119 | from | |
120 | clin.substance_intake c_si | |
121 | inner join ref.consumable_substance r_cs on (c_si.fk_substance = r_cs.pk) | |
122 | left join clin.episode cep on (c_si.fk_episode = cep.pk) | |
123 | left join clin.health_issue c_hi on (c_hi.pk = cep.fk_health_issue) | |
124 | left join clin.encounter c_enc on (c_si.fk_encounter = c_enc.pk) | |
125 | where | |
126 | c_si.fk_drug_component IS NULL | |
127 | ; | |
128 | ||
129 | grant select on clin.v_nonbrand_intakes to group "gm-doctors"; | |
130 | ||
131 | -- -------------------------------------------------------------- | |
132 | drop view if exists clin.v_substance_intakes cascade; | |
133 | ||
134 | create view clin.v_substance_intakes as | |
135 | select * from clin.v_brand_intakes | |
136 | union all | |
137 | select * from clin.v_nonbrand_intakes | |
138 | ; | |
139 | ||
140 | grant select on clin.v_substance_intakes to group "gm-doctors"; | |
141 | ||
142 | -- -------------------------------------------------------------- | |
143 | select gm.log_script_insertion('v21-clin-v_substance_intakes-fixup.sql', '21.15'); |
0 | -- ============================================================== | |
1 | -- GNUmed database schema change script | |
2 | -- | |
3 | -- License: GPL v2 or later | |
4 | -- Author: karsten.hilbert@gmx.net | |
5 | -- | |
6 | -- ============================================================== | |
7 | \set ON_ERROR_STOP 1 | |
8 | --set default_transaction_read_only to off; | |
9 | ||
10 | -- -------------------------------------------------------------- | |
11 | select 'no-op SELECT such that the bootstrapper is run and forces SQL_INHERITANCE back to DEFAULT if on PG <10'; | |
12 | ||
13 | -- -------------------------------------------------------------- | |
14 | select gm.log_script_insertion('v21-db-sql_inheritance-fixup.sql', '21.15'); |
0 | -- ====================================================== | |
1 | -- GNUmed fixed string internationalisation (SQL gettext) | |
2 | -- ====================================================== | |
3 | -- force terminate + exit(3) on errors if non-interactive | |
4 | \set ON_ERROR_STOP 1 | |
5 | ||
6 | -- ============================================= | |
7 | create or replace function i18n.set_curr_lang(text) | |
8 | returns boolean | |
9 | language 'plpgsql' | |
10 | security definer | |
11 | as ' | |
12 | DECLARE | |
13 | _lang ALIAS FOR $1; | |
14 | BEGIN | |
15 | if exists(select pk from i18n.translations where lang = _lang) then | |
16 | delete from i18n.curr_lang where user = CURRENT_USER; | |
17 | insert into i18n.curr_lang (lang) values (_lang); | |
18 | return true; | |
19 | end if; | |
20 | raise notice ''Cannot set current language to [%]. No translations available.'', _lang; | |
21 | return false; | |
22 | END; | |
23 | '; | |
24 | ||
25 | comment on function i18n.set_curr_lang(text) is | |
26 | 'set preferred language: | |
27 | - for "current user" | |
28 | - only if translations for this language are available'; | |
29 | ||
30 | -- ============================================= | |
31 | create or replace function i18n.force_curr_lang(text) | |
32 | returns boolean | |
33 | language 'plpgsql' | |
34 | security definer | |
35 | as ' | |
36 | DECLARE | |
37 | _lang ALIAS FOR $1; | |
38 | BEGIN | |
39 | raise notice ''Forcing current language to [%] without checking for translations..'', _lang; | |
40 | delete from i18n.curr_lang where user = CURRENT_USER; | |
41 | insert into i18n.curr_lang(lang) values (_lang); | |
42 | return 1; | |
43 | END; | |
44 | '; | |
45 | ||
46 | comment on function i18n.force_curr_lang(text) is | |
47 | 'force preferred language to some language: | |
48 | - for "current user"'; | |
49 | ||
50 | -- -------------------------------------------------------------- | |
51 | select gm.log_script_insertion('v21-i18n-lang_funcs-fixup.sql', '21.15'); |