server/sources/__init__.py
changeset 10086 98bc2ca1a816
parent 9822 4a118bfd6ab4
child 10575 036f5964e6fe
child 10580 5fbdbbe51867
equal deleted inserted replaced
10085:dc315002a2d4 10086:98bc2ca1a816
     1 # copyright 2003-2013 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     1 # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
     3 #
     3 #
     4 # This file is part of CubicWeb.
     4 # This file is part of CubicWeb.
     5 #
     5 #
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
     6 # CubicWeb is free software: you can redistribute it and/or modify it under the
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    17 # with CubicWeb.  If not, see <http://www.gnu.org/licenses/>.
    18 """cubicweb server sources support"""
    18 """cubicweb server sources support"""
    19 
    19 
    20 __docformat__ = "restructuredtext en"
    20 __docformat__ = "restructuredtext en"
    21 
    21 
    22 import itertools
       
    23 from os.path import join, splitext
       
    24 from time import time
    22 from time import time
    25 from datetime import datetime, timedelta
       
    26 from logging import getLogger
    23 from logging import getLogger
    27 
    24 
    28 from logilab.common import configuration
    25 from logilab.common import configuration
    29 from logilab.common.deprecation import deprecated
    26 from logilab.common.deprecation import deprecated
    30 
    27 
    31 from yams.schema import role_name
    28 from yams.schema import role_name
    32 
    29 
    33 from cubicweb import ValidationError, set_log_methods, server
    30 from cubicweb import ValidationError, set_log_methods, server
    34 from cubicweb.schema import VIRTUAL_RTYPES
    31 from cubicweb.server import SOURCE_TYPES
    35 from cubicweb.server.sqlutils import SQL_PREFIX
       
    36 from cubicweb.server.edition import EditedEntity
    32 from cubicweb.server.edition import EditedEntity
    37 
    33 
    38 
    34 
    39 def dbg_st_search(uri, union, varmap, args, cachekey=None, prefix='rql for'):
    35 def dbg_st_search(uri, union, varmap, args, cachekey=None, prefix='rql for'):
    40     if server.DEBUG & server.DBG_RQL:
    36     if server.DEBUG & server.DBG_RQL:
   309         """called by the repository after an entity stored here has been
   305         """called by the repository after an entity stored here has been
   310         inserted in the system table.
   306         inserted in the system table.
   311         """
   307         """
   312         pass
   308         pass
   313 
   309 
   314     def _load_mapping(self, session=None, **kwargs):
   310     def _load_mapping(self, cnx, **kwargs):
   315         if not 'CWSourceSchemaConfig' in self.schema:
   311         if not 'CWSourceSchemaConfig' in self.schema:
   316             self.warning('instance is not mapping ready')
   312             self.warning('instance is not mapping ready')
   317             return
   313             return
   318         if session is None:
   314         for schemacfg in cnx.execute(
   319             _session = self.repo.internal_session()
   315             'Any CFG,CFGO,S WHERE '
   320         else:
   316             'CFG options CFGO, CFG cw_schema S, '
   321             _session = session
   317             'CFG cw_for_source X, X eid %(x)s', {'x': self.eid}).entities():
   322         try:
   318             self.add_schema_config(schemacfg, **kwargs)
   323             for schemacfg in _session.execute(
       
   324                 'Any CFG,CFGO,S WHERE '
       
   325                 'CFG options CFGO, CFG cw_schema S, '
       
   326                 'CFG cw_for_source X, X eid %(x)s', {'x': self.eid}).entities():
       
   327                 self.add_schema_config(schemacfg, **kwargs)
       
   328         finally:
       
   329             if session is None:
       
   330                 _session.close()
       
   331 
   319 
   332     def add_schema_config(self, schemacfg, checkonly=False):
   320     def add_schema_config(self, schemacfg, checkonly=False):
   333         """added CWSourceSchemaConfig, modify mapping accordingly"""
   321         """added CWSourceSchemaConfig, modify mapping accordingly"""
   334         msg = schemacfg._cw._("this source doesn't use a mapping")
   322         msg = schemacfg._cw._("this source doesn't use a mapping")
   335         raise ValidationError(schemacfg.eid, {None: msg})
   323         raise ValidationError(schemacfg.eid, {None: msg})
   370 
   358 
   371     def get_extid(self, entity):
   359     def get_extid(self, entity):
   372         """return the external id for the given newly inserted entity"""
   360         """return the external id for the given newly inserted entity"""
   373         raise NotImplementedError(self)
   361         raise NotImplementedError(self)
   374 
   362 
   375     def add_entity(self, session, entity):
   363     def add_entity(self, cnx, entity):
   376         """add a new entity to the source"""
   364         """add a new entity to the source"""
   377         raise NotImplementedError(self)
   365         raise NotImplementedError(self)
   378 
   366 
   379     def update_entity(self, session, entity):
   367     def update_entity(self, cnx, entity):
   380         """update an entity in the source"""
   368         """update an entity in the source"""
   381         raise NotImplementedError(self)
   369         raise NotImplementedError(self)
   382 
   370 
   383     def delete_entities(self, session, entities):
   371     def delete_entities(self, cnx, entities):
   384         """delete several entities from the source"""
   372         """delete several entities from the source"""
   385         for entity in entities:
   373         for entity in entities:
   386             self.delete_entity(session, entity)
   374             self.delete_entity(cnx, entity)
   387 
   375 
   388     def delete_entity(self, session, entity):
   376     def delete_entity(self, cnx, entity):
   389         """delete an entity from the source"""
   377         """delete an entity from the source"""
   390         raise NotImplementedError(self)
   378         raise NotImplementedError(self)
   391 
   379 
   392     def add_relation(self, session, subject, rtype, object):
   380     def add_relation(self, cnx, subject, rtype, object):
   393         """add a relation to the source"""
   381         """add a relation to the source"""
   394         raise NotImplementedError(self)
   382         raise NotImplementedError(self)
   395 
   383 
   396     def add_relations(self, session,  rtype, subj_obj_list):
   384     def add_relations(self, cnx,  rtype, subj_obj_list):
   397         """add a relations to the source"""
   385         """add a relations to the source"""
   398         # override in derived classes if you feel you can
   386         # override in derived classes if you feel you can
   399         # optimize
   387         # optimize
   400         for subject, object in subj_obj_list:
   388         for subject, object in subj_obj_list:
   401             self.add_relation(session, subject, rtype, object)
   389             self.add_relation(cnx, subject, rtype, object)
   402 
   390 
   403     def delete_relation(self, session, subject, rtype, object):
   391     def delete_relation(self, session, subject, rtype, object):
   404         """delete a relation from the source"""
   392         """delete a relation from the source"""
   405         raise NotImplementedError(self)
   393         raise NotImplementedError(self)
   406 
   394 
   407     # system source interface #################################################
   395     # system source interface #################################################
   408 
   396 
   409     def eid_type_source(self, session, eid):
   397     def eid_type_source(self, cnx, eid):
   410         """return a tuple (type, source, extid) for the entity with id <eid>"""
   398         """return a tuple (type, source, extid) for the entity with id <eid>"""
   411         raise NotImplementedError(self)
   399         raise NotImplementedError(self)
   412 
   400 
   413     def create_eid(self, session):
   401     def create_eid(self, cnx):
   414         raise NotImplementedError(self)
   402         raise NotImplementedError(self)
   415 
   403 
   416     def add_info(self, session, entity, source, extid):
   404     def add_info(self, cnx, entity, source, extid):
   417         """add type and source info for an eid into the system table"""
   405         """add type and source info for an eid into the system table"""
   418         raise NotImplementedError(self)
   406         raise NotImplementedError(self)
   419 
   407 
   420     def update_info(self, session, entity, need_fti_update):
   408     def update_info(self, cnx, entity, need_fti_update):
   421         """mark entity as being modified, fulltext reindex if needed"""
   409         """mark entity as being modified, fulltext reindex if needed"""
   422         raise NotImplementedError(self)
   410         raise NotImplementedError(self)
   423 
   411 
   424     def index_entity(self, session, entity):
   412     def index_entity(self, cnx, entity):
   425         """create an operation to [re]index textual content of the given entity
   413         """create an operation to [re]index textual content of the given entity
   426         on commit
   414         on commit
   427         """
   415         """
   428         raise NotImplementedError(self)
   416         raise NotImplementedError(self)
   429 
   417 
   430     def fti_unindex_entities(self, session, entities):
   418     def fti_unindex_entities(self, cnx, entities):
   431         """remove text content for entities from the full text index
   419         """remove text content for entities from the full text index
   432         """
   420         """
   433         raise NotImplementedError(self)
   421         raise NotImplementedError(self)
   434 
   422 
   435     def fti_index_entities(self, session, entities):
   423     def fti_index_entities(self, cnx, entities):
   436         """add text content of created/modified entities to the full text index
   424         """add text content of created/modified entities to the full text index
   437         """
   425         """
   438         raise NotImplementedError(self)
   426         raise NotImplementedError(self)
   439 
   427 
   440     # sql system source interface #############################################
   428     # sql system source interface #############################################
   441 
   429 
   442     def sqlexec(self, session, sql, args=None):
   430     def sqlexec(self, cnx, sql, args=None):
   443         """execute the query and return its result"""
   431         """execute the query and return its result"""
   444         raise NotImplementedError(self)
   432         raise NotImplementedError(self)
   445 
   433 
   446     def create_index(self, session, table, column, unique=False):
   434     def create_index(self, cnx, table, column, unique=False):
   447         raise NotImplementedError(self)
   435         raise NotImplementedError(self)
   448 
   436 
   449     def drop_index(self, session, table, column, unique=False):
   437     def drop_index(self, cnx, table, column, unique=False):
   450         raise NotImplementedError(self)
   438         raise NotImplementedError(self)
   451 
   439 
   452 
   440 
   453     @deprecated('[3.13] use extid2eid(source, value, etype, session, **kwargs)')
   441     @deprecated('[3.13] use extid2eid(source, value, etype, cnx, **kwargs)')
   454     def extid2eid(self, value, etype, session, **kwargs):
   442     def extid2eid(self, value, etype, cnx, **kwargs):
   455         return self.repo.extid2eid(self, value, etype, session, **kwargs)
   443         return self.repo.extid2eid(self, value, etype, cnx, **kwargs)
   456 
   444 
   457 
   445 
   458 
   446 
   459 from cubicweb.server import SOURCE_TYPES
       
   460 
   447 
   461 def source_adapter(source_type):
   448 def source_adapter(source_type):
   462     try:
   449     try:
   463         return SOURCE_TYPES[source_type]
   450         return SOURCE_TYPES[source_type]
   464     except KeyError:
   451     except KeyError: