~ubuntu-branches/ubuntu/trusty/python-axiom/trusty

« back to all changes in this revision

Viewing changes to axiom/tags.py

  • Committer: Bazaar Package Importer
  • Author(s): Stefano Zacchiroli
  • Date: 2007-04-01 19:09:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070401190903-ar7yssg8lwv3si1h
Tags: upstream-0.5.0
ImportĀ upstreamĀ versionĀ 0.5.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
from epsilon.extime import Time
 
3
 
 
4
from axiom.item import Item
 
5
from axiom.attributes import text, reference, integer, AND, timestamp
 
6
 
 
7
class Tag(Item):
 
8
    typeName = 'tag'
 
9
    schemaVersion = 1
 
10
 
 
11
    name = text(doc="""
 
12
    The short string which is being applied as a tag to an Item.
 
13
    """)
 
14
 
 
15
    created = timestamp(doc="""
 
16
    When this tag was applied to the Item to which it applies.
 
17
    """)
 
18
 
 
19
    object = reference(doc="""
 
20
    The Item to which this tag applies.
 
21
    """)
 
22
 
 
23
    catalog = reference(doc="""
 
24
    The L{Catalog} item in which this tag was created.
 
25
    """)
 
26
 
 
27
    tagger = reference(doc="""
 
28
    An optional reference to the Item which is responsible for this tag's
 
29
    existence.
 
30
    """)
 
31
 
 
32
 
 
33
 
 
34
class _TagName(Item):
 
35
    """
 
36
    Helper class to make Catalog.tagNames very fast.  One of these is created
 
37
    for each distinct tag name that is created.  _TagName Items are never
 
38
    deleted from the database.
 
39
    """
 
40
    typeName = 'tagname'
 
41
 
 
42
    name = text(doc="""
 
43
    The short string which uniquely represents this tag.
 
44
    """, indexed=True)
 
45
 
 
46
    catalog = reference(doc="""
 
47
    The L{Catalog} item in which this tag exists.
 
48
    """)
 
49
 
 
50
 
 
51
 
 
52
class Catalog(Item):
 
53
 
 
54
    typeName = 'tag_catalog'
 
55
    schemaVersion = 2
 
56
 
 
57
    tagCount = integer(default=0)
 
58
 
 
59
    def tag(self, obj, tagName, tagger=None):
 
60
        """
 
61
        """
 
62
        # check to see if that tag exists.  Put the object attribute first,
 
63
        # since each object should only have a handful of tags and the object
 
64
        # reference is indexed.  As long as this is the case, it doesn't matter
 
65
        # whether the name or catalog attributes are indexed because selecting
 
66
        # from a small set of results is fast even without an index.
 
67
        if self.store.findFirst(Tag,
 
68
                                AND(Tag.object == obj,
 
69
                                    Tag.name == tagName,
 
70
                                    Tag.catalog == self)):
 
71
            return
 
72
 
 
73
        # if the tag doesn't exist, maybe we need to create a new tagname object
 
74
        self.store.findOrCreate(_TagName, name=tagName, catalog=self)
 
75
 
 
76
        # Increment only if we are creating a new tag
 
77
        self.tagCount += 1
 
78
        Tag(store=self.store, object=obj,
 
79
            name=tagName, catalog=self,
 
80
            created=Time(), tagger=tagger)
 
81
 
 
82
 
 
83
    def tagNames(self):
 
84
        """
 
85
        Return an iterator of unicode strings - the unique tag names which have
 
86
        been applied objects in this catalog.
 
87
        """
 
88
        return self.store.query(_TagName, _TagName.catalog == self).getColumn("name")
 
89
 
 
90
 
 
91
    def tagsOf(self, obj):
 
92
        """
 
93
        Return an iterator of unicode strings - the tag names which apply to
 
94
        the given object.
 
95
        """
 
96
        return self.store.query(
 
97
            Tag,
 
98
            AND(Tag.catalog == self,
 
99
                Tag.object == obj)).getColumn("name")
 
100
 
 
101
 
 
102
    def objectsIn(self, tagName):
 
103
        return self.store.query(
 
104
            Tag,
 
105
            AND(Tag.catalog == self,
 
106
                Tag.name == tagName)).getColumn("object")
 
107
 
 
108
 
 
109
 
 
110
def upgradeCatalog1to2(oldCatalog):
 
111
    """
 
112
    Create _TagName instances which version 2 of Catalog automatically creates
 
113
    for use in determining the tagNames result, but which version 1 of Catalog
 
114
    did not create.
 
115
    """
 
116
    newCatalog = oldCatalog.upgradeVersion('tag_catalog', 1, 2,
 
117
                                           tagCount=oldCatalog.tagCount)
 
118
    tags = newCatalog.store.query(Tag, Tag.catalog == newCatalog)
 
119
    tagNames = tags.getColumn("name").distinct()
 
120
    for t in tagNames:
 
121
        _TagName(store=newCatalog.store, catalog=newCatalog, name=t)
 
122
    return newCatalog
 
123
 
 
124
from axiom.upgrade import registerUpgrader
 
125
registerUpgrader(upgradeCatalog1to2, 'tag_catalog', 1, 2)