# HG changeset patch # User sylvain.thenault@logilab.fr # Date 1242226885 -7200 # Node ID 9eadf34fd86067cc5874e82c371ebbd542718840 # Parent c77629112437ebc4bbefb92dcc68c1b394af4583 delete-trailing-spaces diff -r c77629112437 -r 9eadf34fd860 server/sources/__init__.py --- a/server/sources/__init__.py Wed May 13 17:01:16 2009 +0200 +++ b/server/sources/__init__.py Wed May 13 17:01:25 2009 +0200 @@ -17,13 +17,13 @@ def __init__(self, ttlm, ttls=0): # time to live in minutes self.ttl = timedelta(0, ttlm*60 + ttls, 0) - + def __setitem__(self, key, value): dict.__setitem__(self, key, (datetime.now(), value)) - + def __getitem__(self, key): return dict.__getitem__(self, key)[1] - + def clear_expired(self): now_ = datetime.now() ttl = self.ttl @@ -41,7 +41,7 @@ # boolean telling if the repository should connect to this source during # migration connect_for_migration = True - + # mappings telling which entities and relations are available in the source # keys are supported entity/relation types and values are boolean indicating # wether the support is read-only (False) or read-write (True) @@ -54,30 +54,30 @@ repo = None # a reference to the application'schema (may differs from the source'schema) schema = None - + def __init__(self, repo, appschema, source_config, *args, **kwargs): self.repo = repo self.uri = source_config['uri'] set_log_methods(self, getLogger('cubicweb.sources.'+self.uri)) self.set_schema(appschema) self.support_relations['identity'] = False - + def init_creating(self): """method called by the repository once ready to create a new instance""" pass - + def init(self): """method called by the repository once ready to handle request""" pass - + def reset_caches(self): """method called during test to reset potential source caches""" pass - + def clear_eid_cache(self, eid, etype): """clear potential caches for the given eid""" pass - + def __repr__(self): return '<%s source @%#x>' % (self.uri, id(self)) @@ -92,11 +92,11 @@ if other.uri == 'system': return -1 return cmp(self.uri, other.uri) - + def set_schema(self, schema): """set the application'schema""" self.schema = schema - + def support_entity(self, etype, write=False): """return true if the given entity's type is handled by this adapter if write is true, return true only if it's a RW support @@ -108,13 +108,13 @@ if write: return wsupport return True - + def support_relation(self, rtype, write=False): """return true if the given relation's type is handled by this adapter if write is true, return true only if it's a RW support - current implementation return true if the relation is defined into - `support_relations` or if it is a final relation of a supported entity + current implementation return true if the relation is defined into + `support_relations` or if it is a final relation of a supported entity type """ try: @@ -133,8 +133,8 @@ return False if write: return wsupport - return True - + return True + def eid2extid(self, eid, session=None): return self.repo.eid2extid(self, eid, session) @@ -187,7 +187,7 @@ rschema.type, myeids) session.system_sql(sql) break - + def cleanup_entities_info(self, session): """cleanup system tables from information for entities coming from this source. This should be called when a source is removed to @@ -204,13 +204,13 @@ {'uri': self.uri}) session.system_sql('DELETE FROM entities WHERE source=%(uri)s', {'uri': self.uri}) - + # abstract methods to override (at least) in concrete source classes ####### - + def get_connection(self): """open and return a connection to the source""" raise NotImplementedError() - + def check_connection(self, cnx): """check connection validity, return None if the connection is still valid else a new connection (called when the pool using the given connection is @@ -219,7 +219,7 @@ do nothing by default """ pass - + def pool_reset(self, cnx): """the pool using the given connection is being reseted from its current attached session @@ -227,7 +227,7 @@ do nothing by default """ pass - + def authenticate(self, session, login, password): """if the source support CWUser entity type, it should implements this method which should return CWUser eid for the given login/password @@ -235,16 +235,16 @@ given. Else raise `AuthenticationError` """ raise NotImplementedError() - + def syntax_tree_search(self, session, union, args=None, cachekey=None, varmap=None, debug=0): - """return result from this source for a rql query (actually from a rql - syntax tree and a solution dictionary mapping each used variable to a + """return result from this source for a rql query (actually from a rql + syntax tree and a solution dictionary mapping each used variable to a possible type). If cachekey is given, the query necessary to fetch the results (but not the results themselves) may be cached using this key. """ raise NotImplementedError() - + def flying_insert(self, table, session, union, args=None, varmap=None): """similar as .syntax_tree_search, but inserts data in the temporary table (on-the-fly if possible, eg for the system source whose the given @@ -254,21 +254,21 @@ res = self.syntax_tree_search(session, union, args, varmap=varmap) session.pool.source('system')._manual_insert(res, table, session) - + # system source don't have to implement the two methods below - + def before_entity_insertion(self, session, lid, etype, eid): """called by the repository when an eid has been attributed for an entity stored here but the entity has not been inserted in the system table yet. - + This method must return the an Entity instance representation of this entity. """ entity = self.repo.vreg.etype_class(etype)(session, None) entity.set_eid(eid) return entity - + def after_entity_insertion(self, session, lid, entity): """called by the repository after an entity stored here has been inserted in the system table. @@ -280,11 +280,11 @@ def get_extid(self, entity): """return the external id for the given newly inserted entity""" raise NotImplementedError() - + def add_entity(self, session, entity): """add a new entity to the source""" raise NotImplementedError() - + def update_entity(self, session, entity): """update an entity in the source""" raise NotImplementedError() @@ -296,7 +296,7 @@ def add_relation(self, session, subject, rtype, object): """add a relation to the source""" raise NotImplementedError() - + def delete_relation(self, session, subject, rtype, object): """delete a relation from the source""" raise NotImplementedError() @@ -306,7 +306,7 @@ def eid_type_source(self, session, eid): """return a tuple (type, source, extid) for the entity with id """ raise NotImplementedError() - + def create_eid(self, session): raise NotImplementedError() @@ -319,18 +319,18 @@ record from the entities table to the deleted_entities table """ raise NotImplementedError() - + def fti_unindex_entity(self, session, eid): """remove text content for entity with the given eid from the full text index """ raise NotImplementedError() - + def fti_index_entity(self, session, entity): """add text content of a created/modified entity to the full text index """ raise NotImplementedError() - + def modified_entities(self, session, etypes, mtime): """return a 2-uple: * list of (etype, eid) of entities of the given types which have been @@ -346,13 +346,13 @@ def sqlexec(self, session, sql, args=None): """execute the query and return its result""" raise NotImplementedError() - + def temp_table_def(self, selection, solution, table, basemap): raise NotImplementedError() - + def create_index(self, session, table, column, unique=False): raise NotImplementedError() - + def drop_index(self, session, table, column, unique=False): raise NotImplementedError() @@ -363,14 +363,14 @@ """remove temporary data, usually associated to temporary tables""" pass - + class TrFunc(object): """lower, upper""" def __init__(self, trname, index, attrname=None): self._tr = trname.lower() self.index = index self.attrname = attrname - + def apply(self, resdict): value = resdict.get(self.attrname) if value is not None: @@ -428,7 +428,7 @@ return SOURCE_TYPES[adapter_type] except KeyError: raise RuntimeError('Unknown adapter %r' % adapter_type) - + def get_source(source_config, global_schema, repo): """return a source adapter according to the adapter field in the source's configuration diff -r c77629112437 -r 9eadf34fd860 server/sources/native.py --- a/server/sources/native.py Wed May 13 17:01:16 2009 +0200 +++ b/server/sources/native.py Wed May 13 17:01:25 2009 +0200 @@ -29,7 +29,7 @@ class LogCursor(object): def __init__(self, cursor): self.cu = cursor - + def execute(self, query, args=None): """Execute a query. it's a function just so that it shows up in profiling @@ -42,13 +42,13 @@ print "sql: %r\n args: %s\ndbms message: %r" % ( query, args, ex.args[0]) raise - + def fetchall(self): return self.cu.fetchall() - + def fetchone(self): return self.cu.fetchone() - + def make_schema(selected, solution, table, typemap): """return a sql schema to store RQL query result""" sql = [] @@ -84,11 +84,11 @@ """ # need default value on class since migration doesn't call init method has_deleted_entitites_table = True - + passwd_rql = "Any P WHERE X is CWUser, X login %(login)s, X upassword P" auth_rql = "Any X WHERE X is CWUser, X login %(login)s, X upassword %(pwd)s" _sols = ({'X': 'CWUser', 'P': 'Password'},) - + options = ( ('db-driver', {'type' : 'string', @@ -127,7 +127,7 @@ 'group': 'native-source', 'inputlevel': 1, }), ) - + def __init__(self, repo, appschema, source_config, *args, **kwargs): SQLAdapterMixIn.__init__(self, source_config) AbstractSource.__init__(self, repo, appschema, source_config, @@ -150,18 +150,18 @@ def reset_caches(self): """method called during test to reset potential source caches""" self._cache = Cache(self.repo.config['rql-cache-size']) - + def clear_eid_cache(self, eid, etype): """clear potential caches for the given eid""" self._cache.pop('%s X WHERE X eid %s' % (etype, eid), None) self._cache.pop('Any X WHERE X eid %s' % eid, None) - + def sqlexec(self, session, sql, args=None): """execute the query and return its result""" cursor = session.pool[self.uri] self.doexec(cursor, sql, args) return self.process_result(cursor) - + def init_creating(self): # check full text index availibility pool = self.repo._get_pool() @@ -171,7 +171,7 @@ self.repo._free_pool(pool) def init(self): - self.init_creating() + self.init_creating() pool = self.repo._get_pool() # XXX cubicweb < 2.42 compat if 'deleted_entities' in self.dbhelper.list_tables(pool['system']): @@ -179,7 +179,7 @@ else: self.has_deleted_entitites_table = False self.repo._free_pool(pool) - + # ISource interface ####################################################### def compile_rql(self, rql): @@ -189,7 +189,7 @@ self.repo.querier.sqlgen_annotate(rqlst) set_qdata(self.schema.rschema, rqlst, ()) return rqlst - + def set_schema(self, schema): """set the application'schema""" self._cache = Cache(self.repo.config['rql-cache-size']) @@ -203,13 +203,13 @@ # rql syntax trees used to authenticate users self._passwd_rqlst = self.compile_rql(self.passwd_rql) self._auth_rqlst = self.compile_rql(self.auth_rql) - + def support_entity(self, etype, write=False): """return true if the given entity's type is handled by this adapter if write is true, return true only if it's a RW support """ return not etype in NONSYSTEM_ETYPES - + def support_relation(self, rtype, write=False): """return true if the given relation's type is handled by this adapter if write is true, return true only if it's a RW support @@ -217,7 +217,7 @@ if write: return not rtype in NONSYSTEM_RELATIONS # due to current multi-sources implementation, the system source - # can't claim not supporting a relation + # can't claim not supporting a relation return True #not rtype == 'content_for' def authenticate(self, session, login, password): @@ -243,8 +243,8 @@ return rset[0][0] except IndexError: raise AuthenticationError('bad password') - - def syntax_tree_search(self, session, union, args=None, cachekey=None, + + def syntax_tree_search(self, session, union, args=None, cachekey=None, varmap=None): """return result from this source for a rql query (actually from a rql syntax tree and a solution dictionary mapping each used @@ -289,7 +289,7 @@ if server.DEBUG: print '------>', res return res - + def flying_insert(self, table, session, union, args=None, varmap=None): """similar as .syntax_tree_search, but inserts data in the temporary table (on-the-fly if possible, eg for the system @@ -319,7 +319,7 @@ else: super(NativeSQLSource, self).flying_insert(table, session, union, args, varmap) - + def _manual_insert(self, results, table, session): """insert given result into a temporary table on the system source""" #print 'manual insert', table, results @@ -362,13 +362,13 @@ del self._temp_table_data[table] except KeyError: continue - + def add_entity(self, session, entity): """add a new entity to the source""" attrs = self.preprocess_entity(entity) sql = self.sqlgen.insert(SQL_PREFIX + str(entity.e_schema), attrs) self.doexec(session.pool[self.uri], sql, attrs) - + def update_entity(self, session, entity): """replace an entity in the source""" attrs = self.preprocess_entity(entity) @@ -386,7 +386,7 @@ attrs = {'eid_from': subject, 'eid_to': object} sql = self.sqlgen.insert('%s_relation' % rtype, attrs) self.doexec(session.pool[self.uri], sql, attrs) - + def delete_relation(self, session, subject, rtype, object): """delete a relation from the source""" rschema = self.schema.rschema(rtype) @@ -399,7 +399,7 @@ else: attrs = {'eid_from': subject, 'eid_to': object} sql = self.sqlgen.delete('%s_relation' % rtype, attrs) - self.doexec(session.pool[self.uri], sql, attrs) + self.doexec(session.pool[self.uri], sql, attrs) def doexec(self, cursor, query, args=None): """Execute a query. @@ -417,7 +417,7 @@ self.critical("sql: %r\n args: %s\ndbms message: %r", query, args, ex.args[0]) raise - + def doexecmany(self, cursor, query, args): """Execute a query. it's a function just so that it shows up in profiling @@ -433,13 +433,13 @@ except: self.critical("sql many: %r\n args: %s", query, args) raise - + # short cut to method requiring advanced db helper usage ################## - + def create_index(self, session, table, column, unique=False): cursor = LogCursor(session.pool[self.uri]) self.dbhelper.create_index(cursor, table, column, unique) - + def drop_index(self, session, table, column, unique=False): cursor = LogCursor(session.pool[self.uri]) self.dbhelper.drop_index(cursor, table, column, unique) @@ -466,16 +466,16 @@ {'x': str(lid), 's': source.uri}) # XXX testing rowcount cause strange bug with sqlite, results are there # but rowcount is 0 - #if cursor.rowcount > 0: + #if cursor.rowcount > 0: try: result = cursor.fetchone() if result: eid = result[0] - return eid + return eid except: pass return None - + def temp_table_def(self, selected, sol, table): return make_schema(selected, sol, table, self.dbhelper.TYPE_MAPPING) @@ -485,7 +485,7 @@ # on commit sql = self.dbhelper.sql_temporary_table(table, schema, False) self.doexec(session.pool[self.uri], sql) - + def create_eid(self, session): self._eid_creation_lock.acquire() try: @@ -513,7 +513,7 @@ attrs = {'type': etype, 'eid': eid, 'extid': extid, 'source': uri, 'dtime': datetime.now()} session.system_sql(self.sqlgen.insert('deleted_entities', attrs), attrs) - + def fti_unindex_entity(self, session, eid): """remove text content for entity with the given eid from the full text index @@ -523,7 +523,7 @@ except: if self.indexer is not None: self.exception('error while unindexing %s', eid) - + def fti_index_entity(self, session, entity): """add text content of a created/modified entity to the full text index """ @@ -537,7 +537,7 @@ # update entities.mtime attrs = {'eid': entity.eid, 'mtime': datetime.now()} session.system_sql(self.sqlgen.update('entities', attrs, ['eid']), attrs) - + def modified_entities(self, session, etypes, mtime): """return a 2-uple: * list of (etype, eid) of entities of the given types which have been