Exemplo n.º 1
0
def test_Query_hasSubQuery():
    query = q.Query('some.Toc')
    assert not query.hasSubQuery()

    query.push(foo='bar')
    assert not query.hasSubQuery()

    query.push(baz=q.Query('some.OtherToc'))
    assert query.hasSubQuery()
Exemplo n.º 2
0
    def test_comparison_mangling(self):
        query = q.Query(self.toc, foo=q.GreaterEq(1))
        mongo = query.mongo()
        assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                         'foo': {'$gte': 1}}

        query = q.Query(self.toc, str=q.GreaterEq('aaa'))
        mongo = query.mongo()
        assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                         'str': {'$gte': 'aaa'}}
Exemplo n.º 3
0
 def test_id_empty(self):
     # this will of course never find any tois, but the query is
     # possible to ask
     query = q.Query(self.toc, id=None)
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      '_id': {'$in': [None, [], {}]}}
Exemplo n.º 4
0
def test_lateValidation():
    """
    Test that you can populate a Query using strings and run the
    validation afterwards
    """

    y = q.Query('myToc', myStr="foo", myBool=True)
    assert y.toc is None
    assert y.tocName == 'myToc'
    for attr in list(y[0].keys()):
        assert isinstance(attr, str)
    y[0].customAttribute = 'testing'
    
    class myToc(TO):
        class myStr(LimitedString()):
            pass
        class myBool(Bool()):
            pass

    py.test.raises(RuntimeError, y.validate) # Couldn't find TOC
    y.toc = myToc
    y.validate()
    assert y.toc == myToc
    for attr in list(y[0].keys()):
        assert isinstance(attr, Attribute)
    assert y[0].customAttribute == 'testing'
Exemplo n.º 5
0
 def test_Now_bson(self):
     now = q.Now(-10)
     now.evaluate = lambda when=None: 100
     query = q.Query(self.toc, baz=q.LessEq(now))
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      'baz': {'$lte': 100}}
Exemplo n.º 6
0
    def test_serializable(self):
        from pytransact import query as Query
        attr = Serializable._instantiate('foo')

        for val in (1, [1, 2, 3], Query.Query('Foo')):
            v = attr.coerceValue(val)
            assert v is val
Exemplo n.º 7
0
 def test_toiref_empty(self):
     from bson.objectid import ObjectId
     oid = ObjectId()
     query = q.Query(self.toc, bar=None)
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      'bar': {'$in': [None, [], {}]}
                      }
Exemplo n.º 8
0
 def test_toiref_exact(self):
     from bson.objectid import ObjectId
     oid = ObjectId()
     query = q.Query(self.toc, bar=q.Exact([oid]))
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      'bar.id': {'$all' : [oid], '$size' : 1}
                      }
Exemplo n.º 9
0
 def test_toiref_noneof(self):
     from bson.objectid import ObjectId
     oid = ObjectId()
     query = q.Query(self.toc, bar=q.NoneOf([str(oid)]))
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      '$nor' : [{ 'bar.id': oid }]
                      }
Exemplo n.º 10
0
 def test_NoneOfMap(self):
     query = q.Query(self.toc, map=q.NoneOfMap('apa', [27, 42]))
     mongo = query.mongo()
     assert (mongo == {'_bases': {'$in': [self.toc._fullname]},
                       '$nor': [{'map.apa': 42}, {'map.apa': 27}] }
             or
             mongo == {'_bases': {'$in': [self.toc._fullname]},
                       '$nor': [{'map.apa': 27}, {'map.apa': 42}] })
Exemplo n.º 11
0
 def test_id(self):
     from bson.objectid import ObjectId
     oid = ObjectId()
     query = q.Query(self.toc, id=oid)
     mongo = query.mongo()
     # id -> _id
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      '_id': {'$in': [oid]}
                      }
Exemplo n.º 12
0
    def test_special_case_op(self):
        query = q.Query(self.toc)
        query.clear()
        query.pushDict({'foo': [q.In([27, 42]), q.Empty()]})
        mongo = query.mongo()

        # xxx Empty overrides In
        assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                         'foo': {'$in': [None, [], {}]}}
Exemplo n.º 13
0
def test_Query_hasFulltext():
    query = q.Query('some.Toc')
    assert not query.hasFulltext()

    query.push(foo='bar')
    assert not query.hasFulltext()

    query.push(id=q.Fulltext('some.OtherToc'))
    assert query.hasFulltext()
Exemplo n.º 14
0
def test_Query_copy():
    query = q.Query('some.Toc')
    query.push(foo='bar')
    query.attrList = {'foo'}

    copy = query.copy()

    assert copy == query
    assert copy.attrList == query.attrList
Exemplo n.º 15
0
 def test_Now_between_bson(self):
     now = q.Now(-10)
     now.evaluate = lambda when=None: 100
     then = q.Now(-50)
     then.evaluate = lambda when=None: 50
     query = q.Query(self.toc, baz=q.Between(then,now))
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      'baz': { '$elemMatch' : { '$gte' : 50, '$lte': 100 }}}
Exemplo n.º 16
0
    def test_condgroups(self):
        query = q.Query(self.toc)
        query.clear()
        query.push(foo=[27, 42])
        query.push(foo=[66, 666])
        mongo = query.mongo()

        assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                         '$or': [{'foo': {'$in': uolist([27, 42])}},
                                 {'foo': {'$in': uolist([66, 666])}}]
                         }
Exemplo n.º 17
0
def test_Query_behaves_list_like():
    query = q.Query('some.Toc')

    assert len(query) == 1 # one empty cond group
    list(query) # don't explode

    query.append('blah')
    assert query[-1] == 'blah'

    query[:] = []
    assert len(query) == 0
Exemplo n.º 18
0
def test_OperatorTypeEnforcement():
    "Test that attributes verify operator types"

    class myToc(TO):
        class myAttr(Bool()):
            pass

    y = q.Query(myToc, myAttr=q.Empty())

    def spam():
        y = q.Query(myToc, myAttr=q.Greater(23))

    py.test.raises(TypeError, spam)
Exemplo n.º 19
0
def test_defaultOperator():
    class myToc(TO):
        class myStr(LimitedString()):
            pass
        class myMap(StringMap()):
            pass

    y = q.Query(myToc, myStr="foo", myMap=('foo','bar'))
    
    y.toc = myToc
    y.validate()
    assert y.toc == myToc
    for attr in list(y[0].keys()):
        assert isinstance(attr, Attribute)
    assert isinstance(y[0][myToc.myMap][0], q.InMap)
    assert isinstance(y[0][myToc.myStr][0], q.In)
Exemplo n.º 20
0
def test_serializable():
    from pytransact import query as Query
    from pytransact.object.restriction import Quantity

    calls = []

    class Foo(TO):
        @method(None)
        def bar(toi, arg=Serializable(Quantity(1))):
            calls.append((toi, arg[0]))

    foo = Foo()
    for val in (1, [1, 2, 3], Query.Query('Foo')):
        foo.bar([val])
        x = calls.pop()
        assert x[0] is foo
        assert x[1] is val
Exemplo n.º 21
0
    def test_toiref(self):
        from bson.objectid import ObjectId
        oid = ObjectId()
        query = q.Query(self.toc, bar=oid)
        mongo = query.mongo()
        assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                         'bar.id': {'$in': [oid]}
                         }

        # again, with an op value that is (well, looks like) a toi
        class FakeToi(object):
            def __init__(self, id):
                self.id = tuple(id)
        op = list(query[0].items())[0][1][0] # fishing... oh, well
        op.value = set([FakeToi(id=op.value)])
        mongo = query.mongo()
        assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                         'bar.id': {'$in': [oid]}
                         }
Exemplo n.º 22
0
 def test_decode_simple_query(self):
     data = json.dumps({
         '_cls_':
         'Query',
         'toc':
         'Foo',
         'cgs': [{
             '_cls_': 'ConditionGroup',
             'a': [{
                 '_cls_': 'Like',
                 'value': 'abc*'
             }],
             'b': [{
                 '_cls_': 'Between',
                 'value': [1, 2]
             }]
         }]
     })
     decoded = self.decoder.decode(data)
     query = q.Query('Foo', a=q.Like('abc*'), b=q.Between(1, 2))
     assert decoded == query
Exemplo n.º 23
0
    def _run(self, params, state):
        criteria = params['criteria']
        sorting = params.get('sorting')
        clientAttrs = set(params.get('attrList', []))
        neededAttrs = set(clientAttrs)

        if sorting:
            sortingAttrs = getattr(criteria.toc, 'sort_%s_attrs' % sorting, [])
            neededAttrs.update(sortingAttrs)

        for attrName in neededAttrs.copy():
            attr = getattr(criteria.toc, attrName)
            extra = getattr(attr, 'extraAttrs', [])
            neededAttrs.update(extra)

        criteria.attrList = neededAttrs

        changedIds =  self.link.get('outdatedToids', [])
        optimize = bool(state and
                        not criteria.hasSubQuery() and
                        not criteria.hasFulltext() and
                        (changedIds or 'update' in state))
        start = time.time()
        if optimize:
            log.debug('Using optimized sorted query recalculation for %s', self)
            tois = set()
            for toid, attrData in state['tois'].items():
                toi = criteria.toc._create(toid, kw=attrData) # xxx
                tois.add(toi)

            if changedIds:
                changedToisQuery = query.Query(criteria.toc, id=changedIds)
                changedToisQuery.attrList = neededAttrs
                changedTois = ContextBroker().runQuery(changedToisQuery)
            else:
                changedTois = []

            def getter(toi, attr):
                if attr == 'id':
                    return list(map(str, toi.id))
                value = getattr(toi, attr.name).value
                if isinstance(attr, Attribute.ToiRef):
                    # Code fighting code:
                    # The conds for toiref attributes will contain
                    # sets of unicode strings representing toids.
                    # The .matches() of respective operators mostly
                    # use set matching operators, so we need to spit
                    # out objects with the same hash as what's in the
                    # conds - thus TOIs themselves are no good.
                    value = [str(toi.id[0]) for toi in value]
                return value

            unhandled = set(changedIds)
            for changedToi in changedTois:
                unhandled.discard(changedToi.id[0])
                if criteria.matches(changedToi, getter):
                    tois.add(changedToi)
                else:
                    tois.discard(changedToi)
            # toids left in unhandled have been removed
            tois = [toi for toi in tois if toi.id[0] not in unhandled]
        else:
            tois = ContextBroker().runQuery(criteria)
        end = time.time()
        _state = state or {}
        opt_log.debug('%s %f %d %d %s %s', optimize, end - start,
                      len(_state.get('tois', [])), len(tois),
                      bool(self.link.get('outdatedBy')), self)

        if sorting:
            sorter = getattr(criteria.toc, 'sort_'+sorting+'_key')
            #import pdb;pdb.set_trace()
            tois.sort(key=sorter)

        persistent = params.get('subscription')

        toiDiffs = {}
        state = state or { 'query': [], 'tois' : {} }
        result = { 'query' : tois, 'tois' : {}, 'order': [] }
        newBlobVals = set()
        for toi in tois:
            diffOb = difftoi.DiffTOI()
            clientData = dict((x, getattr(toi, x).value) for x in clientAttrs)
            neededData = dict((x, getattr(toi, x).value) for x in neededAttrs)
            toid = str(toi.id[0])
            result['tois'][toid] = neededData
            result['order'].append(toid)

            diffOb.setDiff(toi.__class__, toid,
                           state['tois'].get(toid,{}), {}, clientData, {})
            if diffOb.diffAttrs:
                toiDiffs[toid] = diffOb

                for value in reduce(concat_values,
                                    iter(diffOb.diffAttrs.values()), []):
                    if isinstance(value, Attribute.BlobVal):
                        value.addref(self.clientId)
                        newBlobVals.add(value)

                for value in reduce(concat_values,
                                    iter(diffOb.orgAttrs.values()), []):
                    if isinstance(value, Attribute.BlobVal):
                        value.addref(self.clientId)

        oldBlobVals = set()
        for toid, attrData in state['tois'].items():
            for value in reduce(concat_values, iter(attrData.values()), []):
                if isinstance(value, Attribute.BlobVal):
                    oldBlobVals.add(value)

        for blobVal in newBlobVals - oldBlobVals:
            blobVal.addref(self.link['_id'])

        for blobVal in oldBlobVals - newBlobVals:
            blobVal.delref(self.link['_id'])

        update = None
        if state != result:
            log.debug('Updating %s', self)
            diffops = diff.diff_opcodes(state['query'], tois)
            update = { 'diffops' : diffops,
                       'toiDiffs' : toiDiffs,
                       'error': None }
        def updatelink(doc):
            doc.setdefault('$set', {})['outdatedToids'] = []
        self.update(update, persistent, updatelink)
        if persistent:
            self.save(params, result)
Exemplo n.º 24
0
 def test_empty(self):
     query = q.Query('Foo')
     self.check_hashable(
         query,
         frozenset([('_bases', frozenset([('$in', ('Foo',))]))])
     )
Exemplo n.º 25
0
 def test_LacksKey(self):
     query = q.Query(self.toc, map=q.LacksKey('foo'))
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      'map.foo': { '$exists' : False }}
Exemplo n.º 26
0
 def test_nor(self):
     query = q.Query(self.toc, foo=q.NoneOf([1,2]))
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      '$nor': [ { 'foo' : 1 }, { 'foo' : 2} ] }
Exemplo n.º 27
0
 def test_fulltext(self):
     query = q.Query(self.toc, id=q.Fulltext('foo Bar'))
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      '_terms.data': {'$all' : ['bar', 'foo']}
                      }
Exemplo n.º 28
0
 def test_empty_TO(self):
     query = q.Query(TO)
     mongo = query.mongo()
     assert mongo == {}
Exemplo n.º 29
0
 def test_simple(self):
     query = q.Query(self.toc, foo=[27, 42])
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      'foo': {'$in': uolist([27, 42])}
                      }
Exemplo n.º 30
0
 def test_coercevalue(self):
     query = q.Query(self.toc, foo=['27', '42'])
     mongo = query.mongo()
     assert mongo == {'_bases': {'$in': [self.toc._fullname]},
                      'foo': {'$in': uolist([27, 42])}
                      }