monga 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (63) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +1 -0
  3. data/README.md +59 -3
  4. data/lib/monga/client.rb +51 -6
  5. data/lib/monga/clients/master_slave_client.rb +0 -5
  6. data/lib/monga/clients/replica_set_client.rb +32 -71
  7. data/lib/monga/clients/single_instance_client.rb +53 -0
  8. data/lib/monga/collection.rb +102 -41
  9. data/lib/monga/connection.rb +38 -13
  10. data/lib/monga/connection_pool.rb +6 -17
  11. data/lib/monga/connections/buffer.rb +33 -0
  12. data/lib/monga/connections/em_connection.rb +25 -56
  13. data/lib/monga/connections/em_proxy_connection.rb +80 -0
  14. data/lib/monga/connections/fibered_connection.rb +26 -0
  15. data/lib/monga/connections/fibered_proxy_connection.rb +23 -0
  16. data/lib/monga/connections/proxy_connection.rb +4 -0
  17. data/lib/monga/connections/tcp_connection.rb +57 -0
  18. data/lib/monga/cursor.rb +197 -95
  19. data/lib/monga/database.rb +175 -60
  20. data/lib/monga/{requests → protocol}/delete.rb +1 -2
  21. data/lib/monga/{requests → protocol}/get_more.rb +1 -1
  22. data/lib/monga/{requests → protocol}/insert.rb +1 -2
  23. data/lib/monga/{requests → protocol}/kill_cursors.rb +1 -1
  24. data/lib/monga/{requests → protocol}/query.rb +3 -3
  25. data/lib/monga/{requests → protocol}/update.rb +1 -1
  26. data/lib/monga/request.rb +27 -23
  27. data/lib/monga/utils/constants.rb +5 -0
  28. data/lib/monga/utils/exceptions.rb +11 -0
  29. data/lib/monga.rb +19 -11
  30. data/monga.gemspec +2 -2
  31. data/spec/helpers/mongodb.rb +115 -38
  32. data/spec/monga/block/collection_spec.rb +172 -0
  33. data/spec/monga/block/cursor_spec.rb +160 -0
  34. data/spec/monga/block/database_spec.rb +80 -0
  35. data/spec/monga/block/single_instance_client_spec.rb +31 -0
  36. data/spec/monga/em/collection_spec.rb +308 -0
  37. data/spec/monga/em/cursor_spec.rb +256 -0
  38. data/spec/monga/em/database_spec.rb +140 -0
  39. data/spec/monga/em/replica_set_client_spec.rb +86 -0
  40. data/spec/monga/em/single_instance_client_spec.rb +28 -0
  41. data/spec/monga/sync/collection_spec.rb +247 -0
  42. data/spec/monga/sync/cursor_spec.rb +211 -0
  43. data/spec/monga/sync/database_spec.rb +110 -0
  44. data/spec/monga/sync/replica_set_client_spec.rb +54 -0
  45. data/spec/monga/sync/single_instance_client_spec.rb +25 -0
  46. data/spec/spec_helper.rb +2 -20
  47. metadata +50 -38
  48. data/lib/monga/clients/client.rb +0 -24
  49. data/lib/monga/connections/primary.rb +0 -46
  50. data/lib/monga/connections/secondary.rb +0 -13
  51. data/lib/monga/exceptions.rb +0 -9
  52. data/lib/monga/miner.rb +0 -72
  53. data/lib/monga/response.rb +0 -11
  54. data/spec/helpers/truncate.rb +0 -15
  55. data/spec/monga/collection_spec.rb +0 -448
  56. data/spec/monga/connection_pool_spec.rb +0 -50
  57. data/spec/monga/connection_spec.rb +0 -64
  58. data/spec/monga/cursor_spec.rb +0 -186
  59. data/spec/monga/database_spec.rb +0 -67
  60. data/spec/monga/replica_set_client_spec.rb +0 -46
  61. data/spec/monga/requests/delete_spec.rb +0 -0
  62. data/spec/monga/requests/insert_spec.rb +0 -0
  63. 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