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