def evalOrderBy(ctx, part):
res = evalPart(ctx, part.p)
for e in reversed(part.expr):
def val(x):
v = value(x, e.expr, variables=True)
if isinstance(v, Variable):
return (0, v)
elif isinstance(v, BNode):
return (1, v)
elif isinstance(v, URIRef):
return (2, v)
elif isinstance(v, Literal):
return (3, v)
reverse = bool(e.order and e.order == 'DESC')
res = sorted(res, key=val, reverse=reverse)
return res
python类Variable()的实例源码
def _addVars(x, children):
# import pdb; pdb.set_trace()
if isinstance(x, Variable):
return set([x])
elif isinstance(x, CompValue):
x["_vars"] = set(reduce(operator.or_, children, set()))
if x.name == "Bind":
return set([x.var])
elif x.name == 'SubSelect':
if x.projection:
s = set(v.var or v.evar for v in x.projection)
else:
s = set()
return s
return reduce(operator.or_, children, set())
def __init__(self, json):
self.json = json
if "boolean" in json:
type_ = 'ASK'
elif "results" in json:
type_ = 'SELECT'
else:
raise ResultException('No boolean or results in json!')
Result.__init__(self, type_)
if type_ == 'ASK':
self.askAnswer = bool(json['boolean'])
else:
self.bindings = self._get_bindings()
self.vars = [Variable(x) for x in json["head"]["vars"]]
def __len__(self, context=None):
if not self.sparql11:
raise NotImplementedError(
"For performance reasons, this is not" +
"supported for sparql1.0 endpoints")
else:
self.resetQuery()
q = "SELECT (count(*) as ?c) WHERE {?s ?p ?o .}"
if self._is_contextual(context):
self.addParameter("default-graph-uri", context.identifier)
self.setQuery(q)
doc = ElementTree.parse(SPARQLWrapper.query(self).response)
rt, vars = iter(
_traverse_sparql_result_dom(
doc,
as_dictionary=True,
node_from_result=self.node_from_result
)
).next()
return int(rt.get(Variable("c")))
def remove(self, spo, context):
""" Remove a triple from the store """
if not self.endpoint:
raise Exception("UpdateEndpoint is not set - call 'open'")
(subject, predicate, obj) = spo
if not subject:
subject = Variable("S")
if not predicate:
predicate = Variable("P")
if not obj:
obj = Variable("O")
nts = self.node_to_sparql
triple = "%s %s %s ." % (nts(subject), nts(predicate), nts(obj))
if self._is_contextual(context):
cid = nts(context.identifier)
q = "DELETE { GRAPH %s { %s } } WHERE { GRAPH %s { %s } }" % (
cid, triple,
cid, triple)
else:
q = "DELETE { %s } WHERE { %s } " % (triple, triple)
self._transaction().append(q)
if self.autocommit:
self.commit()
def test_bind():
base = "http://example.org/"
g = Graph()
g.add((URIRef(
base + "thing"), URIRef(base + "ns#comment"), Literal("anything")))
def check(expr, var, obj):
r = g.query("""
prefix : <http://example.org/ns#>
select * where { ?s ?p ?o . %s } """ % expr)
assert r.bindings[0][Variable(var)] == obj
yield (check, 'bind("thing" as ?name)', 'name', Literal("thing"))
yield (check, 'bind(<http://example.org/other> as ?other)', 'other',
URIRef("http://example.org/other"))
yield (check, "bind(:Thing as ?type)", 'type',
URIRef("http://example.org/ns#Thing"))
def test_arithmetic_var():
ctx = QueryContext()
ctx[Variable('x')] = Literal(2)
eq(_eval(_translate((p.Expression.parseString('2+?x')[0])), ctx).value, 4)
eq(_eval(_translate((p.Expression.parseString('?x+3')[0])), ctx).value, 5)
eq(_eval(_translate((p.Expression.parseString('3-?x')[0])), ctx).value, 1)
eq(_eval(_translate((p.Expression.parseString('?x*3')[0])), ctx).value, 6)
eq(_eval(_translate((p.Expression.parseString('4/?x')[0])), ctx).value, 2)
eq(_eval(_translate((p.Expression.parseString('?x+?x+?x')[0])), ctx).value, 6)
eq(_eval(_translate((p.Expression.parseString('?x-?x+?x')[0])), ctx).value, 2)
eq(_eval(_translate((p.Expression.parseString('(?x-?x)+?x')[0])), ctx).value, 2)
eq(_eval(_translate((p.Expression.parseString('?x-(?x+?x)')[0])), ctx).value, -2)
eq(_eval(_translate((p.Expression.parseString('?x*?x*?x')[0])), ctx).value, 8)
eq(_eval(_translate((p.Expression.parseString('4/?x*?x')[0])), ctx).value, 4)
eq(_eval(_translate((p.Expression.parseString('8/4*?x')[0])), ctx).value, 4)
eq(_eval(_translate((p.Expression.parseString('8/(4*?x)')[0])), ctx).value, 1)
eq(_eval(_translate((p.Expression.parseString('(?x/?x)*?x')[0])), ctx).value, 2)
eq(_eval(_translate((p.Expression.parseString('4/(?x*?x)')[0])), ctx).value, 1)
def test_comparisons_var():
ctx = QueryContext()
ctx[Variable('x')] = Literal(2)
eq(bool(_eval(_translate((p.Expression.parseString('?x<3')[0])), ctx)), True)
eq(bool(_eval(_translate((p.Expression.parseString('?x<3.0')[0])), ctx)), True)
eq(bool(_eval(_translate((p.Expression.parseString('?x<3e0')[0])), ctx)), True)
eq(bool(_eval(_translate((p.Expression.parseString('?x<2.1')[0])), ctx)), True)
eq(bool(_eval(_translate((p.Expression.parseString('?x<21e-1')[0])), ctx)), True)
eq(bool(_eval(_translate((p.Expression.parseString('?x=2.0')[0])), ctx)), True)
eq(bool(_eval(_translate((p.Expression.parseString('?x=2e0')[0])), ctx)), True)
eq(bool(_eval(_translate((p.Expression.parseString('?x="cake"')[0])), ctx)), False)
ctx = QueryContext()
ctx[Variable('x')] = Literal(4)
eq(bool(_eval(_translate((p.Expression.parseString('?x<3')[0])), ctx)), False)
eq(bool(_eval(_translate((p.Expression.parseString('?x<3.0')[0])), ctx)), False)
eq(bool(_eval(_translate((p.Expression.parseString('?x<3e0')[0])), ctx)), False)
def evalOrderBy(ctx, part):
res = evalPart(ctx, part.p)
for e in reversed(part.expr):
def val(x):
v = value(x, e.expr, variables=True)
if isinstance(v, Variable):
return (0, v)
elif isinstance(v, BNode):
return (1, v)
elif isinstance(v, URIRef):
return (2, v)
elif isinstance(v, Literal):
return (3, v)
reverse = bool(e.order and e.order == 'DESC')
res = sorted(res, key=val, reverse=reverse)
return res
def _addVars(x, children):
# import pdb; pdb.set_trace()
if isinstance(x, Variable):
return set([x])
elif isinstance(x, CompValue):
x["_vars"] = set(reduce(operator.or_, children, set()))
if x.name == "Bind":
return set([x.var])
elif x.name == 'SubSelect':
if x.projection:
s = set(v.var or v.evar for v in x.projection)
else:
s = set()
return s
return reduce(operator.or_, children, set())
def parse(self, source):
r = Result('SELECT')
if isinstance(source.read(0), py3compat.bytestype):
# if reading from source returns bytes do utf-8 decoding
source = codecs.getreader('utf-8')(source)
reader = csv.reader(source, delimiter=self.delim)
r.vars = [Variable(x) for x in reader.next()]
r.bindings = []
for row in reader:
r.bindings.append(self.parseRow(row, r.vars))
return r
def __init__(self, json):
self.json = json
if "boolean" in json:
type_ = 'ASK'
elif "results" in json:
type_ = 'SELECT'
else:
raise ResultException('No boolean or results in json!')
Result.__init__(self, type_)
if type_ == 'ASK':
self.askAnswer = bool(json['boolean'])
else:
self.bindings = self._get_bindings()
self.vars = [Variable(x) for x in json["head"]["vars"]]
def __len__(self, context=None):
if not self.sparql11:
raise NotImplementedError(
"For performance reasons, this is not" +
"supported for sparql1.0 endpoints")
else:
self.resetQuery()
q = "SELECT (count(*) as ?c) WHERE {?s ?p ?o .}"
if self._is_contextual(context):
self.addParameter("default-graph-uri", context.identifier)
self.setQuery(q)
doc = ElementTree.parse(SPARQLWrapper.query(self).response)
rt, vars = iter(
_traverse_sparql_result_dom(
doc,
as_dictionary=True,
node_from_result=self.node_from_result
)
).next()
return int(rt.get(Variable("c")))
def test_ldp_result_to_dataset(self):
result = self.mock.collection_result()
b = result.bindings
ds = self.sparql.result_to_dataset(result)
g = Variable('g')
s = Variable('s')
p = Variable('p')
o = Variable('o')
self.assertEqual(len(b), len(ds))
for d in result.bindings:
self.assertIn((d[s], d[p], d[o], d[g]), ds)
# todo: create result / dataset mocks
def result_to_dataset(result):
ds = Dataset()
for q in result.bindings:
ds.add((q[Variable('s')],q[Variable('p')],q[Variable('o')],q[Variable('g')]))
return ds
def __init__(self, s=Variable('s'), p=Variable('p'), o=Variable('o')):
self.s = s
self.p = p
self.o = o
def Builtin_COALESCE(expr, ctx):
"""
http://www.w3.org/TR/sparql11-query/#func-coalesce
"""
for x in expr.get('arg', variables=True):
if x is not None and not isinstance(x, (SPARQLError, Variable)):
return x
raise SPARQLError(
"COALESCE got no arguments that did not evaluate to an error")
def Builtin_BOUND(e, ctx):
"""
http://www.w3.org/TR/sparql11-query/#func-bound
"""
n = e.get('arg', variables=True)
return Literal(not isinstance(n, Variable))
def _knownTerms(triple, varsknown, varscount):
return (len(filter(None, (x not in varsknown and
isinstance(
x, (Variable, BNode)) for x in triple))),
-sum(varscount.get(x, 0) for x in triple),
not isinstance(triple[2], Literal),
)
def reorderTriples(l):
"""
Reorder triple patterns so that we execute the
ones with most bindings first
"""
def _addvar(term, varsknown):
if isinstance(term, (Variable, BNode)):
varsknown.add(term)
l = [(None, x) for x in l]
varsknown = set()
varscount = collections.defaultdict(int)
for t in l:
for c in t[1]:
if isinstance(c, (Variable, BNode)):
varscount[c] += 1
i = 0
# Done in steps, sort by number of bound terms
# the top block of patterns with the most bound terms is kept
# the rest is resorted based on the vars bound after the first
# block is evaluated
# we sort by decorate/undecorate, since we need the value of the sort keys
while i < len(l):
l[i:] = sorted((_knownTerms(x[
1], varsknown, varscount), x[1]) for x in l[i:])
t = l[i][0][0] # top block has this many terms bound
j = 0
while i+j < len(l) and l[i+j][0][0] == t:
for c in l[i+j][1]:
_addvar(c, varsknown)
j += 1
i += 1
return [x[1] for x in l]
def _findVars(x, res):
"""
Find all variables in a tree
"""
if isinstance(x, Variable):
res.add(x)
if isinstance(x, CompValue):
if x.name == "Bind":
res.add(x.var)
return x # stop recursion and finding vars in the expr
elif x.name == 'SubSelect':
if x.projection:
res.update(v.var or v.evar for v in x.projection)
return x
def _sample(e, v=None):
"""
For each unaggregated variable V in expr
Replace V with Sample(V)
"""
if isinstance(e, CompValue) and e.name.startswith("Aggregate_"):
return e # do not replace vars in aggregates
if isinstance(e, Variable) and v != e:
return CompValue('Aggregate_Sample', vars=e)
def translateAggregates(q, M):
E = []
A = []
# collect/replace aggs in :
# select expr as ?var
if q.projection:
for v in q.projection:
if v.evar:
v.expr = traverse(v.expr, functools.partial(_sample, v=v.evar))
v.expr = traverse(v.expr, functools.partial(_aggs, A=A))
# having clause
if traverse(q.having, _hasAggregate, complete=False):
q.having = traverse(q.having, _sample)
traverse(q.having, functools.partial(_aggs, A=A))
# order by
if traverse(q.orderby, _hasAggregate, complete=False):
q.orderby = traverse(q.orderby, _sample)
traverse(q.orderby, functools.partial(_aggs, A=A))
# sample all other select vars
# TODO: only allowed for vars in group-by?
if q.projection:
for v in q.projection:
if v.var:
rv = Variable('__agg_%d__' % (len(A) + 1))
A.append(CompValue('Aggregate_Sample', vars=v.var, res=rv))
E.append((rv, v.var))
return CompValue('AggregateJoin', A=A, p=M), E
def _get_bindings(self):
ret = []
for row in self.json['results']['bindings']:
outRow = {}
for k, v in row.items():
outRow[Variable(k)] = parseJsonTerm(v)
ret.append(outRow)
return ret
def __getitem__(self, key):
if not isinstance(key, Node):
key = Variable(key)
if not type(key) in (BNode, Variable):
return key
return self._d[key]
def value(ctx, val, variables=False, errors=False):
"""
utility function for evaluating something...
Variables will be looked up in the context
Normally, non-bound vars is an error,
set variables=True to return unbound vars
Normally, an error raises the error,
set errors=True to return error
"""
if isinstance(val, Expr):
return val.eval(ctx) # recurse?
elif isinstance(val, CompValue):
raise Exception("What do I do with this CompValue? %s" % val)
elif isinstance(val, list):
return [value(ctx, x, variables, errors) for x in val]
elif isinstance(val, (BNode, Variable)):
r = ctx.get(val)
if isinstance(r, SPARQLError) and not errors:
raise r
if r is not None:
return r
# not bound
if variables:
return val
else:
raise NotBoundError
elif isinstance(val, ParseResults) and len(val) == 1:
return value(ctx, val[0], variables, errors)
else:
return val
def _traverse_sparql_result_dom(
doc, as_dictionary=False, node_from_result=_node_from_result):
"""
Returns a generator over tuples of results
"""
# namespace handling in elementtree xpath sub-set is not pretty :(
vars_ = [
Variable(v.attrib["name"])
for v in doc.findall(
'./{http://www.w3.org/2005/sparql-results#}head/'
'{http://www.w3.org/2005/sparql-results#}variable'
)
]
for result in doc.findall(
'./{http://www.w3.org/2005/sparql-results#}results/'
'{http://www.w3.org/2005/sparql-results#}result'):
curr_bind = {}
values = []
for binding in result.findall(
'{http://www.w3.org/2005/sparql-results#}binding'):
var_val = binding.attrib["name"]
var = Variable(var_val)
term = node_from_result(binding.findall('*')[0])
values.append(term)
curr_bind[var] = term
if as_dictionary:
yield curr_bind, vars_
else:
def __locproc(values_):
if len(values_) == 1:
return values_[0]
else:
return tuple(values_)
yield __locproc(values), vars_
def contexts(self, triple=None):
"""
Iterates over results to "SELECT ?NAME { GRAPH ?NAME { ?s ?p ?o } }"
or "SELECT ?NAME { GRAPH ?NAME {} }" if triple is `None`.
Returns instances of this store with the SPARQL wrapper
object updated via addNamedGraph(?NAME).
This causes a named-graph-uri key / value pair to be sent over
the protocol.
Please note that some SPARQL endpoints are not able to find empty named
graphs.
"""
self.resetQuery()
if triple:
nts = self.node_to_sparql
s, p, o = triple
params = (nts(s if s else Variable('s')),
nts(p if p else Variable('p')),
nts(o if o else Variable('o')))
self.setQuery('SELECT ?name WHERE { GRAPH ?name { %s %s %s }}' % params)
else:
self.setQuery('SELECT ?name WHERE { GRAPH ?name {} }')
doc = ElementTree.parse(SPARQLWrapper.query(self).response)
return (
rt.get(Variable("name"))
for rt, vars in _traverse_sparql_result_dom(
doc, as_dictionary=True, node_from_result=self.node_from_result)
)
# Namespace persistence interface implementation
def testVariableKeyWithQuestionMark():
results = list(g2.query("SELECT ?o WHERE { ?s :p ?o }", initBindings={Variable("?s"): EX['s1']}))
assert len(results) == 1, results
def Builtin_COALESCE(expr, ctx):
"""
http://www.w3.org/TR/sparql11-query/#func-coalesce
"""
for x in expr.get('arg', variables=True):
if x is not None and not isinstance(x, (SPARQLError, Variable)):
return x
raise SPARQLError(
"COALESCE got no arguments that did not evaluate to an error")