em-mongo 0.2.8 → 0.2.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -59,7 +59,6 @@ module EM::Mongo
59
59
  request_id
60
60
  end
61
61
 
62
-
63
62
  def insert(collection_name, documents)
64
63
  message = BSON::ByteBuffer.new([0, 0, 0, 0])
65
64
  BSON::BSON_RUBY.serialize_cstr(message, collection_name)
@@ -139,79 +138,69 @@ module EM::Mongo
139
138
  succeed
140
139
  end
141
140
 
141
+ def message_received?(buffer)
142
+ x= remaining_bytes(@buffer)
143
+ x > STANDARD_HEADER_SIZE && x >= peek_size(@buffer)
144
+ end
142
145
 
143
- def message_received?
144
- size = @buffer.get_int
145
- #@buffer.put_int(size, -1)
146
- @buffer.rewind
147
-
148
- @buffer.size >= size-4
146
+ def remaining_bytes(buffer)
147
+ buffer.size-buffer.position
148
+ end
149
+
150
+ def peek_size(buffer)
151
+ position= buffer.position
152
+ size= buffer.get_int
153
+ buffer.position= position
154
+ size
149
155
  end
150
156
 
151
157
  def receive_data(data)
152
158
 
153
159
  @buffer.append!(BSON::ByteBuffer.new(data.unpack('C*')))
154
- return if @buffer.size < STANDARD_HEADER_SIZE
155
-
156
- if message_received?
157
- # Header
158
- header = BSON::ByteBuffer.new
159
- header.put_array(@buffer.get(STANDARD_HEADER_SIZE))
160
- unless header.size == STANDARD_HEADER_SIZE
161
- raise "Short read for DB header: " +
162
- "expected #{STANDARD_HEADER_SIZE} bytes, saw #{header.size}"
163
- end
164
- header.rewind
165
- size = header.get_int
166
- request_id = header.get_int
167
- response_to = header.get_int
168
- op = header.get_int
169
-
170
- # Response Header
171
- response_header = BSON::ByteBuffer.new
172
- response_header.put_array(@buffer.get(RESPONSE_HEADER_SIZE))
173
- if response_header.length != RESPONSE_HEADER_SIZE
174
- raise "Short read for DB response header; " +
175
- "expected #{RESPONSE_HEADER_SIZE} bytes, saw #{response_header.length}"
176
- end
177
-
178
- response_header.rewind
179
- result_flags = response_header.get_int
180
- cursor_id = response_header.get_long
181
- starting_from = response_header.get_int
182
- number_remaining = response_header.get_int
183
-
184
- # Documents
185
- docs = (1..number_remaining).map do |n|
186
-
187
- buf = BSON::ByteBuffer.new
188
- buf.put_int(@buffer.get_int)
189
-
190
- buf.rewind
191
- size = buf.get_int
192
-
193
- if size > @buffer.size
194
- @buffer = ''
195
- raise "Buffer Overflow: Failed to parse document buffer: size: #{size}, expected: #{@buffer.size}"
196
- end
197
- buf.put_array(@buffer.get(size-4), 4)
198
-
199
- buf.rewind
200
- BSON::BSON_CODER.deserialize(buf)
201
- end
160
+
161
+ @buffer.rewind
162
+ while message_received?(@buffer)
163
+ response_to, docs= next_response
164
+ callback = @responses.delete(response_to)
165
+ callback.call(docs) if callback
166
+ end
202
167
 
168
+ if @buffer.more?
169
+ remaining_bytes= @buffer.size-@buffer.position
170
+ @buffer = BSON::ByteBuffer.new(@buffer.get(remaining_bytes))
171
+ @buffer.rewind
172
+ else
203
173
  @buffer.clear
204
-
205
- if cb = @responses.delete(response_to)
206
- cb.call(docs)
207
- end
208
- close_connection if @close_pending and @responses.size == 0
209
174
  end
175
+
176
+ close_connection if @close_pending && @responses.empty?
210
177
 
211
178
  end
212
-
213
- def send_data data
214
- super data
179
+
180
+ def next_response()
181
+
182
+ # Header
183
+ size = @buffer.get_int
184
+ request_id = @buffer.get_int
185
+ response_to = @buffer.get_int
186
+ op = @buffer.get_int
187
+ #puts "message header #{size} #{request_id} #{response_to} #{op}"
188
+
189
+ # Response Header
190
+ result_flags = @buffer.get_int
191
+ cursor_id = @buffer.get_long
192
+ starting_from = @buffer.get_int
193
+ number_returned = @buffer.get_int
194
+ #puts "response header #{result_flags} #{cursor_id} #{starting_from} #{number_returned}"
195
+
196
+ # Documents
197
+ docs = number_returned.times.collect do
198
+ size= peek_size(@buffer)
199
+ buf = BSON::ByteBuffer.new(@buffer.get(size))
200
+ BSON::BSON_CODER.deserialize(buf)
201
+ end
202
+
203
+ [response_to,docs]
215
204
  end
216
205
 
217
206
  def unbind
@@ -228,14 +217,8 @@ module EM::Mongo
228
217
  end
229
218
  end
230
219
 
231
- private
232
-
233
- def log *args
234
- puts args
235
- puts
236
- end
237
-
238
220
  end
221
+
239
222
  end
240
223
 
241
224
  # Make EM::Mongo look like mongo-ruby-driver
data/lib/em-mongo.rb CHANGED
@@ -7,7 +7,7 @@ module EM::Mongo
7
7
  module Version
8
8
  MAJOR = 0
9
9
  MINOR = 2
10
- TINY = 8
10
+ TINY = 9
11
11
  STRING = [MAJOR, MINOR, TINY].join('.')
12
12
  end
13
13
 
@@ -4,7 +4,7 @@ describe EMMongo::Collection do
4
4
  include EM::SpecHelper
5
5
 
6
6
  before(:all) do
7
- @numbers = {
7
+ @numbers = {
8
8
  1 => 'one',
9
9
  2 => 'two',
10
10
  3 => 'three',
@@ -32,7 +32,7 @@ describe EMMongo::Collection do
32
32
 
33
33
  it 'should find an object by attribute' do
34
34
  EM::Spec::Mongo.collection do |collection|
35
- collection.insert("hello" => 'world')
35
+ collection.insert("hello" => 'world')
36
36
  r = collection.find({"hello" => "world"},{}) do |res|
37
37
  res.size.should >= 1
38
38
  res[0]["hello"].should == "world"
@@ -43,7 +43,7 @@ describe EMMongo::Collection do
43
43
 
44
44
  it 'should find an object by id' do
45
45
  EM::Spec::Mongo.collection do |collection|
46
- obj = collection.insert('hello' => 'world')
46
+ obj = collection.insert('hello' => 'world')
47
47
  collection.find({'_id' => obj['_id']},{}) do |res|
48
48
  res.size.should >= 1
49
49
  res[0]['hello'].should == "world"
@@ -153,7 +153,7 @@ describe EMMongo::Collection do
153
153
  end
154
154
  EM::Spec::Mongo.close
155
155
  end
156
-
156
+
157
157
  end
158
158
  end
159
159
 
@@ -201,4 +201,19 @@ describe EMMongo::Collection do
201
201
  end
202
202
  end
203
203
 
204
+ it 'should handle multiple pending queries' do
205
+ EM::Spec::Mongo.collection do |collection|
206
+ id = collection.insert("foo" => "bar")['_id']
207
+ received = 0
208
+
209
+ 10.times do |n|
210
+ collection.first("_id" => id) do |res|
211
+ received += 1
212
+ EM::Spec::Mongo.close if received == 10
213
+ end
214
+ end
215
+
216
+ end
217
+ end
218
+
204
219
  end
@@ -7,37 +7,41 @@ describe EMMongo::Connection do
7
7
  em do
8
8
  connection = EMMongo::Connection.new
9
9
  EM.next_tick do
10
- connection.connected?.should == true
10
+ connection.should be_connected
11
11
  done
12
12
  end
13
- end
13
+ end
14
14
  end
15
-
15
+
16
16
  it 'should close' do
17
17
  em do
18
18
  connection = EMMongo::Connection.new
19
+
19
20
  EM.add_timer(1) do
20
- connection.connected?.should == true
21
+ connection.should be_connected
21
22
  connection.close
22
23
  end
24
+
23
25
  EM.add_timer(2) do
24
26
  EM.next_tick do
25
- connection.connected?.should == false
27
+ connection.should_not be_connected
26
28
  done
27
29
  end
28
30
  end
29
- end
31
+ end
30
32
  end
31
33
 
32
- it 'should instantiate a Databse' do
34
+ it 'should instantiate a Database' do
33
35
  EM::Spec::Mongo.connection do |connection|
34
36
  db1 = connection.db
35
- db1.is_a?(EM::Mongo::Database).should == true
37
+ db1.should be_kind_of(EM::Mongo::Database)
38
+
36
39
  db2 = connection.db('db2')
37
- db2.is_a?(EM::Mongo::Database).should == true
40
+ db2.should be_kind_of(EM::Mongo::Database)
38
41
  db2.should_not == db1
42
+
39
43
  EM::Spec::Mongo.close
40
- end
44
+ end
41
45
  end
42
46
 
43
47
 
data/spec/spec_helper.rb CHANGED
@@ -40,3 +40,4 @@ module EM
40
40
  end
41
41
  end
42
42
 
43
+ $stdout.sync = true
metadata CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
5
5
  segments:
6
6
  - 0
7
7
  - 2
8
- - 8
9
- version: 0.2.8
8
+ - 9
9
+ version: 0.2.9
10
10
  platform: ruby
11
11
  authors:
12
12
  - bcg