1 """basic API for collections"""
2 from functools import wraps
3 import time
4 import os
5 import threading
6 import socket
7 from grassyknoll.lib.meta import FactoryMixin
8
9 __all__=['CollectionDocument', 'CollectionResult', 'CollectionResultSet',
10 'CollectionIds', 'Collection', 'addMetaData']
11
34 return timedFunc
35
36
38 """base class for things that inherit from L{list}
39
40 @ivar metadata: metadata about the items
41 @type metadata: dict
42 """
43 __slots__=['metadata']
44
45 - def __init__(self, items, metadata=None):
46 """
47 @arg results: the results
48 @type results: list of L{CollectionResult}
49 """
50 super(_ListLike, self).__init__(items)
51
52 self.metadata=metadata if metadata is not None else {}
53 assert isinstance(self.metadata, dict)
54
56 return '<%s: %d items>' % (type(self).__name__, len(self))
57
59 return self[:], self.metadata.copy()
60
62 self[:], self.metadata = state
63
65 """base class for things that inherit from L{dict}
66
67
68 This class maps attribute C{name} to item C{__name__}
69
70 >>> d=_DictLike()
71 >>> d.pants=42
72 >>> d['__pants__']
73 42
74 >>> d['__shirt__']=101
75 >>> d.shirt
76 101
77
78 """
79 __slots__=[]
80
81
82
83
84 __read_only_attrs=set(dir(dict))
85 __read_only_attrs.remove('__class__')
86
88 return '<%s: %s>' % (type(self).__name__, self.get('__id__'))
89
91 try:
92 return self['__%s__'%name]
93 except KeyError:
94 raise AttributeError, name
95
97 if name in self.__read_only_attrs:
98 raise AttributeError, "attribute %s is read-only"%name
99 elif name in self.__slots__:
100 object.__setattr__(self, name, value)
101 else:
102 self['__%s__'%name]=value
103
105 if name in self.__read_only_attrs:
106 raise AttributeError, "attribute %s is read-only"%name
107 else:
108 try:
109 del self['__%s__'%name]
110 except KeyError:
111 raise AttributeError, name
112
114 """An item that may be I{added} to a L{Collection}
115
116 the C{id} attribute / C{__id__} value should probably be
117 L{unicode}.
118
119 @ivar norman: name of the L{Norman} for this document
120 @type norman: string or None
121 """
122 __slots__=['norman']
123
124 - def __init__(self, fields=None, norman=None, **kwargs):
134
136 """An item that may be I{retrieved} from a L{Collection}
137
138 Items are a map of C{field name => field value}. Names should be
139 str.
140 """
141 __slots__=[]
142
144 """
145 @returns: a representation consisting of soleley builtin types
146 @rtype: dict
147 """
148 return dict(self)
149
151 """a set of L{CollectionResult}s"""
152
153 __slots__=[]
154
156 """
157 @returns: a representation consisting of soleley builtin types.
158 Includes: metadata=>dict & results=>list of L{CollectionResult}s
159 @rtype: dict
160 """
161 return {'metadata':self.metadata.copy(),
162 'results': [r.dump() for r in self]}
163
165 """a set of ids in the collection"""
166
167 __slots__=[]
168
170 """
171 @returns: a representation consisting of soleley builtin types.
172 Includes: metadata=>dict & ids=>list of strings
173 @rtype: dict
174 """
175 return {'metadata':self.metadata.copy(),
176 'ids':self[:]}
177
179 """A bunch of items.
180
181 Items in a collection are uniquely identified by a C{id}.
182 Implementations are responsible for maintaining this constraint.
183
184 Items are I{added} as instances of L{CollectionDocument} and I{retrieved}
185 as instances of L{CollectionResult}.
186
187 Implementations are free to interpret various methods however is
188 reasonable. They may also choose not to implement methods if they are not
189 applicable. The methods in this class all raise L{NotImplementedError}.
190
191 Implementations may also provide query methods, named like I{foo}Query.
192 These methods may take whatever keyword arguments desired. They should
193 return the results of the query as a L{CollectionResultSet}.
194
195 XXX: should we have an subclass attr describing what methods are provided?
196 """
197
199 """
200 XXX this should prolly return None
201
202 @arg docs: several new docs to be added to the collection
203 @type docs: list of L{CollectionDocument}s
204
205 @returns: the created ids
206 @rtype: L{CollectionIds}
207 """
208 raise NotImplementedError
209
211 """delete several L{CollectionDocument}s by id
212
213 XXX this should prolly return None
214
215 @arg ids: the ids to delete
216 @type ids: list of string
217
218 @returns: the deleted ids
219 @rtype: L{CollectionIds}
220 """
221 raise NotImplementedError
222
224 """
225 @returns: the ids in the collection
226 @rtype: L{CollectionIds}
227 """
228 raise NotImplementedError
229
231 """retrive several L{CollectionResult}s by id
232
233 @arg ids: the ids of the results
234 @type ids: list of string
235
236 @arg fields: a sub-L{set} of fields that should be returned. Defaults
237 to None, meaning all available fields. XXX why a set? we use tuples
238 everywhere...
239 @type fields: set
240
241 @returns: the results
242 @rtype: L{CollectionResultSet}
243 """
244 raise NotImplementedError
245
247 raise NotImplementedError
248
250 """free resources associated with this collection"""
251 pass
252
254 """remove the collection from disk. Useful for testing"""
255 pass
256