UNPKG

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