def get_usage_for_month(self, dateobj): """ Returns all C{UsageItem} for month C{dateobj} """ if not isinstance(dateobj, datetime.date): raise ValueError("Don't know what to do with %s" % dateobj) first_current_month_day = dateobj.replace(day=1).timetuple() if dateobj.month < 12: nextmonth = dateobj.month + 1 nextyear = dateobj.year else: nextmonth = 1 nextyear = dateobj.year + 1 first_next_month_day = dateobj.replace(day=1, month=nextmonth, year=nextyear).timetuple() return list( self.store.query( UsageItem, AND( UsageItem.start_time >= Time.fromStructTime(first_current_month_day), UsageItem.start_time < Time.fromStructTime(first_next_month_day))))
def tagsOf(self, obj): """ Return an iterator of unicode strings - the tag names which apply to the given object. """ return self.store.query(Tag, AND(Tag.catalog == self, Tag.object == obj)).getColumn("name")
def __eq__(self, other): if not isinstance(other, (AttributeTuple, tuple, list)): return NotImplemented return AND(*[ myAttr == otherAttr for (myAttr, otherAttr) in zip(self, other)])
def tag(self, obj, tagName, tagger=None): """ """ # check to see if that tag exists. Put the object attribute first, # since each object should only have a handful of tags and the object # reference is indexed. As long as this is the case, it doesn't matter # whether the name or catalog attributes are indexed because selecting # from a small set of results is fast even without an index. if self.store.findFirst( Tag, AND(Tag.object == obj, Tag.name == tagName, Tag.catalog == self)): return # if the tag doesn't exist, maybe we need to create a new tagname object self.store.findOrCreate(_TagName, name=tagName, catalog=self) # Increment only if we are creating a new tag self.tagCount += 1 Tag(store=self.store, object=obj, name=tagName, catalog=self, created=Time(), tagger=tagger)
def powerupsFor(self, interface): """ Returns powerups installed using C{powerUp}, in order of descending priority. Powerups found to have been deleted, either during the course of this powerupsFor iteration, during an upgrader, or previously, will not be returned. """ name = unicode(qual(interface), 'ascii') for cable in self.store.query( _PowerupConnector, AND(_PowerupConnector.interface == name, _PowerupConnector.item == self), sort=_PowerupConnector.priority.descending): pup = cable.powerup if pup is None: # this powerup was probably deleted during an upgrader. cable.deleteFromStore() else: indirector = IPowerupIndirector(pup, None) if indirector is not None: yield indirector.indirect(interface) else: yield pup
def contains(startAttribute, endAttribute, value): """ Return an L{axiom.iaxiom.IComparison} (an object that can be passed as the 'comparison' argument to Store.query/.sum/.count) which will constrain a query against 2 attributes for ranges which contain the given argument. The range is half-open. """ return AND(startAttribute <= value, value < endAttribute)
def getDomainNames(store): """ Retrieve a list of all local domain names represented in the given store. """ domains = set() domains.update(store.query( LoginMethod, AND(LoginMethod.internal == True, LoginMethod.domain != None)).getColumn("domain").distinct()) return sorted(domains)
def reschedule(self, runnable, fromWhen, toWhen): for evt in self.store.query( TimedEvent, AND(TimedEvent.time == fromWhen, TimedEvent.runnable == runnable)): evt.time = toWhen self._transientSchedule(toWhen, self.now()) break else: raise ValueError("%r is not scheduled to run at %r" % (runnable, fromWhen))
def accountByAddress(self, username, domain): """ @type username: C{unicode} without NUL @type domain: C{unicode} without NUL """ for account in self.store.query(LoginAccount, AND(LoginMethod.domain == domain, LoginMethod.localpart == username, LoginAccount.disabled == 0, LoginMethod.account == LoginAccount.storeID)): return account
def powerDown(self, powerup, interface): """ Remove a powerup. """ for cable in self.store.query( _PowerupConnector, AND(_PowerupConnector.item == self, _PowerupConnector.interface == unicode(qual(interface)), _PowerupConnector.powerup == powerup)): cable.deleteFromStore() return raise ValueError("Not powered up for %r with %r" % (interface, powerup))
def get_usage_for_day(self, dateobj): """ Returns all C{UsageItem} for day C{dateobj} """ if not isinstance(dateobj, datetime.date): raise ValueError("Don't know what to do with %s" % dateobj) today = dateobj.timetuple() tomorrow = (dateobj + datetime.timedelta(hours=24)).timetuple() return list( self.store.query( UsageItem, AND(UsageItem.start_time >= Time.fromStructTime(today), UsageItem.end_time < Time.fromStructTime(tomorrow))))
def _installOn(self, target, __explicitlyInstalled=False): depBlob = _globalDependencyMap.get(self.__class__, []) dependencies, itemCustomizers, refs = (map(list, zip(*depBlob)) or ([], [], [])) #See if any of our dependencies have been installed already for dc in self.store.query(_DependencyConnector, _DependencyConnector.target == target): if dc.installee.__class__ in dependencies: i = dependencies.index(dc.installee.__class__) refs[i].__set__(self, dc.installee) del dependencies[i], itemCustomizers[i], refs[i] if (dc.installee.__class__ == self.__class__ and self.__class__ in set( itertools.chain([blob[0][0] for blob in _globalDependencyMap.values()]))): #Somebody got here before we did... let's punt raise DependencyError("An instance of %r is already " "installed on %r." % (self.__class__, target)) #The rest we'll install for i, cls in enumerate(dependencies): it = cls(store=self.store) if itemCustomizers[i] is not None: itemCustomizers[i](it) _installOn(it, target, False) refs[i].__set__(self, it) #And now the connector for our own dependency. dc = self.store.findUnique(_DependencyConnector, AND(_DependencyConnector.target==target, _DependencyConnector.installee==self, _DependencyConnector.explicitlyInstalled==__explicitlyInstalled), None) assert dc is None, "Dependency connector already exists, wtf are you doing?" _DependencyConnector(store=self.store, target=target, installee=self, explicitlyInstalled=__explicitlyInstalled) for interface, priority in _getPowerupInterfaces(self): target.powerUp(self, interface, priority) callback = getattr(self, "installed", None) if callback is not None: callback()
def overlapping(startAttribute, # X endAttribute, # Y startValue, # A endValue, # B ): """ Return an L{axiom.iaxiom.IComparison} (an object that can be passed as the 'comparison' argument to Store.query/.sum/.count) which will constrain a query against 2 attributes for ranges which overlap with the given arguments. For a database with Items of class O which represent values in this configuration: X Y (a) (b) |-------------------| (c) (d) |--------| (e) (f) |--------| (g) (h) |---| (i) (j) |------| (k) (l) |-------------------------------------| (a) (l) |-----------------------------| (c) (b) |------------------------| (c) (a) |----| (b) (l) |---------| The query: myStore.query( O, findOverlapping(O.X, O.Y, a, b)) Will return a generator of Items of class O which represent segments a-b, c-d, e-f, k-l, a-l, c-b, c-a and b-l, but NOT segments g-h or i-j. (NOTE: If you want to pass attributes of different classes for startAttribute and endAttribute, read the implementation of this method to discover the additional join clauses required. This may be eliminated some day so for now, consider this method undefined over multiple classes.) In the database where this query is run, for an item N, all values of N.startAttribute must be less than N.endAttribute. startValue must be less than endValue. """ assert startValue <= endValue return OR( AND(startAttribute >= startValue, startAttribute <= endValue), AND(endAttribute >= startValue, endAttribute <= endValue), AND(startAttribute <= startValue, endAttribute >= endValue) )
def objectsIn(self, tagName): return self.store.query(Tag, AND(Tag.catalog == self, Tag.name == tagName)).getColumn("object")
def interfacesFor(self, powerup): pc = _PowerupConnector for iface in self.store.query( pc, AND(pc.item == self, pc.powerup == powerup)).getColumn('interface'): yield namedAny(iface)