/usr/share/pyshared/axiom/queryutil.py is in python-axiom 0.7.1-2.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 | # -*- test-case-name: axiom.test.test_queryutil -*-
import operator
from axiom.attributes import AND, OR
def contains(startAttribute,
endAttribute,
value):
"""
Return an L{axiom.iaxiom.IComparison} (an object that can be
passed as the 'comparison' argument to Store.query/.sum/.count)
which will constrain a query against 2 attributes for ranges which
contain the given argument. The range is half-open.
"""
return AND(
startAttribute <= value,
value < endAttribute)
def overlapping(startAttribute, # X
endAttribute, # Y
startValue, # A
endValue, # B
):
"""
Return an L{axiom.iaxiom.IComparison} (an object that can be passed as the
'comparison' argument to Store.query/.sum/.count) which will constrain a
query against 2 attributes for ranges which overlap with the given
arguments.
For a database with Items of class O which represent values in this
configuration::
X Y
(a) (b)
|-------------------|
(c) (d)
|--------| (e) (f)
|--------|
(g) (h)
|---| (i) (j)
|------|
(k) (l)
|-------------------------------------|
(a) (l)
|-----------------------------|
(c) (b)
|------------------------|
(c) (a)
|----|
(b) (l)
|---------|
The query::
myStore.query(
O,
findOverlapping(O.X, O.Y,
a, b))
Will return a generator of Items of class O which represent segments a-b,
c-d, e-f, k-l, a-l, c-b, c-a and b-l, but NOT segments g-h or i-j.
(NOTE: If you want to pass attributes of different classes for
startAttribute and endAttribute, read the implementation of this method to
discover the additional join clauses required. This may be eliminated some
day so for now, consider this method undefined over multiple classes.)
In the database where this query is run, for an item N, all values of
N.startAttribute must be less than N.endAttribute.
startValue must be less than endValue.
"""
assert startValue <= endValue
return OR(
AND(startAttribute >= startValue,
startAttribute <= endValue),
AND(endAttribute >= startValue,
endAttribute <= endValue),
AND(startAttribute <= startValue,
endAttribute >= endValue)
)
def _tupleCompare(tuple1, ineq, tuple2,
eq=lambda a,b: (a==b),
ander=AND,
orer=OR):
"""
Compare two 'in-database tuples'. Useful when sorting by a compound key
and slicing into the middle of that query.
"""
orholder = []
for limit in range(len(tuple1)):
eqconstraint = [
eq(elem1, elem2) for elem1, elem2 in zip(tuple1, tuple2)[:limit]]
ineqconstraint = ineq(tuple1[limit], tuple2[limit])
orholder.append(ander(*(eqconstraint + [ineqconstraint])))
return orer(*orholder)
def _tupleLessThan(tuple1, tuple2):
return _tupleCompare(tuple1, operator.lt, tuple2)
def _tupleGreaterThan(tuple1, tuple2):
return _tupleCompare(tuple1, operator.gt, tuple2)
class AttributeTuple(object):
def __init__(self, *attributes):
self.attributes = attributes
def __iter__(self):
return iter(self.attributes)
def __eq__(self, other):
if not isinstance(other, (AttributeTuple, tuple, list)):
return NotImplemented
return AND(*[
myAttr == otherAttr
for (myAttr, otherAttr)
in zip(self, other)])
def __ne__(self, other):
if not isinstance(other, (AttributeTuple, tuple, list)):
return NotImplemented
return OR(*[
myAttr != otherAttr
for (myAttr, otherAttr)
in zip(self, other)])
def __gt__(self, other):
if not isinstance(other, (AttributeTuple, tuple, list)):
return NotImplemented
return _tupleGreaterThan(tuple(iter(self)), other)
def __lt__(self, other):
if not isinstance(other, (AttributeTuple, tuple, list)):
return NotImplemented
return _tupleLessThan(tuple(iter(self)), other)
def __ge__(self, other):
if not isinstance(other, (AttributeTuple, tuple, list)):
return NotImplemented
return OR(self > other, self == other)
def __le__(self, other):
if not isinstance(other, (AttributeTuple, tuple, list)):
return NotImplemented
return OR(self < other, self == other)
|