Changeset 409 for elixir/trunk/elixir/ext/versioned.py
- Timestamp:
- 10/02/08 14:12:30 (4 years ago)
- Files:
-
- 1 modified
-
elixir/trunk/elixir/ext/versioned.py (modified) (12 diffs)
Legend:
- Unmodified
- Added
- Removed
-
elixir/trunk/elixir/ext/versioned.py
r406 r409 88 88 class VersionedMapperExtension(MapperExtension): 89 89 def before_insert(self, mapper, connection, instance): 90 instance.version = 1 91 instance.timestamp = datetime.now() 90 version_colname, timestamp_colname = \ 91 instance.__class__.__versioned_column_names__ 92 setattr(instance, version_colname, 1) 93 setattr(instance, timestamp_colname, datetime.now()) 92 94 return EXT_CONTINUE 93 95 … … 102 104 # data. 103 105 ignored = instance.__class__.__ignored_fields__ 106 version_colname, timestamp_colname = \ 107 instance.__class__.__versioned_column_names__ 104 108 for key in instance.table.c.keys(): 105 109 if key in ignored: … … 110 114 connection.execute( 111 115 instance.__class__.__history_table__.insert(), dict_values) 112 instance.version = instance.version + 1 113 instance.timestamp = datetime.now() 116 old_version = getattr(instance, version_colname) 117 setattr(instance, version_colname, old_version + 1) 118 setattr(instance, timestamp_colname, datetime.now()) 114 119 break 115 120 … … 132 137 class VersionedEntityBuilder(EntityBuilder): 133 138 134 def __init__(self, entity, ignore=[], check_concurrent=False): 139 def __init__(self, entity, ignore=None, check_concurrent=False, 140 column_names=None): 135 141 self.entity = entity 136 142 self.add_mapper_extension(versioned_mapper_extension) … … 140 146 141 147 # Changes in these fields will be ignored 142 ignore.extend(['version', 'timestamp']) 148 if column_names is None: 149 column_names = ['version', 'timestamp'] 150 entity.__versioned_column_names__ = column_names 151 if ignore is None: 152 ignore = [] 153 ignore.extend(column_names) 143 154 entity.__ignored_fields__ = ignore 144 155 145 156 def create_non_pk_cols(self): 146 157 # add a version column to the entity, along with a timestamp 147 self.add_table_column(Column('version', Integer)) 148 self.add_table_column(Column('timestamp', DateTime)) 158 version_colname, timestamp_colname = \ 159 self.entity.__versioned_column_names__ 160 #XXX: fail in case the columns already exist? 161 #col_names = [col.name for col in self.entity._descriptor.columns] 162 #if version_colname not in col_names: 163 self.add_table_column(Column(version_colname, Integer)) 164 #if timestamp_colname not in col_names: 165 self.add_table_column(Column(timestamp_colname, DateTime)) 149 166 150 167 # add a concurrent_version column to the entity, if required … … 155 172 def after_table(self): 156 173 entity = self.entity 174 version_colname, timestamp_colname = \ 175 entity.__versioned_column_names__ 157 176 158 177 # look for events … … 163 182 164 183 # create a history table for the entity 165 #TODO: fail more noticeably in case there is a version col 184 skipped_columns = [version_colname] 185 if self.check_concurrent: 186 skipped_columns.append('concurrent_version') 187 166 188 columns = [ 167 189 column.copy() for column in entity.table.c 168 if column.name not in ('version', 'concurrent_version')190 if column.name not in skipped_columns 169 191 ] 170 columns.append(Column( 'version', Integer, primary_key=True))192 columns.append(Column(version_colname, Integer, primary_key=True)) 171 193 table = Table(entity.table.name + '_history', entity.table.metadata, 172 194 *columns … … 183 205 mapper(Version, entity.__history_table__) 184 206 207 version_col = getattr(table.c, version_colname) 208 timestamp_col = getattr(table.c, timestamp_colname) 209 185 210 # attach utility methods and properties to the entity 186 211 def get_versions(self): 187 212 v = object_session(self).query(Version) \ 188 213 .filter(get_history_where(self)) \ 189 .order_by( Version.version) \214 .order_by(version_col) \ 190 215 .all() 191 216 # history contains all the previous records. … … 197 222 # if the passed in timestamp is older than our current version's 198 223 # time stamp, then the most recent version is our current version 199 if self.timestamp< dt:224 if getattr(self, timestamp_colname) < dt: 200 225 return self 201 226 … … 205 230 query = sess.query(Version) \ 206 231 .filter(and_(get_history_where(self), 207 Version.timestamp<= dt)) \208 .order_by(desc( Version.timestamp)).limit(1)232 timestamp_col <= dt)) \ 233 .order_by(desc(timestamp_col)).limit(1) 209 234 return query.first() 210 235 211 236 def revert_to(self, to_version): 212 237 if isinstance(to_version, Version): 213 to_version = to_version.version 214 215 hist = entity.__history_table__ 216 old_version = hist.select(and_( 238 to_version = getattr(to_version, version_colname) 239 240 old_version = table.select(and_( 217 241 get_history_where(self), 218 hist.c.version== to_version242 version_col == to_version 219 243 )).execute().fetchone() 220 244 … … 223 247 ) 224 248 225 hist.delete(and_(get_history_where(self),226 hist.c.version>= to_version)).execute()249 table.delete(and_(get_history_where(self), 250 version_col >= to_version)).execute() 227 251 self.expire() 228 252 for event in after_revert_events: … … 230 254 231 255 def revert(self): 232 assert self.version> 1233 self.revert_to( self.version- 1)256 assert getattr(self, version_colname) > 1 257 self.revert_to(getattr(self, version_colname) - 1) 234 258 235 259 def compare_with(self, version): 236 260 differences = {} 237 261 for column in self.table.c: 238 if column.name in ( 'version', 'concurrent_version'):262 if column.name in (version_colname, 'concurrent_version'): 239 263 continue 240 264 this = getattr(self, column.name)
