work in progress: concept map, starting with types
This commit is contained in:
parent
0b765ad16b
commit
3e1127e798
6 changed files with 91 additions and 12 deletions
|
@ -5,7 +5,7 @@ from zope.interface import Interface
|
|||
|
||||
class ITraversable(Interface):
|
||||
|
||||
def get(key, default):
|
||||
def get(key, default=None):
|
||||
"""Return the item addressed by `key`; return `default` if not found."""
|
||||
|
||||
|
||||
|
@ -15,7 +15,7 @@ class IContainer(ITraversable):
|
|||
"""Return a sequence of child objects."""
|
||||
|
||||
def __getitem__(key):
|
||||
"""Return the item addressed by `key`; rais KeyError if not found."""
|
||||
"""Return the item addressed by `key`; raise KeyError if not found."""
|
||||
|
||||
def __setitem__(key, value):
|
||||
"""Store the `value` under the `key`.
|
||||
|
@ -24,6 +24,17 @@ class IContainer(ITraversable):
|
|||
and the value object (e.g. `parent´ and `name`) are stored correctly."""
|
||||
|
||||
|
||||
class IConcept(IContainer):
|
||||
|
||||
def parents(*predicates):
|
||||
"""Return a sequence of `Triple`s in which this object is
|
||||
referenced as `second`."""
|
||||
|
||||
def children(*predicates):
|
||||
"""Return a sequence of `Triple`s in which this object is
|
||||
referenced as `first`."""
|
||||
|
||||
|
||||
class IView(Interface):
|
||||
|
||||
def __call__():
|
||||
|
|
|
@ -4,13 +4,16 @@ import json
|
|||
from zope.interface import implementer
|
||||
from scopes.interfaces import IContainer, IView
|
||||
|
||||
views = {}
|
||||
views = {} # registry for all views: {name: {prefix: viewClass, ...}, ...}
|
||||
|
||||
def register(contextClass, name):
|
||||
def register(name, *contextClasses):
|
||||
"""Use as decorator: `@register(name, class, ...).
|
||||
class `None` means default view for all classes."""
|
||||
def doRegister(viewClass):
|
||||
nameEntry = views.setdefault(name, {})
|
||||
key = contextClass and contextClass.prefix or ''
|
||||
nameEntry[key] = viewClass
|
||||
for cl in contextClasses:
|
||||
key = cl and cl.prefix or ''
|
||||
nameEntry[key] = viewClass
|
||||
return viewClass
|
||||
return doRegister
|
||||
|
||||
|
@ -26,8 +29,8 @@ def getView(request, ob, name):
|
|||
return viewClass(ob, request)
|
||||
|
||||
|
||||
@register(None, 'index.html')
|
||||
@register(None, 'index.json')
|
||||
@register('index.html', None)
|
||||
@register('index.json', None)
|
||||
@implementer(IView)
|
||||
class DefaultView:
|
||||
|
||||
|
|
|
@ -1,12 +1,66 @@
|
|||
# scopes.storage.concept
|
||||
|
||||
"""Abstract base classes for concept map application classes."""
|
||||
"""Core classes for concept map structure."""
|
||||
|
||||
from zope.interface import implementer
|
||||
from scopes.interfaces import IConcept
|
||||
from scopes.storage.common import registerContainerClass
|
||||
from scopes.storage.tracking import Container, Track
|
||||
|
||||
|
||||
@implementer(IConcept)
|
||||
class Concept(Track):
|
||||
|
||||
headFields = ['name']
|
||||
|
||||
|
||||
class Concepts(Container):
|
||||
|
||||
insertOnChange = False
|
||||
|
||||
|
||||
class Predicate(Concept):
|
||||
|
||||
prefix = 'pred'
|
||||
|
||||
|
||||
@registerContainerClass
|
||||
class Predicates(Concepts):
|
||||
|
||||
itemFactory = Predicate
|
||||
tableName = 'preds'
|
||||
|
||||
|
||||
class Triple(Track):
|
||||
|
||||
headFields = ['first', 'second', 'predicate']
|
||||
prefix = 'rel'
|
||||
|
||||
|
||||
@registerContainerClass
|
||||
class Rels(Container):
|
||||
|
||||
itemFactory = Triple
|
||||
indexes = [('first', 'predicate', 'second'),
|
||||
('first', 'second'), ('predicate', 'second')]
|
||||
tableName = 'rels'
|
||||
insertOnChange = False
|
||||
|
||||
|
||||
# types stuff
|
||||
|
||||
class Type(Concept):
|
||||
|
||||
headFields = ['name', 'prefix']
|
||||
prefix = 'type'
|
||||
|
||||
def get(key, default=None):
|
||||
return self.container.queryLast(name=key) or default
|
||||
|
||||
|
||||
@registerContainerClass
|
||||
class Types(Concepts):
|
||||
|
||||
itemFactory = Type
|
||||
indexes = [('name',), ('prefix',)]
|
||||
tableName = 'types'
|
||||
|
|
|
@ -9,7 +9,6 @@ from scopes.storage.tracking import Container, Track
|
|||
|
||||
@implementer(IContainer)
|
||||
class Folder(Track):
|
||||
"""Needs docstring to be traversable."""
|
||||
|
||||
headFields = ['parent', 'name', 'ref']
|
||||
prefix = 'fldr'
|
||||
|
|
|
@ -21,7 +21,10 @@ class Test(unittest.TestCase):
|
|||
def test_002_folder(self):
|
||||
tlib_storage.test_folder(self, config)
|
||||
|
||||
def test_003_server(self):
|
||||
def test_003_type(self):
|
||||
tlib_storage.test_type(self, config)
|
||||
|
||||
def test_013_server(self):
|
||||
tlib_server.test_app(self, config)
|
||||
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"""Test implementation for the `scopes.storage` package."""
|
||||
|
||||
from datetime import datetime
|
||||
from scopes.storage import folder, tracking
|
||||
from scopes.storage import concept, folder, tracking
|
||||
|
||||
|
||||
def test_tracking(self, config):
|
||||
|
@ -73,3 +73,12 @@ def test_folder(self, config):
|
|||
|
||||
storage.commit()
|
||||
|
||||
|
||||
def test_type(self, config):
|
||||
storage = config.storageFactory(config.dbschema)
|
||||
storage.dropTable('types')
|
||||
types = storage.create(concept.Types)
|
||||
tid01 = types.save(concept.Type('type', 'type'))
|
||||
self.assertEqual(tid01, 1)
|
||||
|
||||
storage.commit()
|
||||
|
|
Loading…
Add table
Reference in a new issue