--- a/cubicweb/server/sources/native.py Fri Jul 08 10:17:42 2016 +0200
+++ b/cubicweb/server/sources/native.py Fri Jul 08 09:59:18 2016 +0200
@@ -70,6 +70,7 @@
NONSYSTEM_ETYPES = set()
NONSYSTEM_RELATIONS = set()
+
class LogCursor(object):
def __init__(self, cursor):
self.cu = cursor
@@ -142,12 +143,13 @@
"""check linked entity has not been redirected for this relation"""
card = rdef.role_cardinality(role)
if card in '?1' and tentity.related(rdef.rtype, role):
- raise _UndoException(tentity._cw._(
+ msg = tentity._cw._(
"Can't restore %(role)s relation %(rtype)s to entity %(eid)s which "
"is already linked using this relation.")
- % {'role': neg_role(role),
- 'rtype': rdef.rtype,
- 'eid': tentity.eid})
+ raise _UndoException(msg % {'role': neg_role(role),
+ 'rtype': rdef.rtype,
+ 'eid': tentity.eid})
+
def _undo_rel_info(cnx, subj, rtype, obj):
entities = []
@@ -155,26 +157,27 @@
try:
entities.append(cnx.entity_from_eid(eid))
except UnknownEid:
- raise _UndoException(cnx._(
+ msg = cnx._(
"Can't restore relation %(rtype)s, %(role)s entity %(eid)s"
" doesn't exist anymore.")
- % {'role': cnx._(role),
- 'rtype': cnx._(rtype),
- 'eid': eid})
+ raise _UndoException(msg % {'role': cnx._(role),
+ 'rtype': cnx._(rtype),
+ 'eid': eid})
sentity, oentity = entities
try:
rschema = cnx.vreg.schema.rschema(rtype)
rdef = rschema.rdefs[(sentity.cw_etype, oentity.cw_etype)]
except KeyError:
- raise _UndoException(cnx._(
+ msg = cnx._(
"Can't restore relation %(rtype)s between %(subj)s and "
"%(obj)s, that relation does not exists anymore in the "
"schema.")
- % {'rtype': cnx._(rtype),
- 'subj': subj,
- 'obj': obj})
+ raise _UndoException(msg % {'rtype': cnx._(rtype),
+ 'subj': subj,
+ 'obj': obj})
return sentity, oentity, rdef
+
def _undo_has_later_transaction(cnx, eid):
return cnx.system_sql('''\
SELECT T.tx_uuid FROM transactions AS TREF, transactions AS T
@@ -270,56 +273,56 @@
sqlgen_class = SQLGenerator
options = (
('db-driver',
- {'type' : 'string',
+ {'type': 'string',
'default': 'postgres',
# XXX use choice type
'help': 'database driver (postgres, sqlite, sqlserver2005)',
'group': 'native-source', 'level': 0,
}),
('db-host',
- {'type' : 'string',
+ {'type': 'string',
'default': '',
'help': 'database host',
'group': 'native-source', 'level': 1,
}),
('db-port',
- {'type' : 'string',
+ {'type': 'string',
'default': '',
'help': 'database port',
'group': 'native-source', 'level': 1,
}),
('db-name',
- {'type' : 'string',
+ {'type': 'string',
'default': Method('default_instance_id'),
'help': 'database name',
'group': 'native-source', 'level': 0,
}),
('db-namespace',
- {'type' : 'string',
+ {'type': 'string',
'default': '',
'help': 'database namespace (schema) name',
'group': 'native-source', 'level': 1,
}),
('db-user',
- {'type' : 'string',
+ {'type': 'string',
'default': CubicWebNoAppConfiguration.mode == 'user' and getlogin() or 'cubicweb',
'help': 'database user',
'group': 'native-source', 'level': 0,
}),
('db-password',
- {'type' : 'password',
+ {'type': 'password',
'default': '',
'help': 'database password',
'group': 'native-source', 'level': 0,
}),
('db-encoding',
- {'type' : 'string',
+ {'type': 'string',
'default': 'utf8',
'help': 'database encoding',
'group': 'native-source', 'level': 1,
}),
('db-extra-arguments',
- {'type' : 'string',
+ {'type': 'string',
'default': '',
'help': 'set to "Trusted_Connection" if you are using SQLServer and '
'want trusted authentication for the database connection',
@@ -421,7 +424,6 @@
else:
raise ValueError('Unknown format %r' % format)
-
def restore(self, backupfile, confirm, drop, format='native'):
"""method called to restore a backup of source's data"""
if self.repo.config.init_cnxset_pool:
@@ -438,13 +440,12 @@
if self.repo.config.init_cnxset_pool:
self.open_source_connections()
-
def init(self, activated, source_entity):
try:
# test if 'asource' column exists
query = self.dbhelper.sql_add_limit_offset('SELECT asource FROM entities', 1)
source_entity._cw.system_sql(query)
- except Exception as ex:
+ except Exception:
self.eid_type_source = self.eid_type_source_pre_131
super(NativeSQLSource, self).init(activated, source_entity)
self.init_creating(source_entity._cw.cnxset)
@@ -499,7 +500,7 @@
try:
self._rql_sqlgen.schema = schema
except AttributeError:
- pass # __init__
+ pass # __init__
for authentifier in self.authentifiers:
authentifier.set_schema(self.schema)
clear_cache(self, 'need_fti_indexation')
@@ -508,17 +509,17 @@
"""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
+ return etype not 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
"""
if write:
- return not rtype in NONSYSTEM_RELATIONS
+ return rtype not in NONSYSTEM_RELATIONS
# due to current multi-sources implementation, the system source
# can't claim not supporting a relation
- return True #not rtype == 'content_for'
+ return True #not rtype == 'content_for'
@statsd_timeit
def authenticate(self, cnx, login, **kwargs):
@@ -596,7 +597,7 @@
to_restore = handler(entity, attr)
restore_values.append((entity, attr, to_restore))
try:
- yield # 2/ execute the source's instructions
+ yield # 2/ execute the source's instructions
finally:
# 3/ restore original values
for entity, attr, value in restore_values:
@@ -631,7 +632,7 @@
if cnx.ertype_supports_undo(entity.cw_etype):
attrs = [SQL_PREFIX + r.type
for r in entity.e_schema.subject_relations()
- if (r.final or r.inlined) and not r in VIRTUAL_RTYPES]
+ if (r.final or r.inlined) and r not in VIRTUAL_RTYPES]
changes = self._save_attrs(cnx, entity, attrs)
self._record_tx_action(cnx, 'tx_entity_actions', u'D',
etype=text_type(entity.cw_etype), eid=entity.eid,
@@ -642,12 +643,12 @@
def add_relation(self, cnx, subject, rtype, object, inlined=False):
"""add a relation to the source"""
- self._add_relations(cnx, rtype, [(subject, object)], inlined)
+ self._add_relations(cnx, rtype, [(subject, object)], inlined)
if cnx.ertype_supports_undo(rtype):
self._record_tx_action(cnx, 'tx_relation_actions', u'A',
eid_from=subject, rtype=text_type(rtype), eid_to=object)
- def add_relations(self, cnx, rtype, subj_obj_list, inlined=False):
+ def add_relations(self, cnx, rtype, subj_obj_list, inlined=False):
"""add a relations to the source"""
self._add_relations(cnx, rtype, subj_obj_list, inlined)
if cnx.ertype_supports_undo(rtype):
@@ -662,7 +663,7 @@
attrs = [{'eid_from': subject, 'eid_to': object}
for subject, object in subj_obj_list]
sql.append((self.sqlgen.insert('%s_relation' % rtype, attrs[0]), attrs))
- else: # used by data import
+ else: # used by data import
etypes = {}
for subject, object in subj_obj_list:
etype = cnx.entity_metas(subject)['type']
@@ -674,7 +675,7 @@
attrs = [{'cw_eid': subject, SQL_PREFIX + rtype: object}
for subject, object in subj_obj_list]
sql.append((self.sqlgen.update(SQL_PREFIX + etype, attrs[0],
- ['cw_eid']),
+ ['cw_eid']),
attrs))
for statement, attrs in sql:
self.doexecmany(cnx, statement, attrs)
@@ -694,7 +695,7 @@
column = SQL_PREFIX + rtype
sql = 'UPDATE %s SET %s=NULL WHERE %seid=%%(eid)s' % (table, column,
SQL_PREFIX)
- attrs = {'eid' : subject}
+ attrs = {'eid': subject}
else:
attrs = {'eid_from': subject, 'eid_to': object}
sql = self.sqlgen.delete('%s_relation' % rtype, attrs)
@@ -716,7 +717,7 @@
# during test we get those message when trying to alter sqlite
# db schema
self.info("sql: %r\n args: %s\ndbms message: %r",
- query, args, ex.args[0])
+ query, args, ex.args[0])
if rollback:
try:
cnx.cnxset.rollback()
@@ -847,7 +848,7 @@
self.exception('failed to query entities table for eid %s', eid)
raise UnknownEid(eid)
- def eid_type_source(self, cnx, eid): # pylint: disable=E0202
+ def eid_type_source(self, cnx, eid): # pylint: disable=E0202
"""return a tuple (type, extid, source) for the entity with id <eid>"""
sql = 'SELECT type, extid, asource FROM entities WHERE eid=%s' % eid
res = self._eid_type_source(cnx, eid, sql)
@@ -916,15 +917,18 @@
# insert core relations: is, is_instance_of and cw_source
if entity.e_schema.eid is not None: # else schema has not yet been serialized
- self._handle_is_relation_sql(cnx, 'INSERT INTO is_relation(eid_from,eid_to) VALUES (%s,%s)',
- (entity.eid, entity.e_schema.eid))
+ self._handle_is_relation_sql(
+ cnx, 'INSERT INTO is_relation(eid_from,eid_to) VALUES (%s,%s)',
+ (entity.eid, entity.e_schema.eid))
for eschema in entity.e_schema.ancestors() + [entity.e_schema]:
- self._handle_is_relation_sql(cnx,
- 'INSERT INTO is_instance_of_relation(eid_from,eid_to) VALUES (%s,%s)',
- (entity.eid, eschema.eid))
+ self._handle_is_relation_sql(
+ cnx,
+ 'INSERT INTO is_instance_of_relation(eid_from,eid_to) VALUES (%s,%s)',
+ (entity.eid, eschema.eid))
if source.eid is not None: # else the source has not yet been inserted
- self._handle_is_relation_sql(cnx, 'INSERT INTO cw_source_relation(eid_from,eid_to) VALUES (%s,%s)',
- (entity.eid, source.eid))
+ self._handle_is_relation_sql(
+ cnx, 'INSERT INTO cw_source_relation(eid_from,eid_to) VALUES (%s,%s)',
+ (entity.eid, source.eid))
# now we can update the full text index
if self.need_fti_indexation(entity.cw_etype):
self.index_entity(cnx, entity=entity)
@@ -969,9 +973,9 @@
if actionfilters:
# we will need subqueries to filter transactions according to
# actions done
- tearestr = {} # filters on the tx_entity_actions table
- trarestr = {} # filters on the tx_relation_actions table
- genrestr = {} # generic filters, appliyable to both table
+ tearestr = {} # filters on the tx_entity_actions table
+ trarestr = {} # filters on the tx_relation_actions table
+ genrestr = {} # generic filters, appliyable to both table
# unless public explicitly set to false, we only consider public
# actions
if actionfilters.pop('public', True):
@@ -982,7 +986,7 @@
# filtering on etype implies filtering on entity actions
# only, and with no eid specified
assert actionfilters.get('action', 'C') in 'CUD'
- assert not 'eid' in actionfilters
+ assert 'eid' not in actionfilters
tearestr['etype'] = text_type(val)
elif key == 'eid':
# eid filter may apply to 'eid' of tx_entity_actions or to
@@ -1046,8 +1050,8 @@
'etype', 'eid', 'changes'))
with cnx.ensure_cnx_set:
cu = self.doexec(cnx, sql, restr)
- actions = [tx.EntityAction(a,p,o,et,e,c and pickle.loads(self.binary_to_str(c)))
- for a,p,o,et,e,c in cu.fetchall()]
+ actions = [tx.EntityAction(a, p, o, et, e, c and pickle.loads(self.binary_to_str(c)))
+ for a, p, o, et, e, c in cu.fetchall()]
sql = self.sqlgen.select('tx_relation_actions', restr,
('txa_action', 'txa_public', 'txa_order',
'rtype', 'eid_from', 'eid_to'))
@@ -1146,12 +1150,12 @@
for column, value in changes.items():
rtype = column[len(SQL_PREFIX):]
if rtype == "eid":
- continue # XXX should even `eid` be stored in action changes?
+ continue # XXX should even `eid` be stored in action changes?
try:
rschema = getrschema[rtype]
except KeyError:
err(cnx._("can't restore relation %(rtype)s of entity %(eid)s, "
- "this relation does not exist in the schema anymore.")
+ "this relation does not exist in the schema anymore.")
% {'rtype': rtype, 'eid': eid})
if not rschema.final:
if not rschema.inlined:
@@ -1160,11 +1164,11 @@
elif value is not None:
# not a deletion: we must put something in edited
try:
- entity._cw.entity_from_eid(value) # check target exists
+ entity._cw.entity_from_eid(value) # check target exists
edited[rtype] = value
except UnknownEid:
err(cnx._("can't restore entity %(eid)s of type %(eschema)s, "
- "target of %(rtype)s (eid %(value)s) does not exist any longer")
+ "target of %(rtype)s (eid %(value)s) does not exist any longer")
% locals())
changes[column] = None
elif eschema.destination(rtype) in ('Bytes', 'Password'):
@@ -1183,7 +1187,6 @@
err = errors.append
eid = action.eid
etype = action.etype
- _ = cnx._
# get an entity instance
try:
entity = self.repo.vreg['etypes'].etype_class(etype)(cnx)
@@ -1239,8 +1242,7 @@
# we should find an efficient way to do this (keeping current veolidf
# massive deletion performance)
if _undo_has_later_transaction(cnx, eid):
- msg = cnx._('some later transaction(s) touch entity, undo them '
- 'first')
+ msg = cnx._('some later transaction(s) touch entity, undo them first')
raise ValidationError(eid, {None: msg})
etype = action.etype
# get an entity instance
@@ -1277,7 +1279,7 @@
entity = cnx.entity_from_eid(action.eid)
except UnknownEid:
err(cnx._("can't restore state of entity %s, it has been "
- "deleted inbetween") % action.eid)
+ "deleted inbetween") % action.eid)
return errors
self._reedit_entity(entity, action.changes, err)
entity.cw_edited.check()
@@ -1346,10 +1348,9 @@
try:
for entity in entities:
cursor_unindex_object(entity.eid, cursor)
- except Exception: # let KeyboardInterrupt / SystemExit propagate
+ except Exception: # let KeyboardInterrupt / SystemExit propagate
self.exception('error while unindexing %s', entity)
-
def fti_index_entities(self, cnx, entities):
"""add text content of created/modified entities to the full text index
"""
@@ -1362,7 +1363,7 @@
cursor_index_object(entity.eid,
entity.cw_adapt_to('IFTIndexable'),
cursor)
- except Exception: # let KeyboardInterrupt / SystemExit propagate
+ except Exception: # let KeyboardInterrupt / SystemExit propagate
self.exception('error while indexing %s', entity)
@@ -1391,6 +1392,7 @@
source.fti_unindex_entities(cnx, to_reindex)
source.fti_index_entities(cnx, to_reindex)
+
def sql_schema(driver):
"""Yield SQL statements to create system tables in the database."""
helper = get_db_helper(driver)
@@ -1488,6 +1490,7 @@
"""set the instance'schema"""
pass
+
class LoginPasswordAuthentifier(BaseAuthentifier):
passwd_rql = 'Any P WHERE X is CWUser, X login %(login)s, X upassword P'
auth_rql = (u'Any X WHERE X is CWUser, X login %(login)s, X upassword %(pwd)s, '
@@ -1496,7 +1499,7 @@
def set_schema(self, schema):
"""set the instance'schema"""
- if 'CWUser' in schema: # probably an empty schema if not true...
+ if 'CWUser' in schema: # probably an empty schema if not true...
# rql syntax trees used to authenticate users
self._passwd_rqlst = self.source.compile_rql(self.passwd_rql, self._sols)
self._auth_rqlst = self.source.compile_rql(self.auth_rql, self._sols)
@@ -1508,7 +1511,7 @@
two queries are needed since passwords are stored crypted, so we have
to fetch the salt first
"""
- args = {'login': login, 'pwd' : None}
+ args = {'login': login, 'pwd': None}
if password is not None:
rset = self.source.syntax_tree_search(cnx, self._passwd_rqlst, args)
try:
@@ -1529,15 +1532,15 @@
# before 3.14.7), update with a fresh one
if pwd is not None and pwd.getvalue():
verify, newhash = verify_and_update(password, pwd.getvalue())
- if not verify: # should not happen, but...
+ if not verify: # should not happen, but...
raise AuthenticationError('bad password')
if newhash:
- cnx.system_sql("UPDATE %s SET %s=%%(newhash)s WHERE %s=%%(login)s" % (
- SQL_PREFIX + 'CWUser',
- SQL_PREFIX + 'upassword',
- SQL_PREFIX + 'login'),
- {'newhash': self.source._binary(newhash.encode('ascii')),
- 'login': login})
+ cnx.system_sql("UPDATE %s SET %s=%%(newhash)s WHERE %s=%%(login)s"
+ % (SQL_PREFIX + 'CWUser',
+ SQL_PREFIX + 'upassword',
+ SQL_PREFIX + 'login'),
+ {'newhash': self.source._binary(newhash.encode('ascii')),
+ 'login': login})
cnx.commit()
return user
except IndexError:
@@ -1548,11 +1551,11 @@
def authenticate(self, cnx, login, **authinfo):
# email_auth flag prevent from infinite recursion (call to
# repo.check_auth_info at the end of this method may lead us here again)
- if not '@' in login or authinfo.pop('email_auth', None):
+ if '@' not in login or authinfo.pop('email_auth', None):
raise AuthenticationError('not an email')
rset = cnx.execute('Any L WHERE U login L, U primary_email M, '
- 'M address %(login)s', {'login': login},
- build_descr=False)
+ 'M address %(login)s', {'login': login},
+ build_descr=False)
if rset.rowcount != 1:
raise AuthenticationError('unexisting email')
login = rset.rows[0][0]
@@ -1637,7 +1640,7 @@
eschema = self.schema.eschema(etype)
if eschema.final:
continue
- etype_tables.append('%s%s'%(prefix, etype))
+ etype_tables.append('%s%s' % (prefix, etype))
for rtype in self.schema.relations():
rschema = self.schema.rschema(rtype)
if rschema.final or rschema.inlined or rschema in VIRTUAL_RTYPES:
@@ -1689,7 +1692,7 @@
serialized = self._serialize(table, columns, rows)
archive.writestr('tables/%s.%04d' % (table, i), serialized)
self.logger.debug('wrote rows %d to %d (out of %d) to %s.%04d',
- start, start+len(rows)-1,
+ start, start + len(rows) - 1,
rowcount,
table, i)
else:
@@ -1795,7 +1798,6 @@
self.cnx.commit()
self.logger.info('inserted %d rows', row_count)
-
def _parse_versions(self, version_str):
versions = set()
for line in version_str.splitlines():