opal-pouchdb 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +6 -0
- data/.travis.yml +6 -0
- data/Gemfile +3 -0
- data/LICENSE +7 -0
- data/README.md +45 -0
- data/Rakefile +17 -0
- data/config.ru +12 -0
- data/lib/opal-pouchdb.rb +1 -0
- data/lib/opal/pouchdb.rb +4 -0
- data/lib/opal/pouchdb/version.rb +5 -0
- data/opal-pouchdb.gemspec +22 -0
- data/opal/opal-pouchdb.rb +95 -0
- data/opal/pouchdb/all_documents.rb +30 -0
- data/opal/pouchdb/conversion.rb +28 -0
- data/opal/pouchdb/database.rb +266 -0
- data/opal/pouchdb/event_emitter.rb +27 -0
- data/opal/pouchdb/replication.rb +17 -0
- data/opal/pouchdb/row.rb +15 -0
- data/spec/database_events_spec.rb +81 -0
- data/spec/database_spec.rb +331 -0
- data/spec/pouchdb/es5-shim.min.js +7 -0
- data/spec/pouchdb/index.html.erb +10 -0
- data/spec/pouchdb/pouchdb.js +11 -0
- data/spec/replication_spec.rb +109 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/sync_spec.rb +82 -0
- metadata +139 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3c84d1d843149bb0d58c39411237a37846881524
|
4
|
+
data.tar.gz: f6a923fd1df134a6c2c31cdf38a34ebaf6970527
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3879fab123704c625967452763fcccf51ee5d7e5b2f1393a2ef360f162960f319a84abd648e3bc439a1ec12e1dd2ffe8f469a572047f7ee63cd098f5d0773df8
|
7
|
+
data.tar.gz: d286d7489c7a41de8688216468be1dbd458de75fd97220fd96ea9ae3de42165e155ca6b3ea07a4629f1ff533ca43d4de6f054ed76e7ba364f2439097e9117355
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2015 by Vitor Capela
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# opal-pouchdb: A PouchDB Wrapper for Opal
|
2
|
+
|
3
|
+
[![Build Status](https://travis-ci.org/dodecaphonic/opal-pouchdb.svg?branch=master)](https://travis-ci.org/dodecaphonic/opal-pouchdb)
|
4
|
+
[![Code Climate](https://codeclimate.com/github/dodecaphonic/opal-pouchdb/badges/gpa.svg)](https://codeclimate.com/github/dodecaphonic/opal-pouchdb)
|
5
|
+
|
6
|
+
opal-pouchdb allows [PouchDB][pouchdb] databases to be used with a nice Ruby API.
|
7
|
+
|
8
|
+
## Usage
|
9
|
+
|
10
|
+
Basic usage follows [PouchDB's API][pouchdb-api] very closely. The major difference is that, in JavaScript, a developer may decide if she wishes get the results of her interactions with the database via callbacks or promises. In opal-pouchdb, everything returns an [Opal Promise][opal-promise], allowing your async code to be as composable as that abstraction allows.
|
11
|
+
|
12
|
+
``` ruby
|
13
|
+
db = PouchDB::Database.new("my_database")
|
14
|
+
|
15
|
+
db.put(_id: "doc-1", summary: "Awesome", text: "Cake").then
|
16
|
+
db.get("doc-1")
|
17
|
+
end.then do |db_record|
|
18
|
+
puts db_record # => { "_id" => "doc-1", "_rev" => "some-large-string", "summary" => "Awesome", "text" => "Cake" }
|
19
|
+
end
|
20
|
+
```
|
21
|
+
|
22
|
+
Every single CRUD operation is supported right now:
|
23
|
+
|
24
|
+
- put
|
25
|
+
- post
|
26
|
+
- get
|
27
|
+
- delete
|
28
|
+
- all_docs
|
29
|
+
- bulk_docs
|
30
|
+
|
31
|
+
## TODO
|
32
|
+
|
33
|
+
- Attachments
|
34
|
+
- Querying
|
35
|
+
- Views
|
36
|
+
- Database info
|
37
|
+
- Compaction
|
38
|
+
- Revision diff
|
39
|
+
- Events
|
40
|
+
- Plugins
|
41
|
+
- Debug mode
|
42
|
+
|
43
|
+
[pouchdb]: http://pouchdb.com
|
44
|
+
[pouchdb-api]: http://pouchdb.com/api.html
|
45
|
+
[opal-promise]: http://opalrb.org/docs/promises/
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler.require
|
3
|
+
|
4
|
+
require "bundler/gem_tasks"
|
5
|
+
require "opal/rspec/rake_task"
|
6
|
+
|
7
|
+
require "yard"
|
8
|
+
|
9
|
+
Opal::RSpec::RakeTask.new(:default) do |s|
|
10
|
+
s.index_path = "spec/pouchdb/index.html.erb"
|
11
|
+
end
|
12
|
+
|
13
|
+
YARD::Rake::YardocTask.new do |t|
|
14
|
+
t.files = ['lib/**/*.rb', "opal/**/*.rb"] # optional
|
15
|
+
t.options = ['--any', '--extra', '--opts'] # optional
|
16
|
+
t.stats_options = ['--list-undoc'] # optional
|
17
|
+
end
|
data/config.ru
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require "bundler"
|
2
|
+
Bundler.require
|
3
|
+
|
4
|
+
require "opal-rspec"
|
5
|
+
Opal.append_path File.expand_path('../spec', __FILE__)
|
6
|
+
|
7
|
+
run Opal::Server.new { |s|
|
8
|
+
s.main = "opal/rspec/sprockets_runner"
|
9
|
+
s.append_path "spec"
|
10
|
+
s.debug = false
|
11
|
+
s.index_path = "spec/pouchdb/index.html.erb"
|
12
|
+
}
|
data/lib/opal-pouchdb.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "opal/pouchdb"
|
data/lib/opal/pouchdb.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path("../lib/opal/pouchdb/version", __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "opal-pouchdb"
|
6
|
+
s.version = Opal::PouchDB::VERSION
|
7
|
+
s.author = "Vitor Capela"
|
8
|
+
s.email = "dodecaphonic@gmail.com"
|
9
|
+
s.homepage = "https://github.com/dodecaphonic/opal-pouchdb"
|
10
|
+
s.summary = "Opal bridge to PouchDB"
|
11
|
+
s.description = "An Opal bridge to the PouchDB database library"
|
12
|
+
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
15
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
s.add_runtime_dependency "opal", ">= 0.7.0", "< 0.9.0"
|
19
|
+
s.add_development_dependency "opal-rspec", "~> 0.4.0"
|
20
|
+
s.add_development_dependency "yard"
|
21
|
+
s.add_development_dependency "rake"
|
22
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require "native"
|
2
|
+
require "promise"
|
3
|
+
|
4
|
+
module PouchDB
|
5
|
+
require "pouchdb/conversion"
|
6
|
+
require "pouchdb/database"
|
7
|
+
require "pouchdb/all_documents"
|
8
|
+
require "pouchdb/row"
|
9
|
+
require "pouchdb/event_emitter"
|
10
|
+
require "pouchdb/replication"
|
11
|
+
|
12
|
+
# Replicate data from source to target. Both the source and target can be a
|
13
|
+
# PouchDB instance or a string representing a CouchDB database URL or the name
|
14
|
+
# of a local PouchDB database. If `options.live` is true, then this will track
|
15
|
+
# future changes and also replicate them automatically. This method returns an
|
16
|
+
# object with the method `cancel()`, which you call if you want to cancel live
|
17
|
+
# replication.
|
18
|
+
#
|
19
|
+
# Replication is an event emitter like changes() and emits the "complete",
|
20
|
+
# "active", "paused", "change", "denied" and "error" events.
|
21
|
+
#
|
22
|
+
# Example:
|
23
|
+
#
|
24
|
+
# stream = PouchDB.replicate("mydb", "http://localhost:5984/mydb",
|
25
|
+
# live: true, retry: true)
|
26
|
+
# .on "change" do
|
27
|
+
# # ...
|
28
|
+
# end.on "paused" do
|
29
|
+
# # ...
|
30
|
+
# end # ...
|
31
|
+
#
|
32
|
+
# stream.cancel
|
33
|
+
#
|
34
|
+
# @param source [String, Database] A source database, local or URL
|
35
|
+
# @param target [String, Database] A target database, local or URL
|
36
|
+
# @param options [Hash] Optional arguments, defaulting to `false` unless
|
37
|
+
# specified
|
38
|
+
#
|
39
|
+
# @option options [Boolean] live If `true`, starts subscribing to future
|
40
|
+
# changes in the `source` database and continue replicating them
|
41
|
+
# @option options [Boolean] retry If `true`, will attempt to retry
|
42
|
+
# replications in the case of failure (due to being offline), using a
|
43
|
+
# backoff algorithm that retries at longer and longer intervals until
|
44
|
+
# a connection is re-established. Only applicable if `live: true`
|
45
|
+
# @option options [String] filter References a filter function from a
|
46
|
+
# design document to selectively get upgrades
|
47
|
+
# @option options [Hash] query parameters to send to the filter function
|
48
|
+
# @option options [Array<String>] doc_ids Only replicate docs with these
|
49
|
+
# ids
|
50
|
+
# @option options [Fixnum] since Replicate changes after the given
|
51
|
+
# sequence number
|
52
|
+
# @option options [Boolean] create_target Create target database if it
|
53
|
+
# does not exist. Only for server replications
|
54
|
+
# @option options [Fixnum] batch_size Number of documents to process at a
|
55
|
+
# time. Defaults to 100. This affects the number of docs held in memory
|
56
|
+
# and the number sent at a time to the target server. You may need to
|
57
|
+
# adjust downward if targeting devices with low amounts of memory
|
58
|
+
# (e.g. phones) or if the documents are large in size (e.g. with
|
59
|
+
# attachments). If your documents are small in size, then increasing this
|
60
|
+
# number will probably speed replication up.
|
61
|
+
# @option options [Fixnum] batches_limit Number of batches to process at a
|
62
|
+
# time. Defaults to 10. This (along with `batch_size`) controls how many
|
63
|
+
# docs are kept in memory at a time, so the maximum docs in memory at
|
64
|
+
# once would equal `batch_size` x `batches_limit`.
|
65
|
+
#
|
66
|
+
# @return [EventEmitter] An EventEmitter with the 'complete', 'active',
|
67
|
+
# 'paused', 'change', 'denied' and 'error' events
|
68
|
+
def self.replicate(source, target, options = {})
|
69
|
+
s = database_as_string(source)
|
70
|
+
t = database_as_string(target)
|
71
|
+
EventEmitter.new(`PouchDB.replicate(#{s}, #{t}, #{options.to_n})`)
|
72
|
+
end
|
73
|
+
|
74
|
+
# Sync data from `source` to `target` and `target` to `src`. This is a
|
75
|
+
# convenience method for bidirectional data replication. In other words,
|
76
|
+
# this code:
|
77
|
+
#
|
78
|
+
# PouchDB.replicate("mydb", "http://localhost:5984/mydb")
|
79
|
+
# PouchDB.replicate("http://localhost:5984/mydb", "mydb")
|
80
|
+
#
|
81
|
+
# is equivalent to this code:
|
82
|
+
#
|
83
|
+
# PouchDB.sync("mydb", "http://localhost:5984/mydb")
|
84
|
+
#
|
85
|
+
# @see .replicate
|
86
|
+
# @return [EventEmitter] An EventEmitter with the 'complete', 'active',
|
87
|
+
# 'paused', 'change', 'denied' and 'error' events
|
88
|
+
def self.sync(source, target, options = {})
|
89
|
+
s = database_as_string(source)
|
90
|
+
t = database_as_string(target)
|
91
|
+
EventEmitter.new(`PouchDB.sync(#{s}, #{t}, #{options.to_n})`)
|
92
|
+
end
|
93
|
+
|
94
|
+
extend Conversion
|
95
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module PouchDB
|
2
|
+
class AllDocuments
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
def initialize(results)
|
6
|
+
@results = results
|
7
|
+
end
|
8
|
+
|
9
|
+
def offset
|
10
|
+
`#{@results}.offset`
|
11
|
+
end
|
12
|
+
|
13
|
+
def total_rows
|
14
|
+
`#{@results}.total_rows`
|
15
|
+
end
|
16
|
+
|
17
|
+
def size
|
18
|
+
`#{@results}.rows.length`
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_method :count, :size
|
22
|
+
alias_method :length, :size
|
23
|
+
|
24
|
+
def each
|
25
|
+
`#{@results}.rows`.each do |r|
|
26
|
+
yield Row.new(r)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module PouchDB
|
2
|
+
module Conversion
|
3
|
+
OBJECT_CONVERSION = ->(response) {
|
4
|
+
if (maybe_exception = Native(response)).is_a?(Exception)
|
5
|
+
maybe_exception
|
6
|
+
else
|
7
|
+
Hash.new(response)
|
8
|
+
end
|
9
|
+
}
|
10
|
+
ARRAY_CONVERSION = ->(response) { response.map { |o| OBJECT_CONVERSION.call(o) } }
|
11
|
+
|
12
|
+
def as_opal_promise(pouch_promise_n, &response_handler)
|
13
|
+
pouch_promise = Native(pouch_promise_n)
|
14
|
+
handler = response_handler || OBJECT_CONVERSION
|
15
|
+
promise = Promise.new
|
16
|
+
|
17
|
+
pouch_promise
|
18
|
+
.then(-> (response) do promise.resolve(handler.call(response)) end)
|
19
|
+
.catch(-> (error) do promise.reject(error) end)
|
20
|
+
|
21
|
+
promise
|
22
|
+
end
|
23
|
+
|
24
|
+
def database_as_string(db)
|
25
|
+
db.is_a?(Database) ? db.name : db
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,266 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
module PouchDB
|
3
|
+
# Creates a Database, either interacting with it locally or remotely. If
|
4
|
+
# remotely, the library will act as a CouchDB client.
|
5
|
+
#
|
6
|
+
# Unless explicitly noted, this wrapper follows the same API names and
|
7
|
+
# conventions of the original JavaScript code, with the exception of not
|
8
|
+
# providing the alternative between callbacks and promises on CRUD operations,
|
9
|
+
# opting for promises in every stance. The only situations in which that is
|
10
|
+
# not the case are those involving EventEmitter, where only providing promises
|
11
|
+
# would break semantics.
|
12
|
+
#
|
13
|
+
# That means you can safely read the original documentation and translate it
|
14
|
+
# directly to Ruby. An `options` Object will be an options Hash, an Object
|
15
|
+
# representing a document will be a Hash in Ruby land.
|
16
|
+
#
|
17
|
+
# This is not a toll-free library. It tries to follow the principle of least
|
18
|
+
# surprise, forcing it to convert PouchDB's promises to Opal promises and
|
19
|
+
# Objects to Hashes. It's not that great of a price to pay for convenience.
|
20
|
+
#
|
21
|
+
# Basic usage:
|
22
|
+
#
|
23
|
+
# db = PouchDB::Database.new(name: "awesome_db")
|
24
|
+
# db.put(_id: "doc-id", contents: "This is important").then do
|
25
|
+
# db.all_docs(include_docs: true).then do |docs|
|
26
|
+
# puts "Yay, #{docs.size} docs"
|
27
|
+
# end
|
28
|
+
# end.fail do |error|
|
29
|
+
# puts "This code is perfect, but something went wrong"
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# Refer to the PouchDB API and Getting Started guides for more.
|
33
|
+
class Database
|
34
|
+
include Native
|
35
|
+
include Conversion
|
36
|
+
|
37
|
+
# Creates a Database. If passed a URL, the Database will act as a CouchDB
|
38
|
+
# client. Otherwise, data will be stored and queried locally.
|
39
|
+
#
|
40
|
+
# Notice that here we don't support the alternative between passing the name
|
41
|
+
# or `options` as the first argument. As such, name must *always* be
|
42
|
+
# passed in as a keyword argument. A KeyError will be thrown otherwise.
|
43
|
+
#
|
44
|
+
# @param [Hash] options The options for database creation
|
45
|
+
# @option options [String] :name The name or URL of the database (mandatory)
|
46
|
+
# @option options [Boolean] :auto_compaction This turns on auto compaction, which means
|
47
|
+
# compact() is called after every change (default: false)
|
48
|
+
# @option options [String] :adapter One of 'idb', 'leveldb', 'websql', or 'http'.
|
49
|
+
# If unspecified, PouchDB will infer this automatically, preferring IndexedDB
|
50
|
+
# to WebSQL in browsers that support both (i.e. Chrome, Opera and Android 4.4+).
|
51
|
+
# @option options [Hash] :ajax For CouchDB clients only. Refer to official doc
|
52
|
+
# for more info.
|
53
|
+
# @raise [KeyError] if `:name` is not passed in as a keyword argument
|
54
|
+
def initialize(options = {})
|
55
|
+
@name = options.fetch(:name)
|
56
|
+
super `new PouchDB(#{options.to_n})`
|
57
|
+
end
|
58
|
+
|
59
|
+
attr_reader :name
|
60
|
+
|
61
|
+
# Deletes the database. Be aware this will not affect replicas.
|
62
|
+
#
|
63
|
+
# @option options [Hash] :ajax Refer to the official doc for more info.
|
64
|
+
# @return [Promise<Hash>]
|
65
|
+
def destroy(options = {})
|
66
|
+
as_opal_promise(`#{@native}.destroy()`)
|
67
|
+
end
|
68
|
+
|
69
|
+
# Deletes a document from the database. It can be called in one of two ways:
|
70
|
+
#
|
71
|
+
# db.remove(doc: <full document hash>)
|
72
|
+
# # or, alternatively
|
73
|
+
# db.remove(doc_id: <id>, doc_rev: <revision>)
|
74
|
+
#
|
75
|
+
# @param args [Hash] The arguments for the function
|
76
|
+
# @option args [Hash] :doc A document with _id and _rev to be removed. If defined,
|
77
|
+
# :doc_id and :doc_rev will be ignored.
|
78
|
+
# @option args [String] :doc_id A document's id (requires :doc_rev)
|
79
|
+
# @option args [String] :doc_rev A document's revision (requires :doc_id)
|
80
|
+
# @option args [Hash] :options Extra options (refer to the official doc).
|
81
|
+
# @return [Promise<Hash>]
|
82
|
+
def remove(args = {})
|
83
|
+
doc = args[:doc]
|
84
|
+
doc_id = args[:doc_id]
|
85
|
+
doc_rev = args[:doc_rev]
|
86
|
+
options = args[:options]
|
87
|
+
|
88
|
+
%x{
|
89
|
+
var pouchPromise;
|
90
|
+
if (doc) {
|
91
|
+
pouchPromise = #{@native}.remove(#{doc.to_n}, #{options.to_n})
|
92
|
+
} else {
|
93
|
+
pouchPromise = #{@native}.remove(doc_id, doc_rev, #{options.to_n})
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
as_opal_promise(`pouchPromise`)
|
98
|
+
end
|
99
|
+
|
100
|
+
# Creates or updates a document. When updating a document, its _id and _rev
|
101
|
+
# can either be in `doc` or passed explicitly as :doc_id and :doc_rev.
|
102
|
+
#
|
103
|
+
# @param doc [Hash] The contents to create or update
|
104
|
+
# @param args [Hash] Optional arguments
|
105
|
+
# @option args [String] :doc_id A document's id (requires :doc_rev)
|
106
|
+
# @option args [String] :doc_rev A document's rev (requires :id)
|
107
|
+
# @option args [Hash] :options Extra options (refer to the official doc)
|
108
|
+
# @return [Promise<Hash>]
|
109
|
+
def put(doc, args = {})
|
110
|
+
doc_id = args[:doc_id]
|
111
|
+
doc_rev = args[:doc_rev]
|
112
|
+
options = args[:options]
|
113
|
+
|
114
|
+
as_opal_promise(`#{@native}.put(#{doc.to_n}, doc_id, doc_rev, #{options.to_n})`)
|
115
|
+
end
|
116
|
+
|
117
|
+
# Creates a document, generating its id in the process. It's better to
|
118
|
+
# always use `put` with an explicit id in order to avoid PouchDB's very long
|
119
|
+
# Strings and to take advantage of its sorting of keys when using `all_docs`.
|
120
|
+
#
|
121
|
+
# @param doc [Hash] The contents to use when creating
|
122
|
+
# @param options [Hash] Extra options (refer to the official doc)
|
123
|
+
# @return [Promise<Hash>]
|
124
|
+
def post(doc, options = {})
|
125
|
+
as_opal_promise(`#{@native}.post(#{doc.to_n}, #{options.to_n})`)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Retrieves a document from the database.
|
129
|
+
#
|
130
|
+
# @param doc_id [String] A document's id
|
131
|
+
# @param options [Hash] Optional arguments. All default to `false`
|
132
|
+
# @option options [String] :rev Fetch a specific revision. Defaults to
|
133
|
+
# winning revision
|
134
|
+
# @option options [Boolean] :revs Include revision history with the document
|
135
|
+
# @option options [Boolean] :revs_info Include a list of revisions, and
|
136
|
+
# their availability
|
137
|
+
# @option options [String, Array<String>] :open_revs Fetch all leaf
|
138
|
+
# revisions if open_revs="all" or fetch all leaf revisions specified
|
139
|
+
# in open_revs array. Leaves will be returned in the same order as
|
140
|
+
# specified in input array
|
141
|
+
# @option options [Boolean] :conflicts If specified, conflicting leaf
|
142
|
+
# revisions will be attached in _conflicts array
|
143
|
+
# @option options [Boolean] :attachments Include attachment data
|
144
|
+
# @option options [Hash] :ajax Refer to the official doc
|
145
|
+
# @return [Promise<Hash>]
|
146
|
+
def get(doc_id, options = {})
|
147
|
+
as_opal_promise(`#{@native}.get(doc_id, #{options.to_n})`)
|
148
|
+
end
|
149
|
+
|
150
|
+
# Creates, updates or deletes multiple documents. If you omit an _id in one
|
151
|
+
# of the documents, a new document will be created with a generated id; if
|
152
|
+
# you pass in both an _id and _rev, it will be updated; if you add
|
153
|
+
# `_deleted: true`, it will be removed.
|
154
|
+
#
|
155
|
+
# @param docs [Array<Hash>] an Array of documents
|
156
|
+
# @param options [Hash] optional arguments
|
157
|
+
def bulk_docs(docs, options = {})
|
158
|
+
as_opal_promise(`#{@native}.bulkDocs(#{docs.to_n}, #{options.to_n})`,
|
159
|
+
&ARRAY_CONVERSION)
|
160
|
+
end
|
161
|
+
|
162
|
+
# Fetches multiple documents in bulk, indexing and sorting them by their
|
163
|
+
# _ids. Deleted documents are only included if `options.keys` is specified.
|
164
|
+
# All options are `false` unless otherwise specified.
|
165
|
+
#
|
166
|
+
# @param options [Hash] optional arguments
|
167
|
+
# @option options [Boolean] include_docs include the document itself in
|
168
|
+
# each row in the `doc` field. Otherwise by default you only get the
|
169
|
+
# _id and rev properties.
|
170
|
+
# @option options [Boolean] conflicts Include conflict information in
|
171
|
+
# the `_conflicts` field of a doc (only if `include_docs` is `true`)
|
172
|
+
# @option options [Boolean] attachments Include attachment data as
|
173
|
+
# base64-encoded string (only if `include_docs` is `true`)
|
174
|
+
# @option options [String] startkey Used in conjuction with `endkey`.
|
175
|
+
# Get documents with IDs in a certain range
|
176
|
+
# @option options [String] endkey Used in conjuction with `startkey`.
|
177
|
+
# Get documents with IDs in a certain range
|
178
|
+
# @option options [Boolean] inclusive_end Include documents having an
|
179
|
+
# ID equal to the given `options.endkey` (default: `true`)
|
180
|
+
# @option options [Fixnum] limit Maximum number of documents to return
|
181
|
+
# @option options [Fixnum] skip Number of documents to skip before
|
182
|
+
# returning (warning: poor performance on IndexedDB/LevelDB)
|
183
|
+
# @option options [Boolean] descending Reverse the order of the output
|
184
|
+
# documents
|
185
|
+
# @option options [String] key Only return documents with IDs matching
|
186
|
+
# this key
|
187
|
+
# @option options [Array<String>] keys Keys to be fetched in a single
|
188
|
+
# shot. Neither `startkey` nor `endkey` can be specified with this
|
189
|
+
# option; the rows returned are in the same order as the supplied
|
190
|
+
# `keys` Array; the row for a deleted document will have the revision
|
191
|
+
# ID of the deletion, and an extra `deleted: true` in the `value`
|
192
|
+
# key; the row for a nonexistent document will just contain an
|
193
|
+
# `"error"` key with the value `"not_found"`. For details, see the
|
194
|
+
# CouchDB query options documentation.
|
195
|
+
# @return [Promise]
|
196
|
+
def all_docs(options = {})
|
197
|
+
as_opal_promise(`#{@native}.allDocs(#{options.to_n})`) { |response|
|
198
|
+
AllDocuments.new(response)
|
199
|
+
}
|
200
|
+
end
|
201
|
+
|
202
|
+
# A list of changes made to documents in the database, in the order they
|
203
|
+
# were made. It returns an object with the method `cancel()`, which you call
|
204
|
+
# if you don't want to listen to new changes anymore.
|
205
|
+
#
|
206
|
+
# It is an EventEmitter and will emit a 'change' event on each document
|
207
|
+
# change, a 'complete' event when all the changes have been processed, and
|
208
|
+
# an 'error' event when an error occurs. In addition to the 'change' event,
|
209
|
+
# any change will also emit a 'create', 'update', or 'delete' event.
|
210
|
+
#
|
211
|
+
# @param options [Hash] optional arguments
|
212
|
+
# @option options [Boolean] include_docs Include the associated document
|
213
|
+
# with each change
|
214
|
+
# @option options [Boolean] conflicts Include conflict information in
|
215
|
+
# the `_conflicts` field of a doc (only if `include_docs` is `true`)
|
216
|
+
# @option options [Boolean] attachments Include attachment data as
|
217
|
+
# base64-encoded string (only if `include_docs` is `true`)
|
218
|
+
# @option options [Boolean] descending Reverse the order of the output
|
219
|
+
# documents
|
220
|
+
# @option options [String,Fixnum] since Start the results from the change
|
221
|
+
# immediately after the given sequence number. You can also pass
|
222
|
+
# 'now' if you want only new changes (depends on `live: true` )
|
223
|
+
# @option options [Fixnum] timeout The request timeout, in milliseconds
|
224
|
+
# @option options [Fixnum] limit Limit the numbers of results to this
|
225
|
+
# number
|
226
|
+
# @option options [Array<String>] Only shows changes for docs with these
|
227
|
+
# ids
|
228
|
+
# @option options [String] filter Reference a filter function from a design
|
229
|
+
# document to selectively get updates. To use a view function, pass in
|
230
|
+
# `_view` and provide a reference to that function with the `view` key
|
231
|
+
# @option options [Hash] query_params Properties to pass to the filter
|
232
|
+
# function (e.g.: { foo: "bar" }, where "bar" will be available in the
|
233
|
+
# filter function as `params.query.foo`. To have access to the params,
|
234
|
+
# define your function as receiving a second argument
|
235
|
+
# @option options [String] view Specify a view function (e.g.
|
236
|
+
# "design_doc_name/view_name") to act as a filter. Documents counted
|
237
|
+
# as "passed" for a view filter if a map function emits at least one
|
238
|
+
# record of them (`options.filter` must be set to `"_view"`)
|
239
|
+
# @option options [Boolean] returnDocs Available for non-http databases
|
240
|
+
# only, and defaults to `true`. Passing `false` prevents the changes
|
241
|
+
# feed from keeping all the documents in memory -- in other words,
|
242
|
+
# complete always has an empty results array, and the `change` event
|
243
|
+
# is the only way to get the event. Useful for large change sets
|
244
|
+
# where otherwise you would run out of memory
|
245
|
+
# @option options [Fixnum] batch_size Only available for http databases,
|
246
|
+
# this configures how many changes to fetch at a time. Increasing this
|
247
|
+
# can reduce the number of requests made. Default is 25.
|
248
|
+
# @option options [String] style Specifies how many revisions are returned
|
249
|
+
# in the changes array. The default, `"main_only"`, will only return
|
250
|
+
# the current "winning" revision; `"all_docs"` will return all leaf
|
251
|
+
# revisions (including conflicts and deleted former conflicts). Most
|
252
|
+
# likely you won't need this unless you are writing a replicator.
|
253
|
+
# @return [EventEmitter]
|
254
|
+
def changes(options = {})
|
255
|
+
EventEmitter.new(`#{@native}.changes(#{options.to_n})`)
|
256
|
+
end
|
257
|
+
|
258
|
+
def replicate
|
259
|
+
Replication.new(@native)
|
260
|
+
end
|
261
|
+
|
262
|
+
def sync(other)
|
263
|
+
EventEmitter.new(`#{@native}.sync(#{database_as_string(other)})`)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|