# HG changeset patch # User Sylvain Thénault # Date 1249043130 -7200 # Node ID 92f2bc945261a2104f2f8312f9f089e0694dd359 # Parent 879912fe94e1d0343c92c66b501953d515503c7e# Parent 3a590ff82e99e1c998c4156c38a3a4eb95c6948c backport stable branch diff -r 879912fe94e1 -r 92f2bc945261 misc/migration/3.3.5_Any.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/migration/3.3.5_Any.py Fri Jul 31 14:25:30 2009 +0200 @@ -0,0 +1,8 @@ +# some entities have been added before schema entities, fix the 'is' and +# 'is_instance_of' relations +for rtype in ('is', 'is_instance_of'): + sql('INSERT INTO %s_relation ' + 'SELECT X.eid, ET.cw_eid FROM entities as X, cw_CWEType as ET ' + 'WHERE X.type=ET.cw_name AND NOT EXISTS(' + ' SELECT 1 from is_relation ' + ' WHERE eid_from=X.eid AND eid_to=ET.cw_eid)' % rtype) diff -r 879912fe94e1 -r 92f2bc945261 server/__init__.py --- a/server/__init__.py Fri Jul 31 10:47:15 2009 +0200 +++ b/server/__init__.py Fri Jul 31 14:25:30 2009 +0200 @@ -92,14 +92,11 @@ else: login, pwd = unicode(source['db-user']), source['db-password'] print '-> inserting default user and default groups.' - needisfix = [] for group in BASE_GROUPS: rset = session.execute('INSERT CWGroup X: X name %(name)s', {'name': unicode(group)}) - needisfix.append( (rset.rows[0][0], rset.description[0][0]) ) rset = session.execute('INSERT CWUser X: X login %(login)s, X upassword %(pwd)s', {'login': login, 'pwd': pwd}) - needisfix.append( (rset.rows[0][0], rset.description[0][0]) ) session.execute('SET U in_group G WHERE G name "managers"') session.commit() # reloging using the admin user @@ -109,13 +106,6 @@ handler = config.migration_handler(schema, interactive=False, cnx=cnx, repo=repo) initialize_schema(config, schema, handler) - # admin user and groups have been added before schema entities, fix the 'is' - # relation - for eid, etype in needisfix: - handler.session.unsafe_execute('SET X is E WHERE X eid %(x)s, E name %(name)s', - {'x': eid, 'name': etype}, 'x') - handler.session.unsafe_execute('SET X is_instance_of E WHERE X eid %(x)s, E name %(name)s', - {'x': eid, 'name': etype}, 'x') # insert versions handler.cmd_add_entity('CWProperty', pkey=u'system.version.cubicweb', value=unicode(config.cubicweb_version())) @@ -123,6 +113,15 @@ handler.cmd_add_entity('CWProperty', pkey=u'system.version.%s' % cube.lower(), value=unicode(config.cube_version(cube))) + # some entities have been added before schema entities, fix the 'is' and + # 'is_instance_of' relations + for rtype in ('is', 'is_instance_of'): + handler.sqlexec( + 'INSERT INTO %s_relation ' + 'SELECT X.eid, ET.cw_eid FROM entities as X, cw_CWEType as ET ' + 'WHERE X.type=ET.cw_name AND NOT EXISTS(' + ' SELECT 1 from is_relation ' + ' WHERE eid_from=X.eid AND eid_to=ET.cw_eid)' % rtype) # yoo ! cnx.commit() config.enabled_sources = None diff -r 879912fe94e1 -r 92f2bc945261 server/migractions.py --- a/server/migractions.py Fri Jul 31 10:47:15 2009 +0200 +++ b/server/migractions.py Fri Jul 31 14:25:30 2009 +0200 @@ -159,6 +159,7 @@ except (KeyboardInterrupt, EOFError): print 'aborting...' sys.exit(0) + self.session.keep_pool_mode('transaction') return self._cnx @property diff -r 879912fe94e1 -r 92f2bc945261 server/session.py --- a/server/session.py Fri Jul 31 10:47:15 2009 +0200 +++ b/server/session.py Fri Jul 31 14:25:30 2009 +0200 @@ -59,6 +59,7 @@ self.timestamp = self.creation self.is_internal_session = False self.is_super_session = False + self.default_mode = 'read' # short cut to querier .execute method self._execute = repo.querier.execute # shared data, used to communicate extra information between the client @@ -110,13 +111,33 @@ # connection management ################################################### + def keep_pool_mode(self, mode): + """set pool_mode, e.g. how the session will keep its pool: + + * if mode == 'write', the pool is freed after each ready query, but kept + until the transaction's end (eg commit or rollback) when a write query + is detected (eg INSERT/SET/DELETE queries) + + * if mode == 'transaction', the pool is only freed after the + transaction's end + + notice that a repository has a limited set of pools, and a session has to + wait for a free pool to run any rql query (unless it already has a pool + set). + """ + assert mode in ('transaction', 'write') + if mode == 'transaction': + self.default_mode = 'transaction' + else: # mode == 'write' + self.default_mode = 'read' + def get_mode(self): - return getattr(self._threaddata, 'mode', 'read') + return getattr(self._threaddata, 'mode', self.default_mode) def set_mode(self, value): self._threaddata.mode = value mode = property(get_mode, set_mode, - doc='transaction mode (read/write), resetted to read on ' - 'commit / rollback') + doc='transaction mode (read/write/transaction), resetted to' + ' default_mode on commit / rollback') def get_commit_state(self): return getattr(self._threaddata, 'commit_state', None) @@ -145,11 +166,11 @@ self._threads_in_transaction.add(threading.currentThread()) return self._threaddata.pool - def reset_pool(self): + def reset_pool(self, ignoremode=False): """the session is no longer using its pool, at least for some time""" # pool may be none if no operation has been done since last commit # or rollback - if self.pool is not None and self.mode == 'read': + if self.pool is not None and (ignoremode or self.mode == 'read'): # even in read mode, we must release the current transaction pool = self.pool try: @@ -165,7 +186,7 @@ """update latest session usage timestamp and reset mode to read""" self.timestamp = time() self.local_perm_cache.clear() - self._threaddata.mode = 'read' + self._threaddata.mode = self.default_mode # shared data handling ################################################### @@ -308,7 +329,7 @@ self.pending_operations[:] = [] self.transaction_data.clear() if reset_pool: - self.reset_pool() + self.reset_pool(ignoremode=True) def rollback(self, reset_pool=True): """rollback the current session's transaction""" @@ -333,7 +354,7 @@ self.pending_operations[:] = [] self.transaction_data.clear() if reset_pool: - self.reset_pool() + self.reset_pool(ignoremode=True) def close(self): """do not close pool on session close, since they are shared now""" diff -r 879912fe94e1 -r 92f2bc945261 server/sources/native.py --- a/server/sources/native.py Fri Jul 31 10:47:15 2009 +0200 +++ b/server/sources/native.py Fri Jul 31 14:25:30 2009 +0200 @@ -113,6 +113,12 @@ 'help': 'database host', 'group': 'native-source', 'inputlevel': 1, }), + ('db-port', + {'type' : 'string', + 'default': '', + 'help': 'database port', + 'group': 'native-source', 'inputlevel': 1, + }), ('db-name', {'type' : 'string', 'default': REQUIRED, diff -r 879912fe94e1 -r 92f2bc945261 server/test/unittest_repository.py --- a/server/test/unittest_repository.py Fri Jul 31 10:47:15 2009 +0200 +++ b/server/test/unittest_repository.py Fri Jul 31 14:25:30 2009 +0200 @@ -324,6 +324,10 @@ self.assertRaises(BadConnectionId, repo.set_shared_data, cnxid, 'data', 0) self.assertRaises(BadConnectionId, repo.get_shared_data, cnxid, 'data') + def test_schema_is_relation(self): + no_is_rset = self.execute('Any X WHERE NOT X is ET') + self.failIf(no_is_rset, no_is_rset.description) + class DataHelpersTC(RepositoryBasedTC): diff -r 879912fe94e1 -r 92f2bc945261 vregistry.py --- a/vregistry.py Fri Jul 31 10:47:15 2009 +0200 +++ b/vregistry.py Fri Jul 31 14:25:30 2009 +0200 @@ -266,7 +266,7 @@ oid = obj.id except AttributeError: continue - if oid: + if oid and not '__abstract__' in obj.__dict__: self.register(obj) def register(self, obj, registryname=None, oid=None, clear=False):