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.
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