[bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
--- a/server/migractions.py Fri Apr 23 17:54:34 2010 +0200
+++ b/server/migractions.py Fri Apr 23 17:55:46 2010 +0200
@@ -1179,6 +1179,23 @@
return session
return self.cnx.request()
+ def cmd_storage_changed(self, etype, attribute):
+ """migrate entities to a custom storage. The new storage is expected to
+ be set, it will be temporarily removed for the migration.
+ """
+ from logilab.common.shellutils import ProgressBar
+ source = self.repo.system_source
+ storage = source.storage(etype, attribute)
+ source.unset_storage(etype, attribute)
+ rset = self.rqlexec('Any X,A WHERE X is %s, X %s A'
+ % (etype, attribute), ask_confirm=False)
+ pb = ProgressBar(len(rset))
+ for entity in rset.entities():
+ storage.migrate_entity(entity, attribute)
+ pb.update()
+ print
+ source.set_storage(etype, attribute, storage)
+
def cmd_create_entity(self, etype, commit=False, **kwargs):
"""add a new entity of the given type"""
entity = self._cw.create_entity(etype, **kwargs)
--- a/server/sources/native.py Fri Apr 23 17:54:34 2010 +0200
+++ b/server/sources/native.py Fri Apr 23 17:55:46 2010 +0200
@@ -328,6 +328,14 @@
del self._storages[etype]
self.unmap_attribute(etype, attr)
+ def storage(self, etype, attr):
+ """return the storage for the given entity type / attribute
+ """
+ try:
+ return self._storages[etype][attr]
+ except KeyError:
+ raise Exception('no custom storage set for %s.%s' % (etype, attr))
+
# ISource interface #######################################################
def compile_rql(self, rql, sols):
--- a/server/sources/storages.py Fri Apr 23 17:54:34 2010 +0200
+++ b/server/sources/storages.py Fri Apr 23 17:55:46 2010 +0200
@@ -50,6 +50,9 @@
def entity_deleted(self, entity, attr):
"""an entity using this storage for attr has been deleted"""
raise NotImplementedError()
+ def migrate_entity(self, entity, attribute):
+ """migrate an entity attribute to the storage"""
+ raise NotImplementedError()
# TODO
# * make it configurable without code
@@ -150,6 +153,16 @@
return sysource._process_value(rawvalue, cu.description[0],
binarywrap=str)
+ def migrate_entity(self, entity, attribute):
+ """migrate an entity attribute to the storage"""
+ entity.edited_attributes = set()
+ self.entity_added(entity, attribute)
+ session = entity._cw
+ source = session.repo.system_source
+ attrs = source.preprocess_entity(entity)
+ sql = source.sqlgen.update('cw_' + entity.__regid__, attrs,
+ ['cw_eid'])
+ source.doexec(session, sql, attrs)
class AddFileOp(hook.Operation):