Skip to content

Commit d733a45

Browse files
author
Richard Jones
committed
postgresql backend altered to not use popen (thanks Georges Martin)
1 parent fa6390c commit d733a45

File tree

2 files changed

+40
-34
lines changed

2 files changed

+40
-34
lines changed

CHANGES.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ Fixed:
99
- removed Boolean from source to make py <2.3 happy (sf bug 938790)
1010
- fix nested scope bug in rdbms multilink sorting
1111
- re-seed the random number generator for each request
12+
- postgresql backend altered to not use popen (thanks Georges Martin)
1213

1314

1415
2004-04-18 0.7.0b3

roundup/backends/back_postgresql.py

Lines changed: 39 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4024
def 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

6772
def db_exists(config):
6873
"""Check if database already exists"""

0 commit comments

Comments
 (0)