Commits

Alexander Shorin committed 0e705f3

Add base documents model with few helpers based on implemented couchapps.

Comments (0)

Files changed (2)

hydra/models/__init__.py

+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2013 Alexander Shorin
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution.
+#
+
+from .base import Document, Meta
+
+
+def make_resolver(db, system):
+    def resolve(doctype=None, idx=None, **kwargs):
+        if doctype and idx:
+            key = [system, doctype, idx]
+            view = db.view('externals/by_type_and_id', key=key, reduce=False,
+                           include_docs=True, limit=2)
+            rows = list(view)
+            if not rows:
+                raise LookupError('missed %s @ %s' % (doctype, idx))
+            assert len(rows) == 1, ('duplicate docs found for key: %s'
+                                    % rows[0].key)
+            return rows[0].doc
+        if 'docid' in kwargs:
+            return db[kwargs['docid']]
+        if 'view' in kwargs:
+            key = kwargs['key']
+            view = db.view(kwargs['view'], key=key, reduce=False,
+                           include_docs=True, limit=2)
+            rows = list(view)
+            if not rows:
+                raise LookupError('missed %s @ %s' % (doctype, idx))
+            assert len(rows) == 1, ('duplicate docs found for key: %s'
+                                    % rows[0].key)
+            return rows[0].doc
+        raise NotImplementedError('no idea how to resolve that')
+    return resolve

hydra/models/base.py

+# -*- coding: utf-8 -*-
+#
+# Copyright (C) 2013 Alexander Shorin
+# All rights reserved.
+#
+# This software is licensed as described in the file COPYING, which
+# you should have received as part of this distribution.
+#
+
+import time
+from .. import json
+from ..lib.dateutils import datetime_utc_now
+from ..mapping import Document as _Document
+from ..mapping import (
+    Mapping, TextField, IntegerField, BooleanField, DateTimeField, DictField,
+)
+
+
+class DocumentMeta(_Document.__metaclass__):
+    def __call__(self, *args, **kwargs):
+        instance = super(DocumentMeta, self).__call__(*args, **kwargs)
+        instance.meta.type = self.__meta_type__
+        return instance
+
+
+class Meta(Mapping):
+    author = TextField()
+    created_at = DateTimeField(default=datetime_utc_now)
+    externals = DictField(Mapping)
+    peer = TextField()
+    readonly = BooleanField(default=False)
+    timestamp = IntegerField(
+        default=lambda: int(time.mktime(datetime_utc_now().timetuple())))
+    type = TextField()
+    updated_at = DateTimeField(default=datetime_utc_now)
+    user = TextField()
+
+
+class Document(_Document):
+    __metaclass__ = DocumentMeta
+    __meta_type__ = 'generic'
+    meta = DictField(Meta, name='.meta')
+
+    @classmethod
+    def iter(cls, db, bucket=100):
+        params = {
+            'key': cls._fields['meta'].mapping._fields['type'].default,
+            'reduce': False,
+            'include_docs': True
+        }
+        if hasattr(db, 'iterview'):
+            for row in db.iterview('meta/by_type', bucket, **params):
+                yield cls.wrap(row.doc)
+        else:
+            for row in db.view('meta/by_type', **params):
+                yield cls.wrap(row.doc)
+
+    def bind(self, db, system, host, idx):
+        info = {
+            'system': system,
+            'host': host,
+            'id': idx
+        }
+        db.update_doc('externals/bind', self.id, body=info)
+        return self
+
+    def store(self, db):
+        headers, body = db.update_doc('all_docs/doc',
+                                      self.id,
+                                      body=self.unwrap())
+        self._data['_id'] = json.decode(body.read())['id']
+        self._data['_rev'] = headers.get('X-Couch-Update-NewRev', self.rev)
+        return self
+
+    def update(self, db):
+        self._data.update(db[self.id])
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.