monga 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/.travis.yml +1 -0
- data/README.md +59 -3
- data/lib/monga/client.rb +51 -6
- data/lib/monga/clients/master_slave_client.rb +0 -5
- data/lib/monga/clients/replica_set_client.rb +32 -71
- data/lib/monga/clients/single_instance_client.rb +53 -0
- data/lib/monga/collection.rb +102 -41
- data/lib/monga/connection.rb +38 -13
- data/lib/monga/connection_pool.rb +6 -17
- data/lib/monga/connections/buffer.rb +33 -0
- data/lib/monga/connections/em_connection.rb +25 -56
- data/lib/monga/connections/em_proxy_connection.rb +80 -0
- data/lib/monga/connections/fibered_connection.rb +26 -0
- data/lib/monga/connections/fibered_proxy_connection.rb +23 -0
- data/lib/monga/connections/proxy_connection.rb +4 -0
- data/lib/monga/connections/tcp_connection.rb +57 -0
- data/lib/monga/cursor.rb +197 -95
- data/lib/monga/database.rb +175 -60
- data/lib/monga/{requests → protocol}/delete.rb +1 -2
- data/lib/monga/{requests → protocol}/get_more.rb +1 -1
- data/lib/monga/{requests → protocol}/insert.rb +1 -2
- data/lib/monga/{requests → protocol}/kill_cursors.rb +1 -1
- data/lib/monga/{requests → protocol}/query.rb +3 -3
- data/lib/monga/{requests → protocol}/update.rb +1 -1
- data/lib/monga/request.rb +27 -23
- data/lib/monga/utils/constants.rb +5 -0
- data/lib/monga/utils/exceptions.rb +11 -0
- data/lib/monga.rb +19 -11
- data/monga.gemspec +2 -2
- data/spec/helpers/mongodb.rb +115 -38
- data/spec/monga/block/collection_spec.rb +172 -0
- data/spec/monga/block/cursor_spec.rb +160 -0
- data/spec/monga/block/database_spec.rb +80 -0
- data/spec/monga/block/single_instance_client_spec.rb +31 -0
- data/spec/monga/em/collection_spec.rb +308 -0
- data/spec/monga/em/cursor_spec.rb +256 -0
- data/spec/monga/em/database_spec.rb +140 -0
- data/spec/monga/em/replica_set_client_spec.rb +86 -0
- data/spec/monga/em/single_instance_client_spec.rb +28 -0
- data/spec/monga/sync/collection_spec.rb +247 -0
- data/spec/monga/sync/cursor_spec.rb +211 -0
- data/spec/monga/sync/database_spec.rb +110 -0
- data/spec/monga/sync/replica_set_client_spec.rb +54 -0
- data/spec/monga/sync/single_instance_client_spec.rb +25 -0
- data/spec/spec_helper.rb +2 -20
- metadata +50 -38
- data/lib/monga/clients/client.rb +0 -24
- data/lib/monga/connections/primary.rb +0 -46
- data/lib/monga/connections/secondary.rb +0 -13
- data/lib/monga/exceptions.rb +0 -9
- data/lib/monga/miner.rb +0 -72
- data/lib/monga/response.rb +0 -11
- data/spec/helpers/truncate.rb +0 -15
- data/spec/monga/collection_spec.rb +0 -448
- data/spec/monga/connection_pool_spec.rb +0 -50
- data/spec/monga/connection_spec.rb +0 -64
- data/spec/monga/cursor_spec.rb +0 -186
- data/spec/monga/database_spec.rb +0 -67
- data/spec/monga/replica_set_client_spec.rb +0 -46
- data/spec/monga/requests/delete_spec.rb +0 -0
- data/spec/monga/requests/insert_spec.rb +0 -0
- data/spec/monga/requests/query_spec.rb +0 -28
@@ -0,0 +1,256 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Monga::Cursor do
|
4
|
+
before do
|
5
|
+
EM.run do
|
6
|
+
@client = Monga::Client.new(type: :em, pool_size: 10)
|
7
|
+
@db = @client["dbTest"]
|
8
|
+
@collection = @db["testCollection"]
|
9
|
+
@collection.safe_remove do |err, resp|
|
10
|
+
raise err if err
|
11
|
+
docs = []
|
12
|
+
10.times do |i|
|
13
|
+
docs << { artist: "Madonna", title: "Track #{i+1}" }
|
14
|
+
docs << { artist: "Radiohead", title: "Track #{i+1}" }
|
15
|
+
end
|
16
|
+
@collection.safe_insert(docs) do |err|
|
17
|
+
raise err if err
|
18
|
+
EM.stop
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# ALL
|
25
|
+
|
26
|
+
describe "all" do
|
27
|
+
it "should find all" do
|
28
|
+
EM.run do
|
29
|
+
@collection.find.all do |err, docs|
|
30
|
+
docs.size.must_equal 20
|
31
|
+
EM.stop
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should find all with query" do
|
37
|
+
EM.run do
|
38
|
+
@collection.find(artist: "Madonna").all do |err, docs|
|
39
|
+
docs.size.must_equal 10
|
40
|
+
docs.each{ |d| d["artist"].must_equal "Madonna" }
|
41
|
+
EM.stop
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should find all with limit" do
|
47
|
+
EM.run do
|
48
|
+
@collection.find.limit(5).all do |err, docs|
|
49
|
+
docs.size.must_equal 5
|
50
|
+
EM.stop
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should find all with batch size" do
|
56
|
+
EM.run do
|
57
|
+
@collection.find.batch_size(2).all do |err, docs|
|
58
|
+
docs.size.must_equal 20
|
59
|
+
EM.stop
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should find all with skip" do
|
65
|
+
EM.run do
|
66
|
+
@collection.find.skip(10).all do |err, docs|
|
67
|
+
docs.size.must_equal 10
|
68
|
+
EM.stop
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
# FIRST
|
75
|
+
|
76
|
+
describe "first" do
|
77
|
+
it "should fetch first with sort" do
|
78
|
+
EM.run do
|
79
|
+
@collection.find.sort(title: 1).first do |err, doc|
|
80
|
+
doc["title"].must_equal "Track 1"
|
81
|
+
EM.stop
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should fetch first with sort and skip" do
|
87
|
+
EM.run do
|
88
|
+
@collection.find.sort(title: 1).skip(2).first do |err, doc|
|
89
|
+
doc["title"].must_equal "Track 10"
|
90
|
+
EM.stop
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
# NEXT_BATCH
|
97
|
+
|
98
|
+
describe "next_batch" do
|
99
|
+
it "should fetch batches" do
|
100
|
+
EM.run do
|
101
|
+
cursor = @collection.find.batch_size(2).limit(3)
|
102
|
+
cursor.next_batch do |err, batch, more|
|
103
|
+
batch.size.must_equal 2
|
104
|
+
more.must_equal true
|
105
|
+
cursor.next_batch do |err, batch, more|
|
106
|
+
batch.size.must_equal 1
|
107
|
+
more.must_equal false
|
108
|
+
EM.stop
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# EACH_BATCH
|
116
|
+
|
117
|
+
describe "each_batch" do
|
118
|
+
it "should fetch 3 items by batches" do
|
119
|
+
EM.run do
|
120
|
+
docs = []
|
121
|
+
@collection.find.batch_size(2).limit(3).each_batch do |err, batch, iter|
|
122
|
+
docs += batch
|
123
|
+
if iter
|
124
|
+
iter.next
|
125
|
+
else
|
126
|
+
docs.size.must_equal 3
|
127
|
+
EM.stop
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# NEXT_DOC
|
135
|
+
|
136
|
+
describe "next_doc" do
|
137
|
+
it "should fetch doc by doc" do
|
138
|
+
EM.run do
|
139
|
+
cursor = @collection.find.limit(3).batch_size(2)
|
140
|
+
cursor.next_doc do |err, doc, more|
|
141
|
+
more.must_equal true
|
142
|
+
cursor.next_doc do |err, doc, more|
|
143
|
+
cursor.next_doc do |err, doc, more|
|
144
|
+
more.must_equal false
|
145
|
+
EM.stop
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
# EACH_DOC
|
154
|
+
|
155
|
+
describe "each_doc" do
|
156
|
+
it "should iterate over some docs" do
|
157
|
+
EM.run do
|
158
|
+
docs = []
|
159
|
+
@collection.find.limit(100).skip(15).batch_size(3).each_doc do |err, doc, iter|
|
160
|
+
docs << doc
|
161
|
+
if iter
|
162
|
+
iter.next
|
163
|
+
else
|
164
|
+
docs.size.must_equal 5
|
165
|
+
EM.stop
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
it "should iterate over all docs" do
|
172
|
+
EM.run do
|
173
|
+
docs = []
|
174
|
+
@collection.find.batch_size(3).each_doc do |err, doc, iter|
|
175
|
+
docs << doc
|
176
|
+
if iter
|
177
|
+
iter.next
|
178
|
+
else
|
179
|
+
docs.size.must_equal 20
|
180
|
+
EM.stop
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# KILL CURSOR
|
188
|
+
|
189
|
+
describe "kill" do
|
190
|
+
it "should work with kill" do
|
191
|
+
EM.run do
|
192
|
+
cursor = @collection.find
|
193
|
+
cursor.next_batch do |err, batch, more|
|
194
|
+
cursor.kill
|
195
|
+
cursor.next_batch do |err, batch, more|
|
196
|
+
(Monga::Exceptions::ClosedCursor === err).must_equal true
|
197
|
+
EM.stop
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
# TAILABLE CURSOR
|
205
|
+
|
206
|
+
describe "tailable cursor" do
|
207
|
+
before do
|
208
|
+
EM.run do
|
209
|
+
@db.create_collection("testCapped", capped: true, size: 4*1024) do |err, resp|
|
210
|
+
raise err if err
|
211
|
+
@capped = @db["testCapped"]
|
212
|
+
@capped.safe_insert(title: "Test") do |err, resp|
|
213
|
+
raise err if err
|
214
|
+
EM.stop
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
after do
|
221
|
+
EM.run do
|
222
|
+
@capped = @db["testCapped"]
|
223
|
+
@capped.drop do |err, resp|
|
224
|
+
raise err if err
|
225
|
+
EM.stop
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should be tailable" do
|
231
|
+
EM.run do
|
232
|
+
tailable_cursor = @capped.find.flag(tailable_cursor: true)
|
233
|
+
docs = []
|
234
|
+
tailable_cursor.each_doc do |err, res, iter|
|
235
|
+
if iter
|
236
|
+
if res
|
237
|
+
docs << res
|
238
|
+
if docs.size == 2
|
239
|
+
docs.map{ |d| d["title"] }.must_equal ["Test", "New!"]
|
240
|
+
EM.stop
|
241
|
+
else
|
242
|
+
iter.next
|
243
|
+
end
|
244
|
+
else
|
245
|
+
@capped.safe_insert(title: "New!") do |err, res|
|
246
|
+
iter.next
|
247
|
+
end
|
248
|
+
end
|
249
|
+
else
|
250
|
+
EM.stop
|
251
|
+
end
|
252
|
+
end
|
253
|
+
end
|
254
|
+
end
|
255
|
+
end
|
256
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Monga::Database do
|
4
|
+
before do
|
5
|
+
EM.run do
|
6
|
+
@client = Monga::Client.new(type: :em)
|
7
|
+
@db = @client["dbTest"]
|
8
|
+
@collection = @db["testCollection"]
|
9
|
+
@collection.safe_remove do
|
10
|
+
EM.stop
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
after do
|
16
|
+
EM.run do
|
17
|
+
@collection.safe_remove do
|
18
|
+
EM.stop
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should create and drop collection" do
|
24
|
+
EM.run do
|
25
|
+
@db.create_collection("cappedCollection") do |err, resp|
|
26
|
+
@db.list_collections do |err, resp|
|
27
|
+
resp["retval"].must_include "cappedCollection"
|
28
|
+
@db.drop_collection("cappedCollection") do
|
29
|
+
@db.list_collections do |err, resp|
|
30
|
+
resp["retval"].wont_include "cappedCollection"
|
31
|
+
EM.stop
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should count in collection" do
|
40
|
+
EM.run do
|
41
|
+
@collection.safe_insert([{ title: 1 }, { title: 2 }]) do
|
42
|
+
@db.count("testCollection") do |err, cnt|
|
43
|
+
cnt.must_equal 2
|
44
|
+
EM.stop
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should eval javascript" do
|
51
|
+
EM.run do
|
52
|
+
@db.eval("1+1") do |err, resp|
|
53
|
+
resp["retval"].must_equal 2.0
|
54
|
+
EM.stop
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# INDEXES
|
60
|
+
|
61
|
+
describe "indexes" do
|
62
|
+
before do
|
63
|
+
EM.run do
|
64
|
+
@db.drop_indexes("testCollection", "*") do
|
65
|
+
EM.stop
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should drop index" do
|
71
|
+
EM.run do
|
72
|
+
@collection.safe_ensure_index(title: 1) do
|
73
|
+
@collection.get_indexes do |err, resp|
|
74
|
+
resp.select{ |i| i["ns"] == "dbTest.testCollection" }.size.must_equal 2
|
75
|
+
@db.drop_indexes("testCollection", title: 1) do
|
76
|
+
@collection.get_indexes do |err, resp|
|
77
|
+
resp.select{ |i| i["ns"] == "dbTest.testCollection" }.size.must_equal 1
|
78
|
+
EM.stop
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# GET LAST ERROR
|
88
|
+
|
89
|
+
describe "getLastError" do
|
90
|
+
before do
|
91
|
+
EM.run do
|
92
|
+
@collection.drop_indexes do
|
93
|
+
@collection.safe_ensure_index({ personal_id: 1 }, { unique: true, sparse: true }) do
|
94
|
+
EM.stop
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should get last error" do
|
101
|
+
EM.run do
|
102
|
+
req = @collection.insert(name: "Peter", personal_id: 10)
|
103
|
+
@db.get_last_error(req.connection) do |err, resp|
|
104
|
+
resp["ok"].must_equal 1.0
|
105
|
+
req = @collection.insert(name: "Peter", personal_id: 10)
|
106
|
+
@db.get_last_error(req.connection) do |err, resp|
|
107
|
+
err.class.must_equal Monga::Exceptions::QueryFailure
|
108
|
+
EM.stop
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should getLastError with fsync" do
|
115
|
+
EM.run do
|
116
|
+
req = @collection.insert(name: "Peter", personal_id: 10)
|
117
|
+
@db.get_last_error(req.connection, fsync: true) do |err, resp|
|
118
|
+
resp["ok"].must_equal 1.0
|
119
|
+
req = @collection.insert(name: "Peter", personal_id: 10)
|
120
|
+
@db.get_last_error(req.connection, fsync: true) do |err, resp|
|
121
|
+
err.class.must_equal Monga::Exceptions::QueryFailure
|
122
|
+
EM.stop
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# AGGREGATION
|
130
|
+
|
131
|
+
describe "aggregation" do
|
132
|
+
it "should aggregate"
|
133
|
+
end
|
134
|
+
|
135
|
+
# MAP REDUCE
|
136
|
+
|
137
|
+
describe "map reduce" do
|
138
|
+
it "should run map reduce"
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Monga::Clients::ReplicaSetClient do
|
4
|
+
before do
|
5
|
+
EM.run do
|
6
|
+
@replset = Fake::ReplicaSet.new([29000, 29100, 29200])
|
7
|
+
@client = Monga::Client.new servers: ['127.0.0.1:29000', '127.0.0.1:29100', '127.0.0.1:29200'], type: :em, timeout: 1
|
8
|
+
@collection = @client["dbTest"]["myCollection"]
|
9
|
+
EM.stop
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should fail on disconnect and reconnect when primary is up again" do
|
14
|
+
EM.run do
|
15
|
+
@replset.start_all
|
16
|
+
@collection.safe_insert(name: "Peter") do |err, resp|
|
17
|
+
@replset.primary.stop
|
18
|
+
@collection.safe_insert(name: "Peter") do |err, resp|
|
19
|
+
err.class.must_equal Monga::Exceptions::Disconnected
|
20
|
+
@collection.safe_insert(name: "Peter") do |err, resp|
|
21
|
+
err.class.must_equal Monga::Exceptions::Disconnected
|
22
|
+
@collection.safe_insert(name: "Peter") do |err, resp|
|
23
|
+
err.class.must_equal Monga::Exceptions::Disconnected
|
24
|
+
@replset.primary.start
|
25
|
+
@collection.safe_insert(name: "Madonna") do |err, resp|
|
26
|
+
err.must_equal nil
|
27
|
+
@collection.safe_insert(name: "Madonna") do |err, resp|
|
28
|
+
err.must_equal nil
|
29
|
+
@collection.safe_insert(name: "Madonna") do |err|
|
30
|
+
err.must_equal nil
|
31
|
+
EM.stop
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should work even if secondaries down" do
|
43
|
+
EM.run do
|
44
|
+
@replset.start_all
|
45
|
+
@collection.safe_insert(name: "Peter") do |err|
|
46
|
+
err.must_equal nil
|
47
|
+
@collection.safe_insert(name: "Peter") do |err|
|
48
|
+
err.must_equal nil
|
49
|
+
@replset.secondaries.each(&:stop)
|
50
|
+
@collection.safe_insert(name: "Peter") do |err|
|
51
|
+
err.must_equal nil
|
52
|
+
@collection.safe_insert(name: "Peter") do |err|
|
53
|
+
err.must_equal nil
|
54
|
+
|
55
|
+
EM.stop
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should find new primary if it is down" do
|
64
|
+
EM.run do
|
65
|
+
@replset.start_all
|
66
|
+
@collection.safe_insert(name: "Peter") do |err|
|
67
|
+
err.must_equal nil
|
68
|
+
@replset.primary.stop
|
69
|
+
@collection.safe_insert(name: "Peter") do |err|
|
70
|
+
err.class.must_equal Monga::Exceptions::Disconnected
|
71
|
+
@collection.safe_insert(name: "Peter") do |err|
|
72
|
+
err.class.must_equal Monga::Exceptions::Disconnected
|
73
|
+
@collection.safe_insert(name: "Peter") do |err|
|
74
|
+
err.class.must_equal Monga::Exceptions::Disconnected
|
75
|
+
@replset.vote
|
76
|
+
@collection.safe_insert(name: "Madonna") do |err|
|
77
|
+
err.must_equal nil
|
78
|
+
EM.stop
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Monga::Clients::SingleInstanceClient do
|
4
|
+
before do
|
5
|
+
EM.synchrony do
|
6
|
+
@client = Monga::Client.new port: 29000, type: :em
|
7
|
+
@collection = @client["dbTest"]["myCollection"]
|
8
|
+
@instance = Fake::SingleInstance.new(29000)
|
9
|
+
EM.stop
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should fail on disconnect and reconnect when instance is up again" do
|
14
|
+
EM.synchrony do
|
15
|
+
@instance.start
|
16
|
+
@collection.safe_insert(name: "Peter") do
|
17
|
+
@instance.stop
|
18
|
+
@collection.safe_insert(name: "Peter") do |err, resp|
|
19
|
+
err.class.must_equal Monga::Exceptions::Disconnected
|
20
|
+
@instance.start
|
21
|
+
@collection.safe_insert(name: "Madonna") do
|
22
|
+
EM.stop
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|