em-mongo 0.2.8 → 0.2.9

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