~divmod-dev/divmod.org/remove-addperson-2190

« back to all changes in this revision

Viewing changes to Mantissa/xmantissa/sharing.py

  • Committer: glyph
  • Date: 2007-07-25 20:05:50 UTC
  • Revision ID: svn-v4:866e43f7-fbfc-0310-8f2a-ec88d1da2979:trunk:13104
Fix {{{asAccessibleTo}}} to yield the correct results in the face of a limit.

Fixes #2189

Author: glyph, washort

Reviewer: moe

This change also adds the very beginnings of an explicit, supported query-introspection API that works with all types of queries.  Currently it only works with limit() (the only thing that was necessary for this change) but future query-manipulation logic should be added to the IQuery interface so that code will work when presented with, e.g. an AttributeQuery or one of the 'distinct' query wrappers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
514
514
    raise NoSuchShare()
515
515
 
516
516
 
 
517
 
517
518
def asAccessibleTo(role, query):
518
519
    """
 
520
    Return an iterable which yields the shared proxies that are available to
 
521
    the given role, from the given query.
 
522
 
519
523
    @param role: The role to retrieve L{SharedProxy}s for.
520
524
 
521
525
    @param query: An Axiom query describing the Items to retrieve, which this
522
526
    role can access.
 
527
    @type query: an L{iaxiom.IQuery} provider.
523
528
    """
524
 
    if query.comparison is not None:
525
 
        #XXX fix axiom to not break if an AND branch is None?
526
 
        comparison = AND(Share.sharedItem == query.tableClass.storeID,
527
 
                         Share.sharedTo.oneOf(role.allRoles()),
528
 
                         query.comparison)
529
 
    else:
530
 
        comparison = AND(Share.sharedItem == query.tableClass.storeID,
531
 
                         Share.sharedTo.oneOf(role.allRoles()))
 
529
    allRoles = list(role.allRoles())
 
530
    count = 0
 
531
    unlimited = query.cloneQuery(limit=None)
 
532
    for result in unlimited:
 
533
        allShares = list(query.store.query(
 
534
                Share,
 
535
                AND(Share.sharedItem == result,
 
536
                    Share.sharedTo.oneOf(allRoles))))
 
537
        interfaces = []
 
538
        for share in allShares:
 
539
            interfaces += share.sharedInterfaces
 
540
        if allShares:
 
541
            count += 1
 
542
            yield SharedProxy(result, interfaces, allShares[0].shareID)
 
543
            if count == query.limit:
 
544
                return
532
545
 
533
 
    lastItem = None
534
 
    lastID = None
535
 
    interfaceSpec = None
536
 
    yielded = False
537
 
    seen = set()
538
 
    for resultingShare in (query.store.query(
539
 
            Share,
540
 
            comparison,
541
 
            sort=(query.sort, Share.sharedItem.ascending),
542
 
            limit=query.limit
543
 
            )):
544
 
        yielded = False
545
 
        thisItem = resultingShare.sharedItem
546
 
        thisID = resultingShare.shareID
547
 
        if (lastItem == thisItem) and (thisID == lastID):
548
 
            interfaceSpec += resultingShare.sharedInterfaces
549
 
        else:
550
 
            if lastItem is not None:
551
 
                yielded = True
552
 
                yield SharedProxy(lastItem, interfaceSpec, lastID)
553
 
            interfaceSpec = resultingShare.sharedInterfaces[:]
554
 
        lastItem = thisItem
555
 
        lastID = thisID
556
 
    if lastItem is not None:
557
 
        yield SharedProxy(lastItem, interfaceSpec, lastID)
558
546
 
559
547
 
560
548
def itemFromProxy(obj):