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): | class ITraversable(Interface): | ||||||
| 
 | 
 | ||||||
|     def get(key, default): |     def get(key, default=None): | ||||||
|         """Return the item addressed by `key`; return `default` if not found.""" |         """Return the item addressed by `key`; return `default` if not found.""" | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -15,7 +15,7 @@ class IContainer(ITraversable): | ||||||
|         """Return a sequence of child objects.""" |         """Return a sequence of child objects.""" | ||||||
| 
 | 
 | ||||||
|     def __getitem__(key): |     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): |     def __setitem__(key, value): | ||||||
|         """Store the `value` under the `key`.  |         """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.""" |         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): | class IView(Interface): | ||||||
| 
 | 
 | ||||||
|     def __call__(): |     def __call__(): | ||||||
|  |  | ||||||
|  | @ -4,13 +4,16 @@ import json | ||||||
| from zope.interface import implementer | from zope.interface import implementer | ||||||
| from scopes.interfaces import IContainer, IView | 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): |     def doRegister(viewClass): | ||||||
|         nameEntry = views.setdefault(name, {}) |         nameEntry = views.setdefault(name, {}) | ||||||
|         key = contextClass and contextClass.prefix or '' |         for cl in contextClasses: | ||||||
|         nameEntry[key] = viewClass |             key = cl and cl.prefix or '' | ||||||
|  |             nameEntry[key] = viewClass | ||||||
|         return viewClass |         return viewClass | ||||||
|     return doRegister |     return doRegister | ||||||
| 
 | 
 | ||||||
|  | @ -26,8 +29,8 @@ def getView(request, ob, name): | ||||||
|     return viewClass(ob, request) |     return viewClass(ob, request) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @register(None, 'index.html') | @register('index.html', None) | ||||||
| @register(None, 'index.json') | @register('index.json', None) | ||||||
| @implementer(IView) | @implementer(IView) | ||||||
| class DefaultView: | class DefaultView: | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -1,12 +1,66 @@ | ||||||
| # scopes.storage.concept | # 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.common import registerContainerClass | ||||||
| from scopes.storage.tracking import Container, Track | from scopes.storage.tracking import Container, Track | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @implementer(IConcept) | ||||||
| class Concept(Track): | class Concept(Track): | ||||||
| 
 | 
 | ||||||
|     headFields = ['name'] |     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) | @implementer(IContainer) | ||||||
| class Folder(Track): | class Folder(Track): | ||||||
|     """Needs docstring to be traversable.""" |  | ||||||
| 
 | 
 | ||||||
|     headFields = ['parent', 'name', 'ref'] |     headFields = ['parent', 'name', 'ref'] | ||||||
|     prefix = 'fldr' |     prefix = 'fldr' | ||||||
|  |  | ||||||
|  | @ -21,7 +21,10 @@ class Test(unittest.TestCase): | ||||||
|     def test_002_folder(self): |     def test_002_folder(self): | ||||||
|         tlib_storage.test_folder(self, config) |         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) |         tlib_server.test_app(self, config) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -3,7 +3,7 @@ | ||||||
| """Test implementation for the `scopes.storage` package.""" | """Test implementation for the `scopes.storage` package.""" | ||||||
| 
 | 
 | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
| from scopes.storage import folder, tracking | from scopes.storage import concept, folder, tracking | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def test_tracking(self, config): | def test_tracking(self, config): | ||||||
|  | @ -73,3 +73,12 @@ def test_folder(self, config): | ||||||
| 
 | 
 | ||||||
|         storage.commit() |         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