server/repository.py
branchstable
changeset 5115 2e43ef618d14
parent 5093 8d073d2e089d
child 5167 529861a73ec8
child 5174 78438ad513ca
equal deleted inserted replaced
5114:55b8b7a5bc4a 5115:2e43ef618d14
    22 import sys
    22 import sys
    23 import Queue
    23 import Queue
    24 from os.path import join
    24 from os.path import join
    25 from datetime import datetime
    25 from datetime import datetime
    26 from time import time, localtime, strftime
    26 from time import time, localtime, strftime
    27 #from pickle import dumps
       
    28 
    27 
    29 from logilab.common.decorators import cached
    28 from logilab.common.decorators import cached
    30 from logilab.common.compat import any
    29 from logilab.common.compat import any
    31 from logilab.common import flatten
    30 from logilab.common import flatten
    32 
    31 
    36 
    35 
    37 from cubicweb import (CW_SOFTWARE_ROOT, CW_MIGRATION_MAP,
    36 from cubicweb import (CW_SOFTWARE_ROOT, CW_MIGRATION_MAP,
    38                       UnknownEid, AuthenticationError, ExecutionError,
    37                       UnknownEid, AuthenticationError, ExecutionError,
    39                       ETypeNotSupportedBySources, MultiSourcesError,
    38                       ETypeNotSupportedBySources, MultiSourcesError,
    40                       BadConnectionId, Unauthorized, ValidationError,
    39                       BadConnectionId, Unauthorized, ValidationError,
    41                       typed_eid, onevent)
    40                       RepositoryError, typed_eid, onevent)
    42 from cubicweb import cwvreg, schema, server
    41 from cubicweb import cwvreg, schema, server
    43 from cubicweb.server import utils, hook, pool, querier, sources
    42 from cubicweb.server import utils, hook, pool, querier, sources
    44 from cubicweb.server.session import Session, InternalSession, InternalManager, \
    43 from cubicweb.server.session import Session, InternalSession, InternalManager, \
    45      security_enabled
    44      security_enabled
    46 
    45 
  1065         the type and the eid of an entity must not be changed
  1064         the type and the eid of an entity must not be changed
  1066         """
  1065         """
  1067         if server.DEBUG & server.DBG_REPO:
  1066         if server.DEBUG & server.DBG_REPO:
  1068             print 'UPDATE entity', entity.__regid__, entity.eid, \
  1067             print 'UPDATE entity', entity.__regid__, entity.eid, \
  1069                   dict(entity), edited_attributes
  1068                   dict(entity), edited_attributes
  1070         entity.edited_attributes = edited_attributes
  1069         hm = self.hm
  1071         if session.is_hook_category_activated('integrity'):
       
  1072             entity.check()
       
  1073         eschema = entity.e_schema
  1070         eschema = entity.e_schema
  1074         session.set_entity_cache(entity)
  1071         session.set_entity_cache(entity)
  1075         only_inline_rels, need_fti_update = True, False
  1072         orig_edited_attributes = getattr(entity, 'edited_attributes', None)
  1076         relations = []
  1073         entity.edited_attributes = edited_attributes
  1077         for attr in edited_attributes:
  1074         try:
  1078             if attr == 'eid':
  1075             if session.is_hook_category_activated('integrity'):
  1079                 continue
  1076                 entity.check()
  1080             rschema = eschema.subjrels[attr]
  1077             only_inline_rels, need_fti_update = True, False
  1081             if rschema.final:
  1078             relations = []
  1082                 if getattr(eschema.rdef(attr), 'fulltextindexed', False):
  1079             for attr in list(edited_attributes):
  1083                     need_fti_update = True
  1080                 if attr == 'eid':
  1084                 only_inline_rels = False
  1081                     continue
  1085             else:
  1082                 rschema = eschema.subjrels[attr]
  1086                 # inlined relation
  1083                 if rschema.final:
  1087                 previous_value = entity.related(attr) or None
  1084                     if getattr(eschema.rdef(attr), 'fulltextindexed', False):
  1088                 if previous_value is not None:
  1085                         need_fti_update = True
  1089                     previous_value = previous_value[0][0] # got a result set
  1086                     only_inline_rels = False
  1090                     if previous_value == entity[attr]:
  1087                 else:
  1091                         previous_value = None
  1088                     # inlined relation
       
  1089                     previous_value = entity.related(attr) or None
       
  1090                     if previous_value is not None:
       
  1091                         previous_value = previous_value[0][0] # got a result set
       
  1092                         if previous_value == entity[attr]:
       
  1093                             previous_value = None
       
  1094                         else:
       
  1095                             hm.call_hooks('before_delete_relation', session,
       
  1096                                           eidfrom=entity.eid, rtype=attr,
       
  1097                                           eidto=previous_value)
       
  1098                     relations.append((attr, entity[attr], previous_value))
       
  1099                 source = self.source_from_eid(entity.eid, session)
       
  1100                 if source.should_call_hooks:
       
  1101                     # call hooks for inlined relations
       
  1102                     for attr, value, _ in relations:
       
  1103                         hm.call_hooks('before_add_relation', session,
       
  1104                                       eidfrom=entity.eid, rtype=attr, eidto=value)
       
  1105                     if not only_inline_rels:
       
  1106                         hm.call_hooks('before_update_entity', session, entity=entity)
       
  1107                 source.update_entity(session, entity)
       
  1108             self.system_source.update_info(session, entity, need_fti_update)
       
  1109             if source.should_call_hooks:
       
  1110                 if not only_inline_rels:
       
  1111                     hm.call_hooks('after_update_entity', session, entity=entity)
       
  1112                 for attr, value, prevvalue in relations:
       
  1113                     # if the relation is already cached, update existant cache
       
  1114                     relcache = entity.relation_cached(attr, 'subject')
       
  1115                     if prevvalue is not None:
       
  1116                         hm.call_hooks('after_delete_relation', session,
       
  1117                                       eidfrom=entity.eid, rtype=attr, eidto=prevvalue)
       
  1118                         if relcache is not None:
       
  1119                             session.update_rel_cache_del(entity.eid, attr, prevvalue)
       
  1120                     del_existing_rel_if_needed(session, entity.eid, attr, value)
       
  1121                     if relcache is not None:
       
  1122                         session.update_rel_cache_add(entity.eid, attr, value)
  1092                     else:
  1123                     else:
  1093                         self.hm.call_hooks('before_delete_relation', session,
  1124                         entity.set_related_cache(attr, 'subject',
  1094                                            eidfrom=entity.eid, rtype=attr,
  1125                                                  session.eid_rset(value))
  1095                                            eidto=previous_value)
  1126                     hm.call_hooks('after_add_relation', session,
  1096                 relations.append((attr, entity[attr], previous_value))
  1127                                   eidfrom=entity.eid, rtype=attr, eidto=value)
  1097         source = self.source_from_eid(entity.eid, session)
  1128         finally:
  1098         if source.should_call_hooks:
  1129             if orig_edited_attributes is not None:
  1099             # call hooks for inlined relations
  1130                 entity.edited_attributes = orig_edited_attributes
  1100             for attr, value, _ in relations:
       
  1101                 self.hm.call_hooks('before_add_relation', session,
       
  1102                                     eidfrom=entity.eid, rtype=attr, eidto=value)
       
  1103             if not only_inline_rels:
       
  1104                 self.hm.call_hooks('before_update_entity', session, entity=entity)
       
  1105         source.update_entity(session, entity)
       
  1106         self.system_source.update_info(session, entity, need_fti_update)
       
  1107         if source.should_call_hooks:
       
  1108             if not only_inline_rels:
       
  1109                 self.hm.call_hooks('after_update_entity', session, entity=entity)
       
  1110             for attr, value, prevvalue in relations:
       
  1111                 # if the relation is already cached, update existant cache
       
  1112                 relcache = entity.relation_cached(attr, 'subject')
       
  1113                 if prevvalue is not None:
       
  1114                     self.hm.call_hooks('after_delete_relation', session,
       
  1115                                        eidfrom=entity.eid, rtype=attr, eidto=prevvalue)
       
  1116                     if relcache is not None:
       
  1117                         session.update_rel_cache_del(entity.eid, attr, prevvalue)
       
  1118                 del_existing_rel_if_needed(session, entity.eid, attr, value)
       
  1119                 if relcache is not None:
       
  1120                     session.update_rel_cache_add(entity.eid, attr, value)
       
  1121                 else:
       
  1122                     entity.set_related_cache(attr, 'subject',
       
  1123                                              session.eid_rset(value))
       
  1124                 self.hm.call_hooks('after_add_relation', session,
       
  1125                                     eidfrom=entity.eid, rtype=attr, eidto=value)
       
  1126 
  1131 
  1127     def glob_delete_entity(self, session, eid):
  1132     def glob_delete_entity(self, session, eid):
  1128         """delete an entity and all related entities from the repository"""
  1133         """delete an entity and all related entities from the repository"""
  1129         entity = session.entity_from_eid(eid)
  1134         entity = session.entity_from_eid(eid)
  1130         etype, sourceuri, extid = self.type_and_source_from_eid(eid, session)
  1135         etype, sourceuri, extid = self.type_and_source_from_eid(eid, session)