server/repository.py
changeset 6142 8bc6eac1fac1
parent 6139 f76599a96238
child 6225 a176e68b7d0d
equal deleted inserted replaced
6141:b8287e54b528 6142:8bc6eac1fac1
    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)