53 RepositoryError, typed_eid, onevent) |
53 RepositoryError, typed_eid, onevent) |
54 from cubicweb import cwvreg, schema, server |
54 from cubicweb import cwvreg, schema, server |
55 from cubicweb.server import utils, hook, pool, querier, sources |
55 from cubicweb.server import utils, hook, pool, querier, sources |
56 from cubicweb.server.session import Session, InternalSession, InternalManager, \ |
56 from cubicweb.server.session import Session, InternalSession, InternalManager, \ |
57 security_enabled |
57 security_enabled |
|
58 from cubicweb.server.ssplanner import EditedEntity |
58 |
59 |
59 |
60 |
60 def del_existing_rel_if_needed(session, eidfrom, rtype, eidto): |
61 def del_existing_rel_if_needed(session, eidfrom, rtype, eidto): |
61 """delete existing relation when adding a new one if card is 1 or ? |
62 """delete existing relation when adding a new one if card is 1 or ? |
62 |
63 |
534 if isinstance(password, unicode): |
535 if isinstance(password, unicode): |
535 # password should *always* be utf8 encoded |
536 # password should *always* be utf8 encoded |
536 password = password.encode('UTF8') |
537 password = password.encode('UTF8') |
537 kwargs['login'] = login |
538 kwargs['login'] = login |
538 kwargs['upassword'] = password |
539 kwargs['upassword'] = password |
539 user.update(kwargs) |
540 self.glob_add_entity(session, EditedEntity(user, **kwargs)) |
540 self.glob_add_entity(session, user) |
|
541 session.execute('SET X in_group G WHERE X eid %(x)s, G name "users"', |
541 session.execute('SET X in_group G WHERE X eid %(x)s, G name "users"', |
542 {'x': user.eid}) |
542 {'x': user.eid}) |
543 if email or '@' in login: |
543 if email or '@' in login: |
544 d = {'login': login, 'email': email or login} |
544 d = {'login': login, 'email': email or login} |
545 if session.execute('EmailAddress X WHERE X address %(email)s', d, |
545 if session.execute('EmailAddress X WHERE X address %(email)s', d, |
938 try: |
938 try: |
939 eid = self.system_source.create_eid(session) |
939 eid = self.system_source.create_eid(session) |
940 self._extid_cache[cachekey] = eid |
940 self._extid_cache[cachekey] = eid |
941 self._type_source_cache[eid] = (etype, source.uri, extid) |
941 self._type_source_cache[eid] = (etype, source.uri, extid) |
942 entity = source.before_entity_insertion(session, extid, etype, eid) |
942 entity = source.before_entity_insertion(session, extid, etype, eid) |
943 entity.edited_attributes = set(entity.cw_attr_cache) |
|
944 if source.should_call_hooks: |
943 if source.should_call_hooks: |
945 self.hm.call_hooks('before_add_entity', session, entity=entity) |
944 self.hm.call_hooks('before_add_entity', session, entity=entity) |
946 # XXX call add_info with complete=False ? |
945 # XXX call add_info with complete=False ? |
947 self.add_info(session, entity, source, extid) |
946 self.add_info(session, entity, source, extid) |
948 source.after_entity_insertion(session, extid, entity) |
947 source.after_entity_insertion(session, extid, entity) |
1041 extid = source.get_extid(entity) |
1040 extid = source.get_extid(entity) |
1042 self._extid_cache[(str(extid), suri)] = entity.eid |
1041 self._extid_cache[(str(extid), suri)] = entity.eid |
1043 self._type_source_cache[entity.eid] = (entity.__regid__, suri, extid) |
1042 self._type_source_cache[entity.eid] = (entity.__regid__, suri, extid) |
1044 return extid |
1043 return extid |
1045 |
1044 |
1046 def glob_add_entity(self, session, entity): |
1045 def glob_add_entity(self, session, edited): |
1047 """add an entity to the repository |
1046 """add an entity to the repository |
1048 |
1047 |
1049 the entity eid should originaly be None and a unique eid is assigned to |
1048 the entity eid should originaly be None and a unique eid is assigned to |
1050 the entity instance |
1049 the entity instance |
1051 """ |
1050 """ |
|
1051 entity = edited.entity |
|
1052 entity._cw_is_saved = False # entity has an eid but is not yet saved |
1052 # init edited_attributes before calling before_add_entity hooks |
1053 # init edited_attributes before calling before_add_entity hooks |
1053 entity._cw_is_saved = False # entity has an eid but is not yet saved |
1054 entity.cw_edited = edited |
1054 entity.edited_attributes = set(entity.cw_attr_cache) # XXX cw_edited_attributes |
|
1055 eschema = entity.e_schema |
1055 eschema = entity.e_schema |
1056 source = self.locate_etype_source(entity.__regid__) |
1056 source = self.locate_etype_source(entity.__regid__) |
1057 # allocate an eid to the entity before calling hooks |
1057 # allocate an eid to the entity before calling hooks |
1058 entity.eid = self.system_source.create_eid(session) |
1058 entity.eid = self.system_source.create_eid(session) |
1059 # set caches asap |
1059 # set caches asap |
1061 if server.DEBUG & server.DBG_REPO: |
1061 if server.DEBUG & server.DBG_REPO: |
1062 print 'ADD entity', self, entity.__regid__, entity.eid, entity.cw_attr_cache |
1062 print 'ADD entity', self, entity.__regid__, entity.eid, entity.cw_attr_cache |
1063 relations = [] |
1063 relations = [] |
1064 if source.should_call_hooks: |
1064 if source.should_call_hooks: |
1065 self.hm.call_hooks('before_add_entity', session, entity=entity) |
1065 self.hm.call_hooks('before_add_entity', session, entity=entity) |
1066 # XXX use entity.keys here since edited_attributes is not updated for |
1066 for attr in edited.iterkeys(): |
1067 # inline relations XXX not true, right? (see edited_attributes |
|
1068 # affectation above) |
|
1069 for attr in entity.cw_attr_cache.iterkeys(): |
|
1070 rschema = eschema.subjrels[attr] |
1067 rschema = eschema.subjrels[attr] |
1071 if not rschema.final: # inlined relation |
1068 if not rschema.final: # inlined relation |
1072 relations.append((attr, entity[attr])) |
1069 relations.append((attr, edited[attr])) |
1073 entity._cw_set_defaults() |
1070 edited.set_defaults() |
1074 if session.is_hook_category_activated('integrity'): |
1071 if session.is_hook_category_activated('integrity'): |
1075 entity._cw_check(creation=True) |
1072 edited.check(creation=True) |
1076 source.add_entity(session, entity) |
1073 source.add_entity(session, entity) |
|
1074 edited.saved = True |
1077 self.add_info(session, entity, source, extid, complete=False) |
1075 self.add_info(session, entity, source, extid, complete=False) |
1078 entity._cw_is_saved = True # entity has an eid and is saved |
1076 entity._cw_is_saved = True # entity has an eid and is saved |
1079 # prefill entity relation caches |
1077 # prefill entity relation caches |
1080 for rschema in eschema.subject_relations(): |
1078 for rschema in eschema.subject_relations(): |
1081 rtype = str(rschema) |
1079 rtype = str(rschema) |
1082 if rtype in schema.VIRTUAL_RTYPES: |
1080 if rtype in schema.VIRTUAL_RTYPES: |
1083 continue |
1081 continue |
1084 if rschema.final: |
1082 if rschema.final: |
1085 entity.setdefault(rtype, None) |
1083 entity.cw_attr_cache.setdefault(rtype, None) |
1086 else: |
1084 else: |
1087 entity.cw_set_relation_cache(rtype, 'subject', |
1085 entity.cw_set_relation_cache(rtype, 'subject', |
1088 session.empty_rset()) |
1086 session.empty_rset()) |
1089 for rschema in eschema.object_relations(): |
1087 for rschema in eschema.object_relations(): |
1090 rtype = str(rschema) |
1088 rtype = str(rschema) |
1103 eidfrom=entity.eid, rtype=attr, eidto=value) |
1101 eidfrom=entity.eid, rtype=attr, eidto=value) |
1104 self.hm.call_hooks('after_add_relation', session, |
1102 self.hm.call_hooks('after_add_relation', session, |
1105 eidfrom=entity.eid, rtype=attr, eidto=value) |
1103 eidfrom=entity.eid, rtype=attr, eidto=value) |
1106 return entity.eid |
1104 return entity.eid |
1107 |
1105 |
1108 def glob_update_entity(self, session, entity, edited_attributes): |
1106 def glob_update_entity(self, session, edited): |
1109 """replace an entity in the repository |
1107 """replace an entity in the repository |
1110 the type and the eid of an entity must not be changed |
1108 the type and the eid of an entity must not be changed |
1111 """ |
1109 """ |
|
1110 entity = edited.entity |
1112 if server.DEBUG & server.DBG_REPO: |
1111 if server.DEBUG & server.DBG_REPO: |
1113 print 'UPDATE entity', entity.__regid__, entity.eid, \ |
1112 print 'UPDATE entity', entity.__regid__, entity.eid, \ |
1114 entity.cw_attr_cache, edited_attributes |
1113 entity.cw_attr_cache, edited |
1115 hm = self.hm |
1114 hm = self.hm |
1116 eschema = entity.e_schema |
1115 eschema = entity.e_schema |
1117 session.set_entity_cache(entity) |
1116 session.set_entity_cache(entity) |
1118 orig_edited_attributes = getattr(entity, 'edited_attributes', None) |
1117 orig_edited = getattr(entity, 'cw_edited', None) |
1119 entity.edited_attributes = edited_attributes |
1118 entity.cw_edited = edited |
1120 try: |
1119 try: |
1121 only_inline_rels, need_fti_update = True, False |
1120 only_inline_rels, need_fti_update = True, False |
1122 relations = [] |
1121 relations = [] |
1123 source = self.source_from_eid(entity.eid, session) |
1122 source = self.source_from_eid(entity.eid, session) |
1124 for attr in list(edited_attributes): |
1123 for attr in list(edited): |
1125 if attr == 'eid': |
1124 if attr == 'eid': |
1126 continue |
1125 continue |
1127 rschema = eschema.subjrels[attr] |
1126 rschema = eschema.subjrels[attr] |
1128 if rschema.final: |
1127 if rschema.final: |
1129 if getattr(eschema.rdef(attr), 'fulltextindexed', False): |
1128 if getattr(eschema.rdef(attr), 'fulltextindexed', False): |
1132 else: |
1131 else: |
1133 # inlined relation |
1132 # inlined relation |
1134 previous_value = entity.related(attr) or None |
1133 previous_value = entity.related(attr) or None |
1135 if previous_value is not None: |
1134 if previous_value is not None: |
1136 previous_value = previous_value[0][0] # got a result set |
1135 previous_value = previous_value[0][0] # got a result set |
1137 if previous_value == entity[attr]: |
1136 if previous_value == entity.cw_attr_cache[attr]: |
1138 previous_value = None |
1137 previous_value = None |
1139 elif source.should_call_hooks: |
1138 elif source.should_call_hooks: |
1140 hm.call_hooks('before_delete_relation', session, |
1139 hm.call_hooks('before_delete_relation', session, |
1141 eidfrom=entity.eid, rtype=attr, |
1140 eidfrom=entity.eid, rtype=attr, |
1142 eidto=previous_value) |
1141 eidto=previous_value) |
1143 relations.append((attr, entity[attr], previous_value)) |
1142 relations.append((attr, edited[attr], previous_value)) |
1144 if source.should_call_hooks: |
1143 if source.should_call_hooks: |
1145 # call hooks for inlined relations |
1144 # call hooks for inlined relations |
1146 for attr, value, _ in relations: |
1145 for attr, value, _ in relations: |
1147 hm.call_hooks('before_add_relation', session, |
1146 hm.call_hooks('before_add_relation', session, |
1148 eidfrom=entity.eid, rtype=attr, eidto=value) |
1147 eidfrom=entity.eid, rtype=attr, eidto=value) |
1149 if not only_inline_rels: |
1148 if not only_inline_rels: |
1150 hm.call_hooks('before_update_entity', session, entity=entity) |
1149 hm.call_hooks('before_update_entity', session, entity=entity) |
1151 if session.is_hook_category_activated('integrity'): |
1150 if session.is_hook_category_activated('integrity'): |
1152 entity._cw_check() |
1151 edited.check() |
1153 source.update_entity(session, entity) |
1152 source.update_entity(session, entity) |
|
1153 edited.saved = True |
1154 self.system_source.update_info(session, entity, need_fti_update) |
1154 self.system_source.update_info(session, entity, need_fti_update) |
1155 if source.should_call_hooks: |
1155 if source.should_call_hooks: |
1156 if not only_inline_rels: |
1156 if not only_inline_rels: |
1157 hm.call_hooks('after_update_entity', session, entity=entity) |
1157 hm.call_hooks('after_update_entity', session, entity=entity) |
1158 for attr, value, prevvalue in relations: |
1158 for attr, value, prevvalue in relations: |
1170 entity.cw_set_relation_cache(attr, 'subject', |
1170 entity.cw_set_relation_cache(attr, 'subject', |
1171 session.eid_rset(value)) |
1171 session.eid_rset(value)) |
1172 hm.call_hooks('after_add_relation', session, |
1172 hm.call_hooks('after_add_relation', session, |
1173 eidfrom=entity.eid, rtype=attr, eidto=value) |
1173 eidfrom=entity.eid, rtype=attr, eidto=value) |
1174 finally: |
1174 finally: |
1175 if orig_edited_attributes is not None: |
1175 if orig_edited is not None: |
1176 entity.edited_attributes = orig_edited_attributes |
1176 entity.cw_edited = orig_edited |
1177 |
1177 |
1178 def glob_delete_entity(self, session, eid): |
1178 def glob_delete_entity(self, session, eid): |
1179 """delete an entity and all related entities from the repository""" |
1179 """delete an entity and all related entities from the repository""" |
1180 entity = session.entity_from_eid(eid) |
1180 entity = session.entity_from_eid(eid) |
1181 etype, sourceuri, extid = self.type_and_source_from_eid(eid, session) |
1181 etype, sourceuri, extid = self.type_and_source_from_eid(eid, session) |