99 an entity without a relation for some time |
99 an entity without a relation for some time |
100 |
100 |
101 this kind of behaviour has to be done in the repository so we don't have |
101 this kind of behaviour has to be done in the repository so we don't have |
102 hooks order hazardness |
102 hooks order hazardness |
103 """ |
103 """ |
104 # skip delete queries (only?) if session is an internal session. This is |
104 # XXX now that rql in migraction default to unsafe_execute we don't want to |
105 # hooks responsability to ensure they do not violate relation's cardinality |
105 # skip that anymore. Also we should imo rely on the orm to first fetch |
106 if session.is_super_session: |
106 # existing entity if any then delete it |
107 return |
107 #if session.is_super_session: |
108 ensure_card_respected(session.unsafe_execute, session, eidfrom, rtype, eidto) |
108 # return |
109 |
|
110 |
|
111 def ensure_card_respected(execute, session, eidfrom, rtype, eidto): |
|
112 card = session.schema_rproperty(rtype, eidfrom, eidto, 'cardinality') |
109 card = session.schema_rproperty(rtype, eidfrom, eidto, 'cardinality') |
113 # one may be tented to check for neweids but this may cause more than one |
110 # one may be tented to check for neweids but this may cause more than one |
114 # relation even with '1?' cardinality if thoses relations are added in the |
111 # relation even with '1?' cardinality if thoses relations are added in the |
115 # same transaction where the entity is being created. This never occurs from |
112 # same transaction where the entity is being created. This never occurs from |
116 # the web interface but may occurs during test or dbapi connection (though |
113 # the web interface but may occurs during test or dbapi connection (though |
117 # not expected for this). So: don't do it, we pretend to ensure repository |
114 # not expected for this). So: don't do it, we pretend to ensure repository |
118 # consistency. |
115 # consistency. |
119 if card[0] in '1?': |
116 if card[0] in '1?': |
120 rschema = session.repo.schema.rschema(rtype) |
117 rschema = session.repo.schema.rschema(rtype) |
121 if not rschema.inlined: |
118 if not rschema.inlined: # inlined relations will be implicitly deleted |
122 execute('DELETE X %s Y WHERE X eid %%(x)s,NOT Y eid %%(y)s' % rtype, |
119 session.unsafe_execute('DELETE X %s Y WHERE X eid %%(x)s, NOT Y eid %%(y)s' % rtype, |
123 {'x': eidfrom, 'y': eidto}, 'x') |
120 {'x': eidfrom, 'y': eidto}, 'x') |
124 if card[1] in '1?': |
121 if card[1] in '1?': |
125 execute('DELETE X %s Y WHERE NOT X eid %%(x)s, Y eid %%(y)s' % rtype, |
122 session.unsafe_execute('DELETE X %s Y WHERE NOT X eid %%(x)s, Y eid %%(y)s' % rtype, |
126 {'x': eidfrom, 'y': eidto}, 'y') |
123 {'x': eidfrom, 'y': eidto}, 'y') |
127 |
124 |
128 |
125 |
129 class Repository(object): |
126 class Repository(object): |
130 """a repository provides access to a set of persistent storages for |
127 """a repository provides access to a set of persistent storages for |
131 entities and relations |
128 entities and relations |