work in progress: concept map, starting with types

This commit is contained in:
Helmut Merz 2024-03-14 10:21:43 +01:00
parent 0b765ad16b
commit 3e1127e798
6 changed files with 91 additions and 12 deletions

View file

@ -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__():

View file

@ -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:

View file

@ -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'

View file

@ -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'

View file

@ -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)

View file

@ -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()