UNPKG

4.65 kBJavaScriptView Raw
1// Generated by CoffeeScript 2.3.1
2(function() {
3 // CouchDB back-end
4 // ----------------
5
6 // ### Back-end for a regular (static) DB such as provisioning
7
8 // - `db_uri` refers to a database URI.
9 // - `view_for` refers to a view object or a function that returns a view object (based on a requested key). A view object contains `view.map` (the map function as a function), `view.app`,and `view.name`, which all refer to the same view. If `view_for` is `null`, the `_all_docs` "identity" "view" is used.
10
11 // Changes are not computed for views where the `view_for` parameter is a function. (See below for the reason.) This could be worked-around by providing a database-to-view mapper that records the outcome of the view in a new database (and we are asked to monitor that database). (But notice that regular CouchDB databases are not suitable for this, since they can't directly handle non-string ids, and more importantly, cannot deal with duplicated keys/ids either.)
12 var CouchDB, build_backend, changes_view, couchdb_backend, most, semantic_for, view_as_stream;
13
14 couchdb_backend = function(db_uri, view_for, fromJS, use_lru) {
15 var changes, get_key, semantic, the_db, view_changes, view_key;
16 the_db = new CouchDB(db_uri, use_lru);
17 semantic = semantic_for(the_db, fromJS);
18 get_key = function(key) {
19 return the_db.get(key).catch(function() {
20 return null;
21 });
22 };
23 // Document changes
24 changes = the_db.changes({
25 include_docs: true
26 }).multicast();
27 // Changeset for wandering-country-view/all (or other view)
28 view_changes = (function() {
29 switch ((view_for != null) && typeof view_for) {
30 // For a static `view_for` object, we apply the `.map` function locally to each modified document,
31 // therefor dynamically computing the outcome of the view. (CouchDB does the same thing on its side,
32 // so if we need to reconnect we can query the CouchDB view and obtain the same results.)
33 case 'object':
34 return changes_view(view_for.map, changes).multicast();
35 default:
36 return most.empty();
37 }
38 })();
39 // We do not provide support for view changes for `view_for` functions.
40
41 // The reason this is a bad idea is that the view to use is decided based on the keys
42 // (see below for `.app` and `.name`), but the keys are _generated_ by the very
43 // same `map` function we're trying to select. (If this wasn't the case, the results would be
44 // inconsistent between the data returned by CouchDB, and the data generated by the function.)
45 // In details: to use this feature, you would have to provide a function would have to know
46 // how to reliably predict which keys will be returned by which ids (in other words it would
47 // be able to pre-compute the outcome of the `map` function).
48
49 // Also, we do not provide support for view changes for aggregate views (`count`, `range` etc.).
50
51 // On initial subscription we convert the key into a stream, using the server-side (CouchDB-stored) view.
52 view_key = (function() {
53 switch ((view_for != null) && typeof view_for) {
54 case false:
55 return function(key) {
56 return view_as_stream(db_uri, null, '_all_docs', key);
57 };
58 case 'object': // there is only one DB, or the view is named the same in all DBs
59 return function(key) {
60 return view_as_stream(db_uri, view_for.app, view_for.name, key);
61 };
62 case 'function':
63 return function(key) {
64 var view;
65 view = view_for(key);
66 if (view == null) {
67 return most.emtpy();
68 }
69 return view_as_stream(db_uri, view.app, view.name, key);
70 };
71 default:
72 throw new Error('view_for must be object or function');
73 }
74 })();
75 return build_backend({changes, view_changes, semantic, get_key, view_key, fromJS});
76 };
77
78 module.exports = couchdb_backend;
79
80 changes_view = require('./util/changes-view');
81
82 view_as_stream = require('./util/view');
83
84 most = require('most');
85
86 CouchDB = require('./util/db');
87
88 semantic_for = require('./util/semantic-for');
89
90 build_backend = require('./util/build-backend');
91
92 // FIXME: figure out the pattern to push in bulk
93
94// The semantic really is 'UPDATE', not 'OVERWRITE'
95// → we could either do bulk-get / bulk-put (aka `_all_docs` and `_bulk_docs`),
96// → or use an [update function](http://docs.couchdb.org/en/2.1.1/api/ddoc/render.html#db-design-design-doc-update-update-name)
97// For now the code (above) does single GET/PUT on updates.
98
99}).call(this);