Mercurial > p > roundup > code
comparison roundup/backends/back_sqlite.py @ 2077:3e0961d6d44d
Added the "actor" property.
Metakit backend not done (still not confident I know how it's supposed
to work ;)
Currently it will come up as NULL in the RDBMS backends for older items.
The *dbm backends will look up the journal. I hope to remedy the former
before 0.7's release.
Fixed a bunch of migration issues in the rdbms backends while I was at it
(index changes for key prop changes) and simplified the class table update
code for RDBMSes that have "alter table" in their command set (ie. not
sqlite) ... migration from "version 1" to "version 2" still hasn't
actually been tested yet though.
| author | Richard Jones <richard@users.sourceforge.net> |
|---|---|
| date | Mon, 15 Mar 2004 05:50:20 +0000 |
| parents | b1704ba7be41 |
| children | c091cacdc505 |
comparison
equal
deleted
inserted
replaced
| 2076:2a4309450202 | 2077:3e0961d6d44d |
|---|---|
| 1 # $Id: back_sqlite.py,v 1.15 2004-03-12 04:08:59 richard Exp $ | 1 # $Id: back_sqlite.py,v 1.16 2004-03-15 05:50:20 richard Exp $ |
| 2 '''Implements a backend for SQLite. | 2 '''Implements a backend for SQLite. |
| 3 | 3 |
| 4 See https://pysqlite.sourceforge.net/ for pysqlite info | 4 See https://pysqlite.sourceforge.net/ for pysqlite info |
| 5 ''' | 5 ''' |
| 6 __docformat__ = 'restructuredtext' | 6 __docformat__ = 'restructuredtext' |
| 46 self.cursor.execute('create index otks_key_idx on otks(otk_key)') | 46 self.cursor.execute('create index otks_key_idx on otks(otk_key)') |
| 47 self.cursor.execute('create table sessions (s_key varchar, ' | 47 self.cursor.execute('create table sessions (s_key varchar, ' |
| 48 's_last_use varchar, s_user varchar)') | 48 's_last_use varchar, s_user varchar)') |
| 49 self.cursor.execute('create index sessions_key_idx on sessions(s_key)') | 49 self.cursor.execute('create index sessions_key_idx on sessions(s_key)') |
| 50 | 50 |
| 51 def add_actor_column(self): | |
| 52 # update existing tables to have the new actor column | |
| 53 tables = self.database_schema['tables'] | |
| 54 for classname, spec in self.classes.items(): | |
| 55 if tables.has_key(classname): | |
| 56 dbspec = tables[classname] | |
| 57 self.update_class(spec, dbspec, force=1, adding_actor=1) | |
| 58 | |
| 59 def update_class(self, spec, old_spec, force=0, adding_actor=0): | |
| 60 ''' Determine the differences between the current spec and the | |
| 61 database version of the spec, and update where necessary. | |
| 62 | |
| 63 If 'force' is true, update the database anyway. | |
| 64 | |
| 65 SQLite doesn't have ALTER TABLE, so we have to copy and | |
| 66 regenerate the tables with the new schema. | |
| 67 ''' | |
| 68 new_has = spec.properties.has_key | |
| 69 new_spec = spec.schema() | |
| 70 new_spec[1].sort() | |
| 71 old_spec[1].sort() | |
| 72 if not force and new_spec == old_spec: | |
| 73 # no changes | |
| 74 return 0 | |
| 75 | |
| 76 if __debug__: | |
| 77 print >>hyperdb.DEBUG, 'update_class FIRING' | |
| 78 | |
| 79 # detect multilinks that have been removed, and drop their table | |
| 80 old_has = {} | |
| 81 for name,prop in old_spec[1]: | |
| 82 old_has[name] = 1 | |
| 83 if new_has(name) or not isinstance(prop, hyperdb.Multilink): | |
| 84 continue | |
| 85 # it's a multilink, and it's been removed - drop the old | |
| 86 # table. First drop indexes. | |
| 87 self.drop_multilink_table_indexes(spec.classname, ml) | |
| 88 sql = 'drop table %s_%s'%(spec.classname, prop) | |
| 89 if __debug__: | |
| 90 print >>hyperdb.DEBUG, 'update_class', (self, sql) | |
| 91 self.cursor.execute(sql) | |
| 92 old_has = old_has.has_key | |
| 93 | |
| 94 # now figure how we populate the new table | |
| 95 if adding_actor: | |
| 96 fetch = ['_activity', '_creation', '_creator'] | |
| 97 else: | |
| 98 fetch = ['_actor', '_activity', '_creation', '_creator'] | |
| 99 properties = spec.getprops() | |
| 100 for propname,x in new_spec[1]: | |
| 101 prop = properties[propname] | |
| 102 if isinstance(prop, hyperdb.Multilink): | |
| 103 if force or not old_has(propname): | |
| 104 # we need to create the new table | |
| 105 self.create_multilink_table(spec, propname) | |
| 106 elif old_has(propname): | |
| 107 # we copy this col over from the old table | |
| 108 fetch.append('_'+propname) | |
| 109 | |
| 110 # select the data out of the old table | |
| 111 fetch.append('id') | |
| 112 fetch.append('__retired__') | |
| 113 fetchcols = ','.join(fetch) | |
| 114 cn = spec.classname | |
| 115 sql = 'select %s from _%s'%(fetchcols, cn) | |
| 116 if __debug__: | |
| 117 print >>hyperdb.DEBUG, 'update_class', (self, sql) | |
| 118 self.cursor.execute(sql) | |
| 119 olddata = self.cursor.fetchall() | |
| 120 | |
| 121 # TODO: update all the other index dropping code | |
| 122 self.drop_class_table_indexes(cn, old_spec[0]) | |
| 123 | |
| 124 # drop the old table | |
| 125 self.cursor.execute('drop table _%s'%cn) | |
| 126 | |
| 127 # create the new table | |
| 128 self.create_class_table(spec) | |
| 129 | |
| 130 if olddata: | |
| 131 # do the insert of the old data - the new columns will have | |
| 132 # NULL values | |
| 133 args = ','.join([self.arg for x in fetch]) | |
| 134 sql = 'insert into _%s (%s) values (%s)'%(cn, fetchcols, args) | |
| 135 if __debug__: | |
| 136 print >>hyperdb.DEBUG, 'update_class', (self, sql, olddata[0]) | |
| 137 for entry in olddata: | |
| 138 self.cursor.execute(sql, tuple(entry)) | |
| 139 | |
| 140 return 1 | |
| 141 | |
| 51 def sql_close(self): | 142 def sql_close(self): |
| 52 ''' Squash any error caused by us already having closed the | 143 ''' Squash any error caused by us already having closed the |
| 53 connection. | 144 connection. |
| 54 ''' | 145 ''' |
| 55 try: | 146 try: |
