rocking_chair 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +48 -0
- data/lib/rocking_chair.rb +6 -1
- data/lib/rocking_chair/database.rb +7 -7
- data/lib/rocking_chair/view.rb +2 -2
- data/test/test_helper.rb +2 -0
- data/test/view_test.rb +2 -2
- metadata +4 -3
data/README.md
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
An in-memory CouchDB implementation in Ruby for [couchrest](http://github.com/jchris/couchrest) and [SimplyStored](http://github.com/peritor/simply_stored).
|
2
|
+
Works for the database and document API, by_attribute views, and for SimplyStored generated views.
|
3
|
+
This way your tests will no longer depend on CouchDB and can run against an in-memory database.
|
4
|
+
|
5
|
+
It intercepts the HTTP-API calls of couchrest by implementing a
|
6
|
+
HTTPAdapter for [couchrest](http://github.com/jchris/couchrest). It then delegates those calls to the
|
7
|
+
in-memory database.
|
8
|
+
|
9
|
+
The in-memory database a hash of document_id => JSON-object.
|
10
|
+
|
11
|
+
RockingChair support simple views like _all_docs_ or _by_attribute_.
|
12
|
+
Further, it should supports all the views generated by [SimplyStored](http://github.com/peritor/simply_stored).
|
13
|
+
So it supports associations and soft deletion.
|
14
|
+
|
15
|
+
Installation
|
16
|
+
============
|
17
|
+
|
18
|
+
gem install rocking_chair
|
19
|
+
|
20
|
+
Usage
|
21
|
+
=============
|
22
|
+
|
23
|
+
Require the gem in your tests, e.g. test_helper.rb in Rails:
|
24
|
+
|
25
|
+
require 'rocking_chair'
|
26
|
+
|
27
|
+
Then activate it:
|
28
|
+
|
29
|
+
RockingChair.enable
|
30
|
+
|
31
|
+
Make sure to reset it every now and then so that your testdata doesn't grow too much.
|
32
|
+
Put this e.g. in your setup block:
|
33
|
+
|
34
|
+
def setup
|
35
|
+
RockingChair::Server.reset
|
36
|
+
end
|
37
|
+
|
38
|
+
If you have tests where you want to run against the real CouchDB,
|
39
|
+
just deactivate RockingChair:
|
40
|
+
|
41
|
+
RockingChair.disable
|
42
|
+
|
43
|
+
|
44
|
+
Caveats
|
45
|
+
=============
|
46
|
+
|
47
|
+
At the moment the performance is not as good as it could be as there is a lot of serialization to and from JSON going on.
|
48
|
+
This will be improved by storing not only the JSON tree but also the Ruby representation of the stored objects.
|
data/lib/rocking_chair.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
require "rubygems"
|
2
|
-
require
|
2
|
+
require 'active_support/core_ext/kernel/reporting'
|
3
|
+
require "active_support/core_ext/hash"
|
4
|
+
require "active_support/core_ext/module"
|
5
|
+
require 'active_support/deprecation'
|
6
|
+
require "active_support/core_ext/object/blank"
|
7
|
+
require 'active_support/json'
|
3
8
|
require "uuidtools"
|
4
9
|
require "cgi"
|
5
10
|
require "couchrest"
|
@@ -41,16 +41,16 @@ module RockingChair
|
|
41
41
|
options.assert_valid_keys('rev', 'revs', 'revs_info')
|
42
42
|
|
43
43
|
document = self[doc_id]
|
44
|
-
if options['rev'] && (
|
44
|
+
if options['rev'] && ( JSON.parse(document, :create_additions => false)['_rev'] != options['rev'])
|
45
45
|
RockingChair::Error.raise_404
|
46
46
|
end
|
47
47
|
if options['revs'] && options['revs'] == 'true'
|
48
|
-
json =
|
48
|
+
json = JSON.parse(document, :create_additions => false)
|
49
49
|
json['_revisions'] = {'start' => 1, 'ids' => [json['_rev']]}
|
50
50
|
document = json.to_json
|
51
51
|
end
|
52
52
|
if options['revs_info'] && options['revs_info'] == 'true'
|
53
|
-
json =
|
53
|
+
json = JSON.parse(document, :create_additions => false)
|
54
54
|
json['_revs_info'] = [{"rev" => json['_rev'], "status" => "disk"}]
|
55
55
|
document = json.to_json
|
56
56
|
end
|
@@ -61,7 +61,7 @@ module RockingChair
|
|
61
61
|
# options are ignored for now: batch, bulk
|
62
62
|
json = nil
|
63
63
|
begin
|
64
|
-
json =
|
64
|
+
json = JSON.parse(document, :create_additions => false)
|
65
65
|
raise "is not a Hash" unless json.is_a?(Hash)
|
66
66
|
rescue Exception => e
|
67
67
|
raise RockingChair::Error.new(500, 'InvalidJSON', "the document is not a valid JSON object: #{e}")
|
@@ -90,7 +90,7 @@ module RockingChair
|
|
90
90
|
end
|
91
91
|
|
92
92
|
def copy(original_id, new_id, rev=nil)
|
93
|
-
original = JSON.parse(self[original_id])
|
93
|
+
original = JSON.parse(self[original_id], :create_additions => false)
|
94
94
|
if rev
|
95
95
|
original['_rev'] = rev
|
96
96
|
else
|
@@ -101,7 +101,7 @@ module RockingChair
|
|
101
101
|
end
|
102
102
|
|
103
103
|
def bulk(documents)
|
104
|
-
documents = JSON.parse(documents)
|
104
|
+
documents = JSON.parse(documents, :create_additions => false)
|
105
105
|
response = []
|
106
106
|
documents['docs'].each do |doc|
|
107
107
|
begin
|
@@ -168,7 +168,7 @@ module RockingChair
|
|
168
168
|
end
|
169
169
|
|
170
170
|
def matching_revision?(existing_record, rev)
|
171
|
-
document = JSON.parse(existing_record)
|
171
|
+
document = JSON.parse(existing_record, :create_additions => false)
|
172
172
|
RockingChair::Helper.access('_rev', document) == rev
|
173
173
|
end
|
174
174
|
|
data/lib/rocking_chair/view.rb
CHANGED
@@ -15,7 +15,7 @@ module RockingChair
|
|
15
15
|
def initialize(database, design_document_name, view_name, options = {})
|
16
16
|
unless design_document_name == :all && view_name == :all
|
17
17
|
RockingChair::Error.raise_404 unless database.exists?("_design/#{design_document_name}")
|
18
|
-
@design_document = JSON.parse(database.storage["_design/#{design_document_name}"])
|
18
|
+
@design_document = JSON.parse(database.storage["_design/#{design_document_name}"], :create_additions => false)
|
19
19
|
@view_document = design_document['views'][view_name] || RockingChair::Error.raise_404
|
20
20
|
end
|
21
21
|
|
@@ -137,7 +137,7 @@ module RockingChair
|
|
137
137
|
|
138
138
|
def initialize_ruby_store
|
139
139
|
@ruby_store = database.storage.dup
|
140
|
-
@ruby_store.each{|
|
140
|
+
@ruby_store.each{|doc_id, json_document| ruby_store[doc_id] = JSON.parse(json_document, :create_additions => false) }
|
141
141
|
end
|
142
142
|
|
143
143
|
def filter_items_by_key(attributes)
|
data/test/test_helper.rb
CHANGED
@@ -3,6 +3,8 @@ require File.dirname(__FILE__) + "/../lib/rocking_chair"
|
|
3
3
|
require 'test/unit'
|
4
4
|
require 'shoulda'
|
5
5
|
require 'mocha'
|
6
|
+
require 'json/ext'
|
7
|
+
require 'active_support/inflector'
|
6
8
|
|
7
9
|
require File.dirname(__FILE__) + "/fixtures/extended_couch_rest_fixtures"
|
8
10
|
require File.dirname(__FILE__) + "/fixtures/simply_stored_fixtures"
|
data/test/view_test.rb
CHANGED
@@ -14,7 +14,7 @@ class ViewTest < Test::Unit::TestCase
|
|
14
14
|
@db['_design/user'] = { 'language' => 'javascript', 'views' => {
|
15
15
|
'by_firstname' => {
|
16
16
|
'reduce' => "function(key, values){ return values.length }",
|
17
|
-
"map" => "function(doc) {
|
17
|
+
"map" => "function(doc) { if(doc.ruby_class && doc.ruby_class == 'Instance') { emit(doc['created_at'], null); } }"
|
18
18
|
}
|
19
19
|
}}.to_json
|
20
20
|
|
@@ -29,7 +29,7 @@ class ViewTest < Test::Unit::TestCase
|
|
29
29
|
@db['_design/user'] = { 'language' => 'javascript', 'views' => {
|
30
30
|
'by_firstname' => {
|
31
31
|
'reduce' => "function(key, values){ return values.length }",
|
32
|
-
"map" => "function(doc) {
|
32
|
+
"map" => "function(doc) { if(doc.ruby_class && doc.ruby_class == 'Instance') { emit(doc['created_at'], null); } }"
|
33
33
|
}
|
34
34
|
}}.to_json
|
35
35
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rocking_chair
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Weiss
|
@@ -28,9 +28,10 @@ executables: []
|
|
28
28
|
|
29
29
|
extensions: []
|
30
30
|
|
31
|
-
extra_rdoc_files:
|
32
|
-
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.md
|
33
33
|
files:
|
34
|
+
- README.md
|
34
35
|
- lib/rocking_chair.rb
|
35
36
|
- lib/rocking_chair/couch_rest_http_adapter.rb
|
36
37
|
- lib/rocking_chair/database.rb
|