--- a/dataimport.py Tue Apr 12 14:09:39 2011 +0200
+++ b/dataimport.py Wed Apr 13 11:03:42 2011 +0200
@@ -581,7 +581,7 @@
self.tell(pformat(sorted(error[1])))
def _print_stats(self):
- nberrors = sum(len(err[1]) for err in self.errors.values())
+ nberrors = sum(len(err) for err in self.errors.values())
self.tell('\nImport statistics: %i entities, %i types, %i relations and %i errors'
% (self.store.nb_inserted_entities,
self.store.nb_inserted_types,
--- a/devtools/__init__.py Tue Apr 12 14:09:39 2011 +0200
+++ b/devtools/__init__.py Wed Apr 13 11:03:42 2011 +0200
@@ -232,6 +232,11 @@
# XXX merge with BaseApptestConfiguration ?
class ApptestConfiguration(BaseApptestConfiguration):
+ # `skip_db_create_and_restore` controls wether or not the test database
+ # should be created / backuped / restored. If set to True, those
+ # steps are completely skipped, the database is used as is and is
+ # considered initialized
+ skip_db_create_and_restore = False
def __init__(self, appid, apphome=None,
log_threshold=logging.CRITICAL, sourcefile=None):
@@ -260,6 +265,7 @@
self.view('foaf', rset)
"""
+ skip_db_create_and_restore = True
read_instance_schema = True # read schema from database
@@ -477,13 +483,38 @@
cnx.close()
self.backup_database(test_db_id)
+
+class NoCreateDropDatabaseHandler(TestDataBaseHandler):
+ """This handler is used if config.skip_db_create_and_restore is True
+
+ This is typically the case with RealDBConfig. In that case,
+ we explicitely want to skip init / backup / restore phases.
+
+ This handler redefines the three corresponding methods and delegates
+ to original handler for any other method / attribute
+ """
+
+ def __init__(self, base_handler):
+ self.base_handler = base_handler
+
+ # override init / backup / restore methods
+ def init_test_database(self):
+ pass
+
+ def backup_database(self, db_id):
+ pass
+
+ def restore_database(self, db_id):
+ pass
+
+ # delegate to original handler in all other cases
+ def __getattr__(self, attrname):
+ return getattr(self.base_handler, attrname)
+
+
### postgres test database handling ############################################
class PostgresTestDataBaseHandler(TestDataBaseHandler):
-
- # XXX
- # XXX PostgresTestDataBaseHandler Have not been tested at all.
- # XXX
DRIVER = 'postgres'
@property
@@ -504,14 +535,19 @@
def cursor(self):
return self.dbcnx.cursor()
+ def process_cache_entry(self, directory, dbname, db_id, entry):
+ backup_name = self._backup_name(db_id)
+ if backup_name in self.helper.list_databases(self.cursor):
+ return backup_name
+ return None
+
def init_test_database(self):
- """initialize a fresh postgresql databse used for testing purpose"""
+ """initialize a fresh postgresql database used for testing purpose"""
from cubicweb.server import init_repository
from cubicweb.server.serverctl import system_source_cnx, createdb
# connect on the dbms system base to create our base
try:
self._drop(self.dbname)
-
createdb(self.helper, self.system_source, self.dbcnx, self.cursor)
self.dbcnx.commit()
cnx = system_source_cnx(self.system_source, special_privs='LANGUAGE C',
@@ -555,7 +591,6 @@
def _drop(self, db_name):
if db_name in self.helper.list_databases(self.cursor):
- #print 'dropping overwritted database:', db_name
self.cursor.execute('DROP DATABASE %s' % db_name)
self.dbcnx.commit()
@@ -567,7 +602,6 @@
orig_name = self.system_source['db-name']
try:
backup_name = self._backup_name(db_id)
- #print 'storing postgres backup as', backup_name
self._drop(backup_name)
self.system_source['db-name'] = backup_name
createdb(self.helper, self.system_source, self.dbcnx, self.cursor, template=orig_name)
@@ -581,7 +615,6 @@
"""Actual restore of the current database.
Use the value tostored in db_cache as input """
- #print 'restoring postgrest backup from', backup_coordinates
self._drop(self.dbname)
createdb(self.helper, self.system_source, self.dbcnx, self.cursor,
template=backup_coordinates)
@@ -647,7 +680,6 @@
# remove database file if it exists ?
dbfile = self.absolute_dbfile()
self._cleanup_database(dbfile)
- #print 'resto from', backup_coordinates
shutil.copy(backup_coordinates, dbfile)
repo = self.get_repo()
@@ -754,6 +786,8 @@
handlerkls = HANDLERS.get(driver, None)
if handlerkls is not None:
handler = handlerkls(config)
+ if config.skip_db_create_and_restore:
+ handler = NoCreateDropDatabaseHandler(handler)
HCACHE.set(config, handler)
return handler
else:
--- a/entities/test/unittest_base.py Tue Apr 12 14:09:39 2011 +0200
+++ b/entities/test/unittest_base.py Wed Apr 13 11:03:42 2011 +0200
@@ -111,6 +111,11 @@
'creation_date', 'modification_date', 'cwuri', 'eid'))
)
+ def test_cw_instantiate_object_relation(self):
+ """ a weird non regression test """
+ e = self.execute('CWUser U WHERE U login "member"').get_entity(0, 0)
+ self.request().create_entity('CWGroup', name=u'logilab', reverse_in_group=e)
+
class InterfaceTC(CubicWebTC):
--- a/entity.py Tue Apr 12 14:09:39 2011 +0200
+++ b/entity.py Wed Apr 13 11:03:42 2011 +0200
@@ -254,10 +254,12 @@
>>> companycls = vreg['etypes'].etype_class(('Company')
>>> personcls = vreg['etypes'].etype_class(('Person')
- >>> c = companycls.cw_instantiate(req.execute, name=u'Logilab')
- >>> personcls.cw_instantiate(req.execute, firstname=u'John', lastname=u'Doe',
- ... works_for=c)
+ >>> c = companycls.cw_instantiate(session.execute, name=u'Logilab')
+ >>> p = personcls.cw_instantiate(session.execute, firstname=u'John', lastname=u'Doe',
+ ... works_for=c)
+ You can also set relation where the entity has 'object' role by
+ prefixing the relation by 'reverse_'.
"""
rql = 'INSERT %s X' % cls.__regid__
relations = []
@@ -276,14 +278,14 @@
if len(value) == 1:
value = iter(value).next()
else:
+ # prepare IN clause
del kwargs[attr]
pending_relations.append( (attr, value) )
continue
if hasattr(value, 'eid'): # non final relation
rvar = attr.upper()
- # XXX safer detection of object relation
- if attr.startswith('reverse_'):
- relations.append('%s %s X' % (rvar, attr[len('reverse_'):]))
+ if role == 'object':
+ relations.append('%s %s X' % (rvar, attr))
else:
relations.append('X %s %s' % (attr, rvar))
restriction = '%s eid %%(%s)s' % (rvar, attr)
@@ -941,9 +943,7 @@
assert kwargs
assert self.cw_is_saved(), "should not call set_attributes while entity "\
"hasn't been saved yet"
- relations = []
- for key in kwargs:
- relations.append('X %s %%(%s)s' % (key, key))
+ relations = ['X %s %%(%s)s' % (key, key) for key in kwargs]
# and now update the database
kwargs['x'] = self.eid
self._cw.execute('SET %s WHERE X eid %%(x)s' % ','.join(relations),
--- a/web/views/schema.py Tue Apr 12 14:09:39 2011 +0200
+++ b/web/views/schema.py Wed Apr 13 11:03:42 2011 +0200
@@ -1,4 +1,4 @@
-# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
+# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr
#
# This file is part of CubicWeb.
@@ -543,8 +543,9 @@
pass
class CWSchemaDotPropsHandler(s2d.SchemaDotPropsHandler):
- def __init__(self, visitor):
+ def __init__(self, visitor, cw):
self.visitor = visitor
+ self.cw = cw
self.nextcolor = cycle( ('#ff7700', '#000000',
'#ebbc69', '#888888') ).next
self.colors = {}
@@ -558,7 +559,7 @@
label.append(r'\l}') # trailing \l ensure alignement of the last one
return {'label' : ''.join(label), 'shape' : "record",
'fontname' : "Courier", 'style' : "filled",
- 'href': 'cwetype/%s' % eschema.type,
+ 'href': self.cw.build_url('cwetype/%s' % eschema.type),
'fontsize': '10px'
}
@@ -569,11 +570,12 @@
kwargs = {'label': rschema.type,
'color': '#887788', 'style': 'dashed',
'dir': 'both', 'arrowhead': 'normal', 'arrowtail': 'normal',
- 'fontsize': '10px', 'href': 'cwrtype/%s' % rschema.type}
+ 'fontsize': '10px',
+ 'href': self.cw.build_url('cwrtype/%s' % rschema.type)}
else:
kwargs = {'label': rschema.type,
'color' : 'black', 'style' : 'filled', 'fontsize': '10px',
- 'href': 'cwrtype/%s' % rschema.type}
+ 'href': self.cw.build_url('cwrtype/%s' % rschema.type)}
rdef = rschema.rdef(subjnode, objnode)
composite = rdef.composite
if rdef.composite == 'subject':
@@ -625,7 +627,7 @@
alt = self._cw._('graphical representation of %(appid)s data model')
alt %= {'rtype': rtype, 'etype': etype,
'appid': self._cw.vreg.config.appid}
- prophdlr = CWSchemaDotPropsHandler(visitor)
+ prophdlr = CWSchemaDotPropsHandler(visitor, self._cw)
generator = GraphGenerator(DotBackend('schema', 'BT',
ratio='compress',size=None,
renderer='dot',