[bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
authorSylvain Thénault <sylvain.thenault@logilab.fr>
Fri, 23 Apr 2010 17:55:46 +0200
changeset 5397 cdbf823450aa
parent 5396 78d92a47a4e5
child 5398 b9e1abe1bdfe
[bfss] new storage_changed migration action to move an attribute to a custom storage. Closes #893941
server/migractions.py
server/sources/native.py
server/sources/storages.py
--- 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):