make the schema layout closer to what CouchRest uses twisty
authorMark Hammond <mhammond@skippinet.com.au>
Tue, 24 Mar 2009 21:47:12 +1100
branchtwisty
changeset 121 6675d659f527941a70b1b9b6bfa06c3ae408440c
parent 120 27c7fce59f31b577af80efdc9658ca755505ac93
child 122 6c69a445aee2a2da7ac9f65deaf819942217f47e
push id1
push userroot
push dateWed, 08 Apr 2009 01:46:05 +0000
make the schema layout closer to what CouchRest uses
schema/accounts/all/all-map.js
schema/accounts/all/views/all/map.js
schema/contacts/all/by_identity-map.js
schema/contacts/all/by_suffix-map.js
schema/contacts/all/views/by_identity/map.js
schema/contacts/all/views/by_suffix/map.js
schema/conversations/by/by_involves-map.js
schema/conversations/by/by_mailing_list-map.js
schema/conversations/by/by_tags-map.js
schema/conversations/by/views/by_involves/map.js
schema/conversations/by/views/by_mailing_list/map.js
schema/conversations/by/views/by_tags/map.js
schema/mailing_lists/all/by_list_id-map.js
schema/mailing_lists/all/by_list_id-reduce.js
schema/mailing_lists/all/views/by_list_id/map.js
schema/mailing_lists/all/views/by_list_id/reduce.js
schema/messages/by/by_conversation-map.js
schema/messages/by/by_doc_extension_sequence-map.js
schema/messages/by/by_doc_roots-map.js
schema/messages/by/by_doc_roots-reduce.js
schema/messages/by/by_header_message_id-map.js
schema/messages/by/by_storage-map.js
schema/messages/by/views/by_conversation/map.js
schema/messages/by/views/by_doc_extension_sequence/map.js
schema/messages/by/views/by_doc_roots/map.js
schema/messages/by/views/by_doc_roots/reduce.js
schema/messages/by/views/by_header_message_id/map.js
schema/messages/by/views/by_storage/map.js
schema/tags/all/all-map.js
schema/tags/all/all-reduce.js
schema/tags/all/views/all/map.js
schema/tags/all/views/all/reduce.js
server/python/junius/model.py
rename from schema/accounts/all/views/all/map.js
rename to schema/accounts/all/all-map.js
rename from schema/contacts/all/views/by_identity/map.js
rename to schema/contacts/all/by_identity-map.js
rename from schema/contacts/all/views/by_suffix/map.js
rename to schema/contacts/all/by_suffix-map.js
rename from schema/conversations/by/views/by_involves/map.js
rename to schema/conversations/by/by_involves-map.js
rename from schema/conversations/by/views/by_mailing_list/map.js
rename to schema/conversations/by/by_mailing_list-map.js
rename from schema/conversations/by/views/by_tags/map.js
rename to schema/conversations/by/by_tags-map.js
rename from schema/mailing_lists/all/views/by_list_id/map.js
rename to schema/mailing_lists/all/by_list_id-map.js
rename from schema/mailing_lists/all/views/by_list_id/reduce.js
rename to schema/mailing_lists/all/by_list_id-reduce.js
rename from schema/messages/by/views/by_conversation/map.js
rename to schema/messages/by/by_conversation-map.js
rename from schema/messages/by/views/by_doc_extension_sequence/map.js
rename to schema/messages/by/by_doc_extension_sequence-map.js
rename from schema/messages/by/views/by_doc_roots/map.js
rename to schema/messages/by/by_doc_roots-map.js
rename from schema/messages/by/views/by_doc_roots/reduce.js
rename to schema/messages/by/by_doc_roots-reduce.js
rename from schema/messages/by/views/by_header_message_id/map.js
rename to schema/messages/by/by_header_message_id-map.js
rename from schema/messages/by/views/by_storage/map.js
rename to schema/messages/by/by_storage-map.js
rename from schema/tags/all/views/all/map.js
rename to schema/tags/all/all-map.js
rename from schema/tags/all/views/all/reduce.js
rename to schema/tags/all/all-reduce.js
--- a/server/python/junius/model.py
+++ b/server/python/junius/model.py
@@ -206,83 +206,85 @@ def nuke_db():
     def _nuked_ok(d):
         logger.info("NUKED DATABASE!")
 
     deferred = db.deleteDB(dbinfo['name'])
     deferred.addCallbacks(_nuked_ok, _nuke_failed)
     return deferred
 
 def _build_doc_from_directory(ddir):
-    # for now all we look for is the views.
+    # all we look for is the views.
     ret = {}
-    try:
-        views = os.listdir(os.path.join(ddir, 'views'))
-    except OSError:
-        logger.warning("document directory %r has no 'views' subdirectory - skipping this document", ddir)
-        return ret
-
     ret_views = ret['views'] = {}
-    for view_name in views:
-        view_dir = os.path.join(ddir, 'views', view_name)
-        if not os.path.isdir(view_dir):
-            logger.info("skipping view non-directory: %s", view_dir)
-            continue
-        try:
-            f = open(os.path.join(view_dir, 'map.js'))
+    # The '-map.js' file is the 'trigger' for creating a view...
+    tail = "-map.js"
+    rtail = "-reduce.js"
+    files = os.listdir(ddir)
+    for f in files:
+        fqf = os.path.join(ddir, f)
+        if f.endswith(tail):
+            view_name = f[:-len(tail)]
             try:
-                ret_views[view_name] = {'map': f.read()}
-            finally:
-                f.close()
-        except (OSError, IOError):
-            logger.warning("can't open map.js in view directory %r - skipping this view", view_dir)
-            continue
-        try:
-            f = open(os.path.join(view_dir, 'reduce.js'))
-            ret_views[view_name]['reduce'] = f.read()
-            f.close()
-        except (OSError, IOError):
-            # no reduce - no problem...
-            logger.debug("no reduce.js in '%s' - skipping reduce for this view", view_dir)
-            continue
+                with open(fqf) as f:
+                    ret_views[view_name] = {'map': f.read()}
+            except (OSError, IOError):
+                logger.warning("can't open map file %r - skipping this view", fqf)
+                continue
+            fqr = os.path.join(ddir, view_name + rtail)
+            try:
+                with open(fqr) as f:
+                    ret_views[view_name]['reduce'] = f.read()
+            except (OSError, IOError):
+                # no reduce - no problem...
+                logger.debug("no reduce file %r - skipping reduce for view '%s'",
+                             fqr, view_name)
+        else:
+            # avoid noise...
+            if not f.endswith(rtail) and not f.startswith("."):
+                logger.info("skipping non-map/reduce file %r", fqf)
+
     logger.info("Document in directory %r has views %s", ddir, ret_views.keys())
     if not ret_views:
         logger.warning("Document in directory %r appears to have no views", ddir)
     return ret
 
 
 def generate_designs_from_filesystem(root):
+    # We use the same file-system layout as 'CouchRest' does:
+    # http://jchrisa.net/drl/_design/sofa/_show/post/release__couchrest_0_9_0
+    # note however that we don't create a design documents in exactly the same
+    # way - the view is always named as specified, and currently no 'map only'
+    # view is created (and if/when it is, only it will have a "special" name)
+    # See http://groups.google.com/group/raindrop-core/web/maintaining-design-docs
+
     # This is pretty dumb (but therefore simple).
     # root/* -> directories used purely for a 'namespace'
     # root/*/* -> directories which hold the contents of a document.
-    # root/*/*/views -> directory holding views for the document
-    # root/*/*/views/* -> directory for each named view.
-    # root/*/*/views/*/map.js|reduce.js -> view content
+    # root/*/*-map.js and maybe *-reduce.js -> view content with name b4 '-'
     logger.debug("Starting to build design documents from %r", root)
     for top_name in os.listdir(root):
         fq_child = os.path.join(root, top_name)
         if not os.path.isdir(fq_child):
             logger.debug("skipping non-directory: %s", fq_child)
             continue
-        # hack for debugging - rename a dir to end with .ignore...
-        if fq_child.endswith('.ignore'):
-            logger.info("skipping .ignored directory: %s", fq_child)
-            continue
         # so we have a 'namespace' directory.
         num_docs = 0
         for doc_name in os.listdir(fq_child):
             fq_doc = os.path.join(fq_child, doc_name)
             if not os.path.isdir(fq_doc):
                 logger.info("skipping document non-directory: %s", fq_doc)
                 continue
             # have doc - build a dict from its dir.
             doc = _build_doc_from_directory(fq_doc)
             # XXX - note the artificial 'raindrop' prefix - the intent here
             # is that we need some way to determine which design documents we
             # own, and which are owned by extensions...
-            # XXX - *sob* - and that we can't use '/' in the doc ID at the moment...
+            # XXX - *sob* - and that we shouldn't use '/' in the doc ID at the
+            # moment (well - we probably could if we ensured we quoted all the
+            # '/' chars, but that seems too much burden for no gain...)
             doc['_id'] = '_design/' + ('!'.join(['raindrop', top_name, doc_name]))
             yield doc
             num_docs += 1
 
         if not num_docs:
             logger.info("skipping sub-directory without child directories: %s", fq_child)