Skip to content

Commit

Permalink
Demonstrate the Datetime index
Browse files Browse the repository at this point in the history
  • Loading branch information
janwijbrand committed Nov 20, 2015
1 parent 5c18d02 commit 01e9fef
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 5 deletions.
2 changes: 1 addition & 1 deletion src/grokcore/catalog/__init__.py
Expand Up @@ -3,4 +3,4 @@
from grokcore.catalog.interfaces import IAttributeIndexDefinition
from grokcore.catalog.components import IndexesClass, Indexes
from grokcore.catalog.index import IndexDefinition, AttributeIndexDefinition
from grokcore.catalog.index import Field, Text, Set, Value
from grokcore.catalog.index import Field, Text, Set, Value, Datetime
98 changes: 98 additions & 0 deletions src/grokcore/catalog/ftests/catalog/indexes_datetimeindex.py
@@ -0,0 +1,98 @@
"""
We now demonstrate the use of a ValueIndex with Grok::
Let's set up a site in which we manage a couple of objects::
>>> herd = Herd()
>>> getRootFolder()['herd'] = herd
>>> from zope.site.hooks import setSite
>>> setSite(herd)
Now we add some indexable objects to the site::
>>> herd['alpha'] = Opossum('Alpha', datetime.datetime(2001, 6, 7))
>>> herd['beta'] = Opossum('Beta', datetime.datetime(2001, 7, 8))
>>> herd['gamma'] = Opossum('Gamma', datetime.datetime(2001, 7, 9))
>>> herd['delta'] = Opossum('Delta', datetime.datetime(2001, 9, 24))
Let's query the datetime index::
>>> from zope.catalog.interfaces import ICatalog
>>> from zope.component import getUtility, queryUtility
>>> catalog = getUtility(ICatalog)
>>> def sortedResults(catalog, **kw):
... result = list(catalog.searchResults(**kw))
... result.sort(key=lambda x:x.name)
... return [item.name for item in result]
>>> sortedResults(catalog, birthday={
... 'any_of': [datetime.datetime(2001, 6, 7),
... datetime.datetime(2001, 9, 24)]})
['Alpha', 'Delta']
>>> sortedResults(catalog, birthday={
... 'between': [datetime.datetime(2001, 6, 7),
... datetime.datetime(2001, 7, 9)]})
['Alpha', 'Beta', 'Gamma']
>>> sortedResults(catalog, birthday={
... 'between': [datetime.datetime(2001, 6, 7),
... datetime.datetime(2001, 7, 9),
... True, # exclude boundary.
... True # exclude boundary.
... ]})
['Beta']
Note how the index uses a seconds-resolution and sub-second data is ignored::
>>> herd['omega'] = Opossum(
... 'Omega', datetime.datetime(2002, 5, 3, 14, 53, 14, 000001))
>>> herd['psi'] = Opossum(
... 'Psi', datetime.datetime(2002, 5, 3, 14, 53, 14, 999999))
>>> sortedResults(catalog, birthday={
... 'between': [datetime.datetime(2002, 5, 3l, 14, 53, 14),
... datetime.datetime(2002, 5, 3l, 14, 53, 14)]})
['Omega', 'Psi']
Nuke the catalog and intids in the end, so as not to confuse
other tests::
>>> sm = herd.getSiteManager()
>>> from zope.catalog.interfaces import ICatalog
>>> sm.unregisterUtility(catalog, provided=ICatalog)
True
>>> from zope.intid.interfaces import IIntIds
>>> from zope import component
>>> intids = component.getUtility(IIntIds)
>>> sm.unregisterUtility(intids, provided=IIntIds)
True
Unfortunately ftests don't have good isolation from each other yet.
"""

import datetime
import grokcore.site
import grokcore.catalog
from grokcore.content import Container, Model
from zope.interface import implements, Interface, Attribute


class Herd(Container, grokcore.site.Application):
pass


class IOpossum(Interface):
name = Attribute('Name')
birthday = Attribute('Birthday')


class OpossumIndexes(grokcore.catalog.Indexes):
grokcore.site.site(Herd)
grokcore.catalog.context(IOpossum)

birthday = grokcore.catalog.Datetime()


class Opossum(Model):
implements(IOpossum)

def __init__(self, name, birthday):
self.name = name
self.birthday = birthday
13 changes: 9 additions & 4 deletions src/grokcore/catalog/index.py
Expand Up @@ -185,12 +185,17 @@ def index_doc(self, doc_id, value):
super(_DatetimeIndex, self).index_doc(doc_id, value)

def apply(self, query):
for name in ['any_of', 'between']:
if name not in query:
continue
if 'any_of' in query:
# The "value" of the dict is a sequence of datetime objects.
# Convert it into a timestamps.
query[name] = [to_timestamp(v) for v in query[name]]
query['any_of'] = [to_timestamp(v) for v in query['any_of']]
elif 'between' in query:
# The "value" of the dict is a sequence of arguments to pass on to
# the underlying btree. Convert the first two parameters that are
# datetime objects (or None) into timestamps.
query['between'] = parameters = list(query['between'])
parameters[0] = to_timestamp(parameters[0])
parameters[1] = to_timestamp(parameters[1])
return super(_DatetimeIndex, self).apply(query)

def values(self, min=None, max=None, excludemin=False, excludemax=False,
Expand Down

0 comments on commit 01e9fef

Please sign in to comment.