Ejemplo n.º 1
0
class Table(ZopeDict):
    """
    A table is a combination of a ZopeDict and a RepozeCatalog
    with integer keys and object values
    """

    #TODO write my own IOBTree/Length combination instead of using ZopeDict?
    def __init__(self, parent, indices=None):
        ZopeDict.__init__(self)
        self.__parent__ = parent
        parent[self.__name__] = self
        self._cat = Catalog()
        if indices is None:
            self._currentIndex = ""
        else:
            self._currentIndex = indices[0]
            for index in indices:
                self._cat[index] = CatalogFieldIndex(index)

    def getCurrentIndex(self):
        # FIXME current index should be part of the user preferences
        return self._cat[self._currentIndex]

    def delete(self, names):
        print "TODO delete"
        pass

    def getFromIndex(self, index, target):
        # TODO return a generator instead of a list
        retval = []
        result = self._cat.query(Eq(index, target))
        for key in result[1]:
            user = self.get(key)
            if user:
                retval.append(user)
        return retval

    def maxKey(self):
        return self._data.maxKey() if len(self) else 0

    # NB I have to cast key to an int for traversal to work
    # FIXME: it seems like this is the wrong place for this maybe it
    # is a sign I should give up on traversal altogether?
    def __getitem__(self, key):
        return self._data[int(key)]

    def setdefault(self, key, failobj=None):
        return ZopeDict.setdefault(self, int(key), failobj)

    def has_key(self, key):
        return ZopeDict.has_key(self, int(key))

    def get(self, key, failobj=None):
        return ZopeDict.get(self, int(key), failobj)

    def __contains__(self, key):
        return ZopeDict.__contains__(self, int(key))

    # zc.dict interface
    # Addition is done with __setitem__, overriding it will control addition.
    def __setitem__(self, key, value):
        #self._cat.index_doc(int(key), value)
        ZopeDict.__setitem__(self, int(key), value)

    #TODO find a way to do efficient automatic re-indexing
    # can't see that I can do better than Plone though
    # http://developer.plone.org/searching_and_indexing/indexing.html#when-indexing-happens-and-how-to-reindex-manually
    def reindex(self, value):
        self._cat.index_doc(value.key, value)

    # Removal is done with either pop or clear, overriding these methods will
    # control removal.
    def pop(self, key, *args):
        retval = ZopeDict.pop(self, int(key), *args)
        self._cat.unindex_doc(int(key))
        return retval

    def clear(self):
        ZopeDict.clear(self)
        self._cat.clear()
Ejemplo n.º 2
0
 def clear(self):
     """ Clear all indexes in this catalog. """
     _Catalog.clear(self)
     self.objectids = self.family.IF.TreeSet()
Ejemplo n.º 3
0
class Table(ZopeDict):
    """
    A table is a combination of a ZopeDict and a RepozeCatalog
    with integer keys and object values
    """
    #TODO write my own IOBTree/Length combination instead of using ZopeDict?
    def __init__(self, parent, indices=None):
        ZopeDict.__init__(self)
        self.__parent__  = parent
        parent[self.__name__] = self
        self._cat = Catalog()
        if indices is None:
            self._currentIndex = ""
        else:
            self._currentIndex = indices[0]
            for index in indices:
                self._cat[index] = CatalogFieldIndex(index)

    def getCurrentIndex(self):
        # FIXME current index should be part of the user preferences
        return self._cat[self._currentIndex]

    def delete(self, names):
        print "TODO delete"
        pass

    def getFromIndex(self, index, target):
        # TODO return a generator instead of a list
        retval = []
        result = self._cat.query(Eq(index, target))
        for key in result[1]:
            user = self.get(key)
            if user:
                retval.append(user)
        return retval

    def maxKey(self):
        return self._data.maxKey() if len(self) else 0


    # NB I have to cast key to an int for traversal to work
    # FIXME: it seems like this is the wrong place for this maybe it 
    # is a sign I should give up on traversal altogether?
    def __getitem__(self, key):
        return self._data[int(key)]

    def setdefault(self, key, failobj=None):
        return ZopeDict.setdefault(self, int(key), failobj)

    def has_key(self, key):
        return ZopeDict.has_key(self, int(key))

    def get(self, key, failobj=None):
        return ZopeDict.get(self, int(key), failobj)

    def __contains__(self, key):
        return ZopeDict.__contains__(self, int(key))
    
    # zc.dict interface
    # Addition is done with __setitem__, overriding it will control addition.
    def __setitem__(self, key, value):
        #self._cat.index_doc(int(key), value)
        ZopeDict.__setitem__(self, int(key), value)

    #TODO find a way to do efficient automatic re-indexing
    # can't see that I can do better than Plone though
    # http://developer.plone.org/searching_and_indexing/indexing.html#when-indexing-happens-and-how-to-reindex-manually
    def reindex(self, value):
        self._cat.index_doc(value.key, value)

    # Removal is done with either pop or clear, overriding these methods will
    # control removal.
    def pop(self, key, *args):
        retval = ZopeDict.pop(self, int(key), *args)
        self._cat.unindex_doc(int(key))
        return retval

    def clear(self):
        ZopeDict.clear(self)
        self._cat.clear()
Ejemplo n.º 4
0
class Catalog(object):

    def __init__(self):

        self._catalog = RepozeCatalog()
        self._document_map = DocumentMap()

    @property
    def catalog(self):
        """ convenient proxy to real catalog """

        return self._catalog

    def query(self, qry, as_summary=False, as_object=False, **kwargs):

        """ Query the catalog. If as_summary is set, return object summaries,
        as fetched from info from the indexes"""

        res = self._catalog.query(qry, **kwargs)

        if as_summary:
            return [self.get_object_summary(uuid) for uuid in res[1]]
        elif as_object:
            return [self.get_object(uuid) for uuid in res[1]]
        else:
            return res

    def index_object(self, object):

        path = object_to_path(object)
        uuid = object.uuid

        docid = self._document_map.add(uuid)
        self._document_map.add_metadata(docid, {'path': path})

        try:
            self.catalog.index_doc(docid, object)
            self._p_changed = 1
            self.catalog._p_changed = 1
            self._document_map._p_changed = 1
            self.__parent__._p_changed = 1
        except:
            LOGGER.exception("Could not index object!")

    def reindex_object(self, object):

        uuid = object.uuid

        docid = self._document_map.docid_for_address(uuid)
        if not docid:
            self.index_object(object)
            docid = self._document_map.docid_for_address(uuid)

        # update the path of the object in the documentmap since the
        # object might have been renamed / moved
        path = object_to_path(object)
        self._document_map.add_metadata(docid, {'path': path})

        try:
            self.catalog.reindex_doc(docid, object)
            self._p_changed = 1
            self.catalog._p_changed = 1
            self._document_map._p_changed = 1
            self.__parent__._p_changed = 1
        except:
            LOGGER.exception("Could not index object!")

    def unindex_object(self, object):

        uuid = object.uuid

        docid = self._document_map.docid_for_address(uuid)
        if docid:
            self.catalog.unindex_doc(docid)
            self._document_map.remove_docid(docid)
            self._p_changed = 1
            self.catalog._p_changed = 1
            self._document_map._p_changed = 1
            self.__parent__._p_changed = 1

    def clear(self):

        self._catalog.clear()
        self._document_map = DocumentMap()
        self._p_changed = 1
        self.catalog._p_changed = 1
        self._document_map._p_changed = 1
        self.__parent__._p_changed = 1

    def get_object(self, docid):

        metadata = self._document_map.get_metadata(docid)
        path = metadata['path']
        return path_to_object(path, self.__parent__)

    def get_object_summary(self, uuid):

        """ Return a summary of the found object, based on the values that
        the indexes hold on the given uuid"""

        summ = {}

        for key in self.catalog.keys():
            idx = self.catalog[key]
            if hasattr(idx, "_rev_index"):
                summ[key] = idx._rev_index.get(uuid, '')

        summ['key'] = uuid

        return ObjectSummary(summ)

    def list_objects(self):

        docids = self.list_object_ids()
        for docid in docids:
            metadata = self._document_map.get_metadata(docid)
            yield (docid, metadata['path'])

    def list_object_ids(self):

        return self._document_map.docid_to_address.keys()