Mercurial > p > roundup > code
comparison roundup/backends/back_postgresql.py @ 2075:b1704ba7be41
make mysql / postgresql work again. beginnings of otk/session store in rdbmses
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Fri, 12 Mar 2004 04:09:00 +0000 |
| parents | 261c2e6ceb1e |
| children | 3e0961d6d44d |
comparison
equal
deleted
inserted
replaced
| 2073:261c2e6ceb1e | 2075:b1704ba7be41 |
|---|---|
| 7 # | 7 # |
| 8 '''Postgresql backend via psycopg for Roundup.''' | 8 '''Postgresql backend via psycopg for Roundup.''' |
| 9 __docformat__ = 'restructuredtext' | 9 __docformat__ = 'restructuredtext' |
| 10 | 10 |
| 11 | 11 |
| 12 import os, shutil, popen2, time | |
| 13 import psycopg | |
| 14 | |
| 12 from roundup import hyperdb, date | 15 from roundup import hyperdb, date |
| 13 from roundup.backends import rdbms_common | 16 from roundup.backends import rdbms_common |
| 14 import psycopg | 17 |
| 15 import os, shutil, popen2 | 18 def db_create(config): |
| 19 """Clear all database contents and drop database itself""" | |
| 20 if __debug__: | |
| 21 print >> hyperdb.DEBUG, '+++ create database +++' | |
| 22 name = config.POSTGRESQL_DATABASE['database'] | |
| 23 n = 0 | |
| 24 while n < 10: | |
| 25 cout,cin = popen2.popen4('createdb %s'%name) | |
| 26 cin.close() | |
| 27 response = cout.read().split('\n')[0] | |
| 28 if response.find('FATAL') != -1: | |
| 29 raise RuntimeError, response | |
| 30 elif response.find('ERROR') != -1: | |
| 31 if not response.find('is being accessed by other users') != -1: | |
| 32 raise RuntimeError, response | |
| 33 if __debug__: | |
| 34 print >> hyperdb.DEBUG, '+++ SLEEPING +++' | |
| 35 time.sleep(1) | |
| 36 n += 1 | |
| 37 continue | |
| 38 return | |
| 39 raise RuntimeError, '10 attempts to create database failed' | |
| 40 | |
| 41 def db_nuke(config, fail_ok=0): | |
| 42 """Clear all database contents and drop database itself""" | |
| 43 if __debug__: | |
| 44 print >> hyperdb.DEBUG, '+++ nuke database +++' | |
| 45 name = config.POSTGRESQL_DATABASE['database'] | |
| 46 n = 0 | |
| 47 if os.path.exists(config.DATABASE): | |
| 48 shutil.rmtree(config.DATABASE) | |
| 49 while n < 10: | |
| 50 cout,cin = popen2.popen4('dropdb %s'%name) | |
| 51 cin.close() | |
| 52 response = cout.read().split('\n')[0] | |
| 53 if response.endswith('does not exist') and fail_ok: | |
| 54 return | |
| 55 elif response.find('FATAL') != -1: | |
| 56 raise RuntimeError, response | |
| 57 elif response.find('ERROR') != -1: | |
| 58 if not response.find('is being accessed by other users') != -1: | |
| 59 raise RuntimeError, response | |
| 60 if __debug__: | |
| 61 print >> hyperdb.DEBUG, '+++ SLEEPING +++' | |
| 62 time.sleep(1) | |
| 63 n += 1 | |
| 64 continue | |
| 65 return | |
| 66 raise RuntimeError, '10 attempts to nuke database failed' | |
| 67 | |
| 68 def db_exists(config): | |
| 69 """Check if database already exists""" | |
| 70 db = getattr(config, 'POSTGRESQL_DATABASE') | |
| 71 try: | |
| 72 conn = psycopg.connect(**db) | |
| 73 conn.close() | |
| 74 if __debug__: | |
| 75 print >> hyperdb.DEBUG, '+++ database exists +++' | |
| 76 return 1 | |
| 77 except: | |
| 78 if __debug__: | |
| 79 print >> hyperdb.DEBUG, '+++ no database +++' | |
| 80 return 0 | |
| 16 | 81 |
| 17 class Database(rdbms_common.Database): | 82 class Database(rdbms_common.Database): |
| 18 arg = '%s' | 83 arg = '%s' |
| 19 | 84 |
| 20 def sql_open_connection(self): | 85 def sql_open_connection(self): |
| 86 if not db_exists(self.config): | |
| 87 db_create(self.config) | |
| 88 | |
| 89 if __debug__: | |
| 90 print >>hyperdb.DEBUG, '+++ open database connection +++' | |
| 91 | |
| 21 db = getattr(self.config, 'POSTGRESQL_DATABASE') | 92 db = getattr(self.config, 'POSTGRESQL_DATABASE') |
| 22 try: | 93 try: |
| 23 self.conn = psycopg.connect(**db) | 94 self.conn = psycopg.connect(**db) |
| 24 except psycopg.OperationalError, message: | 95 except psycopg.OperationalError, message: |
| 25 raise hyperdb.DatabaseError, message | 96 raise hyperdb.DatabaseError, message |
| 28 | 99 |
| 29 try: | 100 try: |
| 30 self.load_dbschema() | 101 self.load_dbschema() |
| 31 except: | 102 except: |
| 32 self.rollback() | 103 self.rollback() |
| 33 self.database_schema = {} | 104 self.init_dbschema() |
| 34 self.sql("CREATE TABLE schema (schema TEXT)") | 105 self.sql("CREATE TABLE schema (schema TEXT)") |
| 35 self.sql("CREATE TABLE ids (name VARCHAR(255), num INT4)") | 106 self.sql("CREATE TABLE ids (name VARCHAR(255), num INT4)") |
| 36 self.sql("CREATE INDEX ids_name_idx ON ids(name)") | 107 self.sql("CREATE INDEX ids_name_idx ON ids(name)") |
| 37 self.create_version_2_tables() | 108 self.create_version_2_tables() |
| 38 | 109 |
| 39 def create_version_2_tables(self): | 110 def create_version_2_tables(self): |
| 40 self.cursor.execute('CREATE TABLE otks (key VARCHAR(255), ' | 111 self.cursor.execute('CREATE TABLE otks (otk_key VARCHAR(255), ' |
| 41 'value VARCHAR(255), __time NUMERIC)') | 112 'otk_value VARCHAR(255), otk_time FLOAT(20))') |
| 42 self.cursor.execute('CREATE INDEX otks_key_idx ON otks(key)') | 113 self.cursor.execute('CREATE INDEX otks_key_idx ON otks(otk_key)') |
| 43 self.cursor.execute('CREATE TABLE sessions (key VARCHAR(255), ' | 114 self.cursor.execute('CREATE TABLE sessions (s_key VARCHAR(255), ' |
| 44 'last_use NUMERIC, user VARCHAR(255))') | 115 's_last_use FLOAT(20), s_user VARCHAR(255))') |
| 45 self.cursor.execute('CREATE INDEX sessions_key_idx ON sessions(key)') | 116 self.cursor.execute('CREATE INDEX sessions_key_idx ON sessions(s_key)') |
| 46 | 117 |
| 47 def __repr__(self): | 118 def __repr__(self): |
| 48 return '<roundpsycopgsql 0x%x>' % id(self) | 119 return '<roundpsycopgsql 0x%x>' % id(self) |
| 49 | 120 |
| 50 def sql_stringquote(self, value): | 121 def sql_stringquote(self, value): |
