devtools/fill.py
branchstable
changeset 3742 20f429eb5f46
parent 3712 4b8d7838d74d
child 3747 9165bd634f90
--- a/devtools/fill.py	Mon Oct 19 20:26:22 2009 +0200
+++ b/devtools/fill.py	Mon Oct 19 20:33:30 2009 +0200
@@ -308,13 +308,16 @@
 
 
 
-def select(constraints, cursor, selectvar='O'):
+def select(constraints, cursor, selectvar='O', objtype=None):
     """returns list of eids matching <constraints>
 
     <selectvar> should be either 'O' or 'S' to match schema definitions
     """
     try:
-        rset = cursor.execute('Any %s WHERE %s' % (selectvar, constraints))
+        rql = 'Any %s WHERE %s' % (selectvar, constraints)
+        if objtype:
+            rql += ', %s is %s' % (selectvar, objtype)
+        rset = cursor.execute(rql)
     except:
         print "could restrict eid_list with given constraints (%r)" % constraints
         return []
@@ -335,6 +338,14 @@
     gen = RelationsQueriesGenerator(schema, cursor, existingrels)
     return gen.compute_queries(edict, ignored_relations)
 
+def composite_relation(rschema):
+    for obj in rschema.objects():
+        if obj.objrproperty(rschema, 'composite') == 'subject':
+            return True
+    for obj in rschema.subjects():
+        if obj.subjrproperty(rschema, 'composite') == 'object':
+            return True
+    return False
 
 class RelationsQueriesGenerator(object):
     rql_tmpl = 'SET S %s O WHERE S eid %%(subjeid)s, O eid %%(objeid)s'
@@ -346,8 +357,9 @@
     def compute_queries(self, edict, ignored_relations):
         queries = []
         #   1/ skip final relations and explictly ignored relations
-        rels = [rschema for rschema in self.schema.relations()
-                if not (rschema.final or rschema in ignored_relations)]
+        rels = sorted([rschema for rschema in self.schema.relations()
+                       if not (rschema.final or rschema in ignored_relations)],
+                      key=lambda x:not composite_relation(x))
         # for each relation
         #   2/ take each possible couple (subj, obj)
         #   3/ analyze cardinality of relation
@@ -355,6 +367,7 @@
         #      b/ else insert N relations where N is the mininum
         #         of 20 and the number of existing targetable entities
         for rschema in rels:
+            print rschema
             sym = set()
             sedict = deepcopy(edict)
             oedict = deepcopy(edict)
@@ -366,7 +379,7 @@
                     continue
                 subjcard, objcard = rschema.rproperty(subj, obj, 'cardinality')
                 # process mandatory relations first
-                if subjcard in '1+' or objcard in '1+':
+                if subjcard in '1+' or objcard in '1+' or composite_relation(rschema):
                     queries += self.make_relation_queries(sedict, oedict,
                                                           rschema, subj, obj)
                 else:
@@ -399,10 +412,9 @@
             # restrict object eids if possible
             # XXX the attempt to restrict below in completely wrong
             # disabling it for now
-            objeids = select(restrictions, self.cursor)
+            objeids = select(restrictions, self.cursor, objtype=obj)
         else:
             objeids = oedict.get(obj, frozenset())
-##         objeids = oedict.get(obj, frozenset())
         if subjcard in '?1' or objcard in '?1':
             for subjeid, objeid in used:
                 if subjcard in '?1' and subjeid in subjeids:
@@ -461,8 +473,8 @@
 
 def check_card_satisfied(card, remaining, subj, rschema, obj):
     if card in '1+' and remaining:
-        raise Exception("can't satisfy cardinality %s for relation %s %s %s"
-                        % (card, subj, rschema, obj))
+        print "can't satisfy cardinality %s for relation %s %s %s" % (card, subj, rschema, obj)
+        
 
 def choose_eid(values, avoid):
     values = tuple(values)