@@ -18,51 +18,56 @@ def db_create(config):
1818 """Clear all database contents and drop database itself"""
1919 if __debug__ :
2020 print >> hyperdb .DEBUG , '+++ create database +++'
21- name = config .POSTGRESQL_DATABASE ['database' ]
22- n = 0
23- while n < 10 :
24- cout ,cin = popen2 .popen4 ('createdb %s' % name )
25- cin .close ()
26- response = cout .read ().split ('\n ' )[0 ]
27- if response .find ('FATAL' ) != - 1 :
28- raise RuntimeError , response
29- elif response .find ('ERROR' ) != - 1 :
30- if not response .find ('is being accessed by other users' ) != - 1 :
31- raise RuntimeError , response
32- if __debug__ :
33- print >> hyperdb .DEBUG , '+++ SLEEPING +++'
34- time .sleep (1 )
35- n += 1
36- continue
37- return
38- raise RuntimeError , '10 attempts to create database failed'
21+ command = 'CREATE DATABASE %s' % config .POSTGRESQL_DATABASE ['database' ]
22+ db_command (config , command )
3923
4024def db_nuke (config , fail_ok = 0 ):
4125 """Clear all database contents and drop database itself"""
4226 if __debug__ :
4327 print >> hyperdb .DEBUG , '+++ nuke database +++'
44- name = config .POSTGRESQL_DATABASE ['database' ]
45- n = 0
46- if os .path .exists (config .DATABASE ):
47- shutil .rmtree (config .DATABASE )
48- while n < 10 :
49- cout ,cin = popen2 .popen4 ('dropdb %s' % name )
50- cin .close ()
51- response = cout .read ().split ('\n ' )[0 ]
52- if response .endswith ('does not exist' ) and fail_ok :
53- return
54- elif response .find ('FATAL' ) != - 1 :
28+ command = 'DROP DATABASE %s' % config .POSTGRESQL_DATABASE ['database' ]
29+ db_command (config , command )
30+
31+ def db_command (config , command ):
32+ '''Perform some sort of database-level command. Retry 10 times if we
33+ fail by conflicting with another user.
34+ '''
35+ template1 = config .POSTGRESQL_DATABASE .copy ()
36+ template1 ['database' ] = 'template1'
37+
38+ try :
39+ conn = psycopg .connect (** template1 )
40+ except psycopg .OperationalError , message :
41+ raise hyperdb .DatabaseError , message
42+
43+ conn .set_isolation_level (0 )
44+ cursor = conn .cursor ()
45+ try :
46+ for n in range (10 ):
47+ if pg_command (cursor , command ):
48+ return
49+ finally :
50+ conn .close ()
51+ raise RuntimeError , '10 attempts to create database failed'
52+
53+ def pg_command (cursor , command ):
54+ '''Execute the postgresql command, which may be blocked by some other
55+ user connecting to the database, and return a true value if it succeeds.
56+ '''
57+ try :
58+ cursor .execute (command )
59+ except psycopg .ProgrammingError , err :
60+ response = str (err ).split ('\n ' )[0 ]
61+ if response .find ('FATAL' ) != - 1 :
5562 raise RuntimeError , response
5663 elif response .find ('ERROR' ) != - 1 :
57- if not response .find ('is being accessed by other users' ) ! = - 1 :
64+ if response .find ('is being accessed by other users' ) = = - 1 :
5865 raise RuntimeError , response
5966 if __debug__ :
6067 print >> hyperdb .DEBUG , '+++ SLEEPING +++'
6168 time .sleep (1 )
62- n += 1
63- continue
64- return
65- raise RuntimeError , '10 attempts to nuke database failed'
69+ return 0
70+ return 1
6671
6772def db_exists (config ):
6873 """Check if database already exists"""
0 commit comments