from sqlalchemy import Table, Integer, BigInteger, DECIMAL, Column, String, MetaData, ForeignKey
from sqlalchemy.types import Text
from sqlalchemy.schema import Index, Sequence
-from sqlalchemy.sql import func, and_, or_, not_, null, select, bindparam, text
+from sqlalchemy.sql import func, and_, or_, not_, null, select, bindparam, text, exists
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.engine.reflection import Inspector
from dbworker import DBWorker
-from pithos.lib.filter import parse_filters, OPERATORS
+from pithos.lib.filter import parse_filters
+
ROOTNODE = 0
start = strprevling(prefix)
nextling = strnextling(prefix)
- a = self.attributes.alias('a')
v = self.versions.alias('v')
n = self.nodes.alias('n')
s = select([n.c.path, v.c.serial]).distinct()
if conj:
s = s.where(or_(*conj))
- s = s.order_by(n.c.path)
-
- def filterout(r):
- if not filterq:
- return False
- path, serial = r
+ if domain and filterq:
+ a = self.attributes.alias('a')
included, excluded, opers = parse_filters(filterq)
-
- #retrieve metadata
- meta = dict(self.attribute_get(serial, domain))
- keyset= set([k.encode('utf8') for k in meta.keys()])
-
if included:
- if not set(included) & keyset:
- return True
+ subs = select([1])
+ subs = subs.where(a.c.serial == v.c.serial).correlate(v)
+ subs = subs.where(a.c.domain == domain)
+ subs = subs.where(or_(*[a.c.key.op('=')(x) for x in included]))
+ s = s.where(exists(subs))
if excluded:
- if set(excluded) & keyset:
- return True
- for k, op, v in opers:
- k = k.decode('utf8')
- v = v.decode('utf8')
- if k not in meta:
- return True
- operation = OPERATORS[op]
- if not operation(meta[k], v):
- return True
- return False
-
+ subs = select([1])
+ subs = subs.where(a.c.serial == v.c.serial).correlate(v)
+ subs = subs.where(a.c.domain == domain)
+ subs = subs.where(or_(*[a.c.key.op('=')(x) for x in excluded]))
+ s = s.where(not_(exists(subs)))
+ if opers:
+ subs = select([1])
+ subs = subs.where(a.c.serial == v.c.serial).correlate(v)
+ subs = subs.where(a.c.domain == domain)
+ subs = subs.where(and_(*[and_(a.c.key.op('=')(k), a.c.value.op(o)(v)) for k, o, v in opers]))
+ s = s.where(exists(subs))
+
+ s = s.order_by(n.c.path)
+
if not delimiter:
s = s.limit(limit)
rp = self.conn.execute(s, start=start)
- filter_ = lambda r : [t for t in r if not filterout(t)]
- r = filter_(rp.fetchall())
+ r = rp.fetchall()
rp.close()
return r, ()
props = rp.fetchone()
if props is None:
break
- if filterout(props):
- continue
path, serial = props
idx = path.find(delimiter, pfz)