--- a/server/querier.py Wed Jan 29 15:55:21 2014 +0100
+++ b/server/querier.py Wed Jan 29 15:29:49 2014 +0100
@@ -64,16 +64,16 @@
if etype == 'Password':
raise Unauthorized('Password selection is not allowed (%s)' % var)
-def term_etype(session, term, solution, args):
+def term_etype(cnx, term, solution, args):
"""return the entity type for the given term (a VariableRef or a Constant
node)
"""
try:
return solution[term.name]
except AttributeError:
- return session.entity_metas(term.eval(args))['type']
+ return cnx.entity_metas(term.eval(args))['type']
-def check_read_access(session, rqlst, solution, args):
+def check_read_access(cnx, rqlst, solution, args):
"""Check that the given user has credentials to access data read by the
query and return a dict defining necessary "local checks" (i.e. rql
expression in read permission defined in the schema) where no group grants
@@ -86,7 +86,7 @@
# when used as an external source by another repository.
# XXX what about local read security w/ those rewritten constants...
DBG = (server.DEBUG & server.DBG_SEC) and 'read' in server._SECURITY_CAPS
- schema = session.repo.schema
+ schema = cnx.repo.schema
if rqlst.where is not None:
for rel in rqlst.where.iget_nodes(Relation):
# XXX has_text may have specific perm ?
@@ -94,37 +94,37 @@
continue
rschema = schema.rschema(rel.r_type)
if rschema.final:
- eschema = schema.eschema(term_etype(session, rel.children[0],
+ eschema = schema.eschema(term_etype(cnx, rel.children[0],
solution, args))
rdef = eschema.rdef(rschema)
else:
- rdef = rschema.rdef(term_etype(session, rel.children[0],
+ rdef = rschema.rdef(term_etype(cnx, rel.children[0],
solution, args),
- term_etype(session, rel.children[1].children[0],
+ term_etype(cnx, rel.children[1].children[0],
solution, args))
- if not session.user.matching_groups(rdef.get_groups('read')):
+ if not cnx.user.matching_groups(rdef.get_groups('read')):
if DBG:
print ('check_read_access: %s %s does not match %s' %
- (rdef, session.user.groups, rdef.get_groups('read')))
+ (rdef, cnx.user.groups, rdef.get_groups('read')))
# XXX rqlexpr not allowed
raise Unauthorized('read', rel.r_type)
if DBG:
print ('check_read_access: %s %s matches %s' %
- (rdef, session.user.groups, rdef.get_groups('read')))
+ (rdef, cnx.user.groups, rdef.get_groups('read')))
localchecks = {}
# iterate on defined_vars and not on solutions to ignore column aliases
for varname in rqlst.defined_vars:
eschema = schema.eschema(solution[varname])
if eschema.final:
continue
- if not session.user.matching_groups(eschema.get_groups('read')):
+ if not cnx.user.matching_groups(eschema.get_groups('read')):
erqlexprs = eschema.get_rqlexprs('read')
if not erqlexprs:
ex = Unauthorized('read', solution[varname])
ex.var = varname
if DBG:
print ('check_read_access: %s %s %s %s' %
- (varname, eschema, session.user.groups, eschema.get_groups('read')))
+ (varname, eschema, cnx.user.groups, eschema.get_groups('read')))
raise ex
# don't insert security on variable only referenced by 'NOT X relation Y' or
# 'NOT EXISTS(X relation Y)'
@@ -144,21 +144,21 @@
class ExecutionPlan(object):
"""the execution model of a rql query, composed of querier steps"""
- def __init__(self, querier, rqlst, args, session):
+ def __init__(self, querier, rqlst, args, cnx):
# original rql syntax tree
self.rqlst = rqlst
self.args = args or {}
- # session executing the query
- self.session = session
+ # cnx executing the query
+ self.cnx = cnx
# quick reference to the system source
- self.syssource = session.repo.system_source
+ self.syssource = cnx.repo.system_source
# execution steps
self.steps = []
# various resource accesors
self.querier = querier
self.schema = querier.schema
self.sqlannotate = querier.sqlgen_annotate
- self.rqlhelper = session.vreg.rqlhelper
+ self.rqlhelper = cnx.vreg.rqlhelper
def annotate_rqlst(self):
if not self.rqlst.annotated:
@@ -169,7 +169,7 @@
self.steps.append(step)
def sqlexec(self, sql, args=None):
- return self.syssource.sqlexec(self.session, sql, args)
+ return self.syssource.sqlexec(self.cnx, sql, args)
def execute(self):
"""execute a plan and return resulting rows"""
@@ -184,15 +184,15 @@
return rqlst to actually execute
"""
cached = None
- if security and self.session.read_security:
+ if security and self.cnx.read_security:
# ensure security is turned of when security is inserted,
# else we may loop for ever...
- if self.session.transaction_data.get('security-rqlst-cache'):
+ if self.cnx.transaction_data.get('security-rqlst-cache'):
key = self.cache_key
else:
key = None
- if key is not None and key in self.session.transaction_data:
- cachedunion, args = self.session.transaction_data[key]
+ if key is not None and key in self.cnx.transaction_data:
+ cachedunion, args = self.cnx.transaction_data[key]
union.children[:] = []
for select in cachedunion.children:
union.append(select)
@@ -201,10 +201,10 @@
self.args = args
cached = True
else:
- with self.session.security_enabled(read=False):
+ with self.cnx.security_enabled(read=False):
noinvariant = self._insert_security(union)
if key is not None:
- self.session.transaction_data[key] = (union, self.args)
+ self.cnx.transaction_data[key] = (union, self.args)
else:
noinvariant = ()
if cached is None:
@@ -221,7 +221,7 @@
self._insert_security(subquery.query)
localchecks, restricted = self._check_permissions(select)
if any(localchecks):
- self.session.rql_rewriter.insert_local_checks(
+ self.cnx.rql_rewriter.insert_local_checks(
select, self.args, localchecks, restricted, noinvariant)
return noinvariant
@@ -243,12 +243,12 @@
Note rqlst should not have been simplified at this point.
"""
- session = self.session
+ cnx = self.cnx
msgs = []
# dict(varname: eid), allowing to check rql expression for variables
# which have a known eid
varkwargs = {}
- if not session.transaction_data.get('security-rqlst-cache'):
+ if not cnx.transaction_data.get('security-rqlst-cache'):
for var in rqlst.defined_vars.itervalues():
if var.stinfo['constnode'] is not None:
eid = var.stinfo['constnode'].eval(self.args)
@@ -259,10 +259,10 @@
newsolutions = []
for solution in rqlst.solutions:
try:
- localcheck = check_read_access(session, rqlst, solution, self.args)
+ localcheck = check_read_access(cnx, rqlst, solution, self.args)
except Unauthorized as ex:
msg = 'remove %s from solutions since %s has no %s access to %s'
- msg %= (solution, session.user.login, ex.args[0], ex.args[1])
+ msg %= (solution, cnx.user.login, ex.args[0], ex.args[1])
msgs.append(msg)
LOGGER.info(msg)
else:
@@ -277,10 +277,10 @@
# if entity has been added in the current transaction, the
# user can read it whatever rql expressions are associated
# to its type
- if session.added_in_transaction(eid):
+ if cnx.added_in_transaction(eid):
continue
for rqlexpr in rqlexprs:
- if rqlexpr.check(session, eid):
+ if rqlexpr.check(cnx, eid):
break
else:
raise Unauthorized('No read acces on %r with eid %i.' % (var, eid))
@@ -316,8 +316,8 @@
"""an execution model specific to the INSERT rql query
"""
- def __init__(self, querier, rqlst, args, session):
- ExecutionPlan.__init__(self, querier, rqlst, args, session)
+ def __init__(self, querier, rqlst, args, cnx):
+ ExecutionPlan.__init__(self, querier, rqlst, args, cnx)
# save originaly selected variable, we may modify this
# dictionary for substitution (query parameters)
self.selected = rqlst.selection
@@ -415,17 +415,17 @@
if there is two entities matching U, the result set will look like
[(eidX1, eidY1), (eidX2, eidY2)]
"""
- session = self.session
- repo = session.repo
+ cnx = self.cnx
+ repo = cnx.repo
results = []
for row in self.e_defs:
- results.append([repo.glob_add_entity(session, edef)
+ results.append([repo.glob_add_entity(cnx, edef)
for edef in row])
return results
def insert_relation_defs(self):
- session = self.session
- repo = session.repo
+ cnx = self.cnx
+ repo = cnx.repo
edited_entities = {}
relations = {}
for subj, rtype, obj in self.relation_defs():
@@ -440,7 +440,7 @@
obj = obj.entity.eid
if repo.schema.rschema(rtype).inlined:
if subj not in edited_entities:
- entity = session.entity_from_eid(subj)
+ entity = cnx.entity_from_eid(subj)
edited = EditedEntity(entity)
edited_entities[subj] = edited
else:
@@ -451,9 +451,9 @@
relations[rtype].append((subj, obj))
else:
relations[rtype] = [(subj, obj)]
- repo.glob_add_relations(session, relations)
+ repo.glob_add_relations(cnx, relations)
for edited in edited_entities.itervalues():
- repo.glob_update_entity(session, edited)
+ repo.glob_update_entity(cnx, edited)
class QuerierHelper(object):
@@ -495,13 +495,13 @@
except UnicodeError:
raise RQLSyntaxError(rql)
- def plan_factory(self, rqlst, args, session):
+ def plan_factory(self, rqlst, args, cnx):
"""create an execution plan for an INSERT RQL query"""
if rqlst.TYPE == 'insert':
- return InsertPlan(self, rqlst, args, session)
- return ExecutionPlan(self, rqlst, args, session)
+ return InsertPlan(self, rqlst, args, cnx)
+ return ExecutionPlan(self, rqlst, args, cnx)
- def execute(self, session, rql, args=None, build_descr=True):
+ def execute(self, cnx, rql, args=None, build_descr=True):
"""execute a rql query, return resulting rows and their description in
a `ResultSet` object
@@ -535,7 +535,7 @@
# if there are some, we need a better cache key, eg (rql +
# entity type of each eid)
try:
- cachekey = self._repo.querier_cache_key(session, rql,
+ cachekey = self._repo.querier_cache_key(cnx, rql,
args, eidkeys)
except UnknownEid:
# we want queries such as "Any X WHERE X eid 9999"
@@ -551,7 +551,7 @@
# which are eids. Notice that if you may not need `eidkeys`, we
# have to compute solutions anyway (kept as annotation on the
# tree)
- eidkeys = self.solutions(session, rqlst, args)
+ eidkeys = self.solutions(cnx, rqlst, args)
except UnknownEid:
# we want queries such as "Any X WHERE X eid 9999" return an
# empty result instead of raising UnknownEid
@@ -559,19 +559,19 @@
if args and rql not in self._rql_ck_cache:
self._rql_ck_cache[rql] = eidkeys
if eidkeys:
- cachekey = self._repo.querier_cache_key(session, rql, args,
+ cachekey = self._repo.querier_cache_key(cnx, rql, args,
eidkeys)
self._rql_cache[cachekey] = rqlst
orig_rqlst = rqlst
if rqlst.TYPE != 'select':
- if session.read_security:
+ if cnx.read_security:
check_no_password_selected(rqlst)
- # write query, ensure session's mode is 'write' so connections won't
- # be released until commit/rollback
- session.mode = 'write'
+ # write query, ensure connection's mode is 'write' so connections
+ # won't be released until commit/rollback
+ cnx.mode = 'write'
cachekey = None
else:
- if session.read_security:
+ if cnx.read_security:
for select in rqlst.children:
check_no_password_selected(select)
# on select query, always copy the cached rqlst so we don't have to
@@ -585,7 +585,7 @@
cachekey += tuple(sorted([k for k, v in args.iteritems()
if v is None]))
# make an execution plan
- plan = self.plan_factory(rqlst, args, session)
+ plan = self.plan_factory(rqlst, args, cnx)
plan.cache_key = cachekey
self._planner.build_plan(plan)
# execute the plan
@@ -597,11 +597,11 @@
#
# notes:
# * we should not reset the connections set here, since we don't want the
- # session to loose it during processing
+ # connection to loose it during processing
# * don't rollback if we're in the commit process, will be handled
- # by the session
- if session.commit_state is None:
- session.commit_state = 'uncommitable'
+ # by the connection
+ if cnx.commit_state is None:
+ cnx.commit_state = 'uncommitable'
raise
# build a description for the results if necessary
descr = ()
@@ -616,14 +616,14 @@
descr = RepeatList(len(results), tuple(description))
else:
# hard, delegate the work :o)
- descr = manual_build_descr(session, rqlst, args, results)
+ descr = manual_build_descr(cnx, rqlst, args, results)
elif rqlst.TYPE == 'insert':
# on insert plan, some entities may have been auto-casted,
# so compute description manually even if there is only
# one solution
basedescr = [None] * len(plan.selected)
todetermine = zip(xrange(len(plan.selected)), repeat(False))
- descr = _build_descr(session, results, basedescr, todetermine)
+ descr = _build_descr(cnx, results, basedescr, todetermine)
# FIXME: get number of affected entities / relations on non
# selection queries ?
# return a result set object
@@ -639,7 +639,7 @@
set_log_methods(QuerierHelper, LOGGER)
-def manual_build_descr(tx, rqlst, args, result):
+def manual_build_descr(cnx, rqlst, args, result):
"""build a description for a given result by analysing each row
XXX could probably be done more efficiently during execution of query
@@ -663,11 +663,11 @@
basedescr.append(ttype)
if not todetermine:
return RepeatList(len(result), tuple(basedescr))
- return _build_descr(tx, result, basedescr, todetermine)
+ return _build_descr(cnx, result, basedescr, todetermine)
-def _build_descr(tx, result, basedescription, todetermine):
+def _build_descr(cnx, result, basedescription, todetermine):
description = []
- entity_metas = tx.entity_metas
+ entity_metas = cnx.entity_metas
todel = []
for i, row in enumerate(result):
row_descr = basedescription[:]
@@ -683,7 +683,7 @@
try:
row_descr[index] = entity_metas(value)['type']
except UnknownEid:
- tx.error('wrong eid %s in repository, you should '
+ cnx.error('wrong eid %s in repository, you should '
'db-check the database' % value)
todel.append(i)
break
--- a/server/ssplanner.py Wed Jan 29 15:55:21 2014 +0100
+++ b/server/ssplanner.py Wed Jan 29 15:29:49 2014 +0100
@@ -68,13 +68,13 @@
"""return a dict mapping rqlst variable object to their eid if specified in
the syntax tree
"""
- session = plan.session
+ cnx = plan.cnx
if rqlst.where is None:
return {}
eidconsts = {}
- neweids = session.transaction_data.get('neweids', ())
- checkread = session.read_security
- eschema = session.vreg.schema.eschema
+ neweids = cnx.transaction_data.get('neweids', ())
+ checkread = cnx.read_security
+ eschema = cnx.vreg.schema.eschema
for rel in rqlst.where.get_nodes(Relation):
# only care for 'eid' relations ...
if (rel.r_type == 'eid'
@@ -89,9 +89,9 @@
# the generated select substep if not emited (eg nothing
# to be selected)
if checkread and eid not in neweids:
- with session.security_enabled(read=False):
- eschema(session.entity_metas(eid)['type']).check_perm(
- session, 'read', eid=eid)
+ with cnx.security_enabled(read=False):
+ eschema(cnx.entity_metas(eid)['type']).check_perm(
+ cnx, 'read', eid=eid)
eidconsts[lhs.variable] = eid
return eidconsts
@@ -151,11 +151,11 @@
"""get an execution plan from an INSERT RQL query"""
# each variable in main variables is a new entity to insert
to_build = {}
- session = plan.session
- etype_class = session.vreg['etypes'].etype_class
+ cnx = plan.cnx
+ etype_class = cnx.vreg['etypes'].etype_class
for etype, var in rqlst.main_variables:
# need to do this since entity class is shared w. web client code !
- to_build[var.name] = EditedEntity(etype_class(etype)(session))
+ to_build[var.name] = EditedEntity(etype_class(etype)(cnx))
plan.add_entity_def(to_build[var.name])
# add constant values to entity def, mark variables to be selected
to_select = _extract_const_attributes(plan, rqlst, to_build)
@@ -353,7 +353,7 @@
source for each solution
"""
self.execute_children()
- session = self.plan.session
+ cnx = self.plan.cnx
args = self.plan.args
inputmap = self.inputmap
union = self.union
@@ -370,8 +370,8 @@
else:
cachekey = union.as_string()
# get results for query
- source = session.repo.system_source
- result = source.syntax_tree_search(session, union, args, cachekey, inputmap)
+ source = cnx.repo.system_source
+ result = source.syntax_tree_search(cnx, union, args, cachekey, inputmap)
#print 'ONEFETCH RESULT %s' % (result)
return result
@@ -466,8 +466,8 @@
results = self.execute_child()
if results:
todelete = frozenset(int(eid) for eid, in results)
- session = self.plan.session
- session.repo.glob_delete_entities(session, todelete)
+ cnx = self.plan.cnx
+ cnx.repo.glob_delete_entities(cnx, todelete)
return results
class DeleteRelationsStep(Step):
@@ -479,10 +479,10 @@
def execute(self):
"""execute this step"""
- session = self.plan.session
- delete = session.repo.glob_delete_relation
+ cnx = self.plan.cnx
+ delete = cnx.repo.glob_delete_relation
for subj, obj in self.execute_child():
- delete(session, subj, self.rtype, obj)
+ delete(cnx, subj, self.rtype, obj)
class UpdateStep(Step):
@@ -496,8 +496,8 @@
def execute(self):
"""execute this step"""
- session = self.plan.session
- repo = session.repo
+ cnx = self.plan.cnx
+ repo = cnx.repo
edefs = {}
relations = {}
# insert relations
@@ -515,7 +515,7 @@
try:
edited = edefs[eid]
except KeyError:
- edef = session.entity_from_eid(eid)
+ edef = cnx.entity_from_eid(eid)
edefs[eid] = edited = EditedEntity(edef)
edited.edited_attribute(str(rschema), rhsval)
else:
@@ -526,9 +526,9 @@
relations[str_rschema] = [(lhsval, rhsval)]
result[i] = newrow
# update entities
- repo.glob_add_relations(session, relations)
+ repo.glob_add_relations(cnx, relations)
for eid, edited in edefs.iteritems():
- repo.glob_update_entity(session, edited)
+ repo.glob_update_entity(cnx, edited)
return result
def _handle_relterm(info, row, newrow):