em-mongo 0.4.3 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ Gemfile.lock
2
+ .bundle
3
+ *.gem
4
+ vendor
data/CHANGELOG ADDED
@@ -0,0 +1,117 @@
1
+ - 0.5.0
2
+
3
+ * debian packaging changes
4
+ (https://github.com/bcg/em-mongo/pull/53)
5
+ * added new 2d indexes EM::Mongo::FLAT2D, EM::Mongo::SPHERE2D
6
+ (https://github.com/bcg/em-mongo/pull/49)
7
+
8
+ - 0.4.3
9
+
10
+ * ensure new buffers aren't created when not needed (FlockOfBirds) #40
11
+
12
+ - 0.4.2
13
+
14
+ * defer_as_a instead to to_a
15
+ * bugger optimizations
16
+ * Jruby fixes
17
+
18
+ - 0.4.1
19
+
20
+ * fix collection response value on success (pawelpacana)
21
+ * whitepsace (pawelpacana)
22
+
23
+ - 0.4.0
24
+
25
+ * added a Cursor implementation
26
+ * replaced raw callbacks in the API with deferrables
27
+ * removed CRUD methods from the Connection
28
+ * added a variety of server side aggregation commands
29
+ * added support for indexes
30
+ * added safe update methods
31
+
32
+ - 0.3.6
33
+
34
+ * dj2: fixes reconnects. (see: https://github.com/bcg/em-mongo/pull/23)
35
+
36
+ - 0.3.5
37
+
38
+ * gvarela: added orderby functionality based on the mongo-ruby-driver.
39
+ (https://github.com/bcg/em-mongo/pull/19)
40
+
41
+ - 0.3.4
42
+
43
+ * Silly regression issue. Added em requires to tests and so I missed it when
44
+ I yanked it from lib/em-mongo.rb
45
+ * dynamix found *another* regression in the new database code.
46
+ (see: https://github.com/bcg/em-mongo/pull/16)
47
+
48
+ - 0.3.3
49
+
50
+ * Yank Bundler out lib/em-mongo.rb and push it into spec/spec_helper.rb
51
+ * Numerous Rakefile changes
52
+
53
+ - 0.3.2
54
+
55
+ * Added spec/gem to help with release testing
56
+ * Added some Rakefile helpers
57
+
58
+ - 0.3.1
59
+
60
+ * Added VERSION to the gem. It was breaking the new EM::Mongo::Version module.
61
+
62
+ - 0.3
63
+
64
+ * Refactored test suite
65
+ * Followed ruby-mongo-driver's _id convention. This will BREAK your apps.
66
+ See: http://twitter.com/#!/brendengrace/status/9445253316608000
67
+ * Split out database.rb and pulled in support.rb and conversons.rb from
68
+ ruby-mongo-driver
69
+ * Added initial authentication support to to EM::Mongo::Database
70
+
71
+ - 0.2.14
72
+
73
+ * .close was reconnecting automatically so now its configureable
74
+
75
+ - 0.2.12
76
+
77
+ * Use BSON::ObjectID for _id instead of String (gaffneyc).
78
+
79
+ = 0.2.11
80
+
81
+ * Auto Reconnect on lost connection (dj2)
82
+ * Options handling on Em.connect (dj2)
83
+ * Bundler support (pkieltyka)
84
+
85
+ = 0.2.10
86
+
87
+ * Ruby 1.8 was broken in the last set of patches pulled in.
88
+
89
+ = 0.2.9
90
+
91
+ * Performance enhacements by merrells
92
+ * Cleanups by jarib
93
+
94
+ = 0.2.7
95
+
96
+ * Fixes modifier issues in update. BSON would not allow '$' with key checks. (http://github.com/bcg/em-mongo/issues/3)
97
+
98
+ = 0.2.6
99
+
100
+ * 'limit' was broken in find because of poor protocol parsing. (http://github.com/bcg/em-mongo/issues/1)
101
+
102
+ = 0.2.5
103
+
104
+ * collection.update
105
+
106
+ = 0.2.4
107
+
108
+ * Remove support for symbols, needs to be enforced still
109
+ * Remove lib/buffer.rb and all custom BSON parsing
110
+ * Remove UUID dependency (replaced by BSON::ObjectID.new)
111
+ * Fixes a BufferOverflow because of misunderstood types
112
+
113
+ = 0.1.1 - Initial Relase
114
+
115
+ * Rspec tests
116
+ * Fixes a BufferOverflow with large Hashes
117
+ * Fork of RMongo
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source :gemcutter
2
+
3
+ gemspec
4
+
5
+ group :development do
6
+ gem "rspec", "< 1.3"
7
+ gem "em-spec", :git => "https://github.com/mloughran/em-spec.git"
8
+ end
9
+
data/README.rdoc ADDED
@@ -0,0 +1,255 @@
1
+
2
+ Em-mongo is no longer being maintained (hasn't been for some time). If you are interested in the commit bit
3
+ or want to take over the full project, please let me know!
4
+
5
+ = EM-Mongo
6
+
7
+ An EventMachine client for MongoDB. Originally based on RMongo, this client aims to be as api compatible
8
+ with mongo-ruby-driver as possible.
9
+
10
+ For methods that do not retrieve data from the database the api of em-mongo should be identical (though a subset) to the mongo-ruby-driver. This includes the various update methods like insert, save and update (without the :safe flag, which is handled separately) as well as find, which returns a cursor.
11
+
12
+ For operations that require IO, em-mongo always returns an EventMachine deferrable.
13
+
14
+ == Some examples
15
+
16
+ #this file can be found in the examples directory.
17
+ # bundle exec examples/readme.rb
18
+
19
+ #insert a few records, then read some back using Collection#find
20
+
21
+ require 'em-mongo'
22
+ require 'eventmachine'
23
+
24
+ EM.run do
25
+ db = EM::Mongo::Connection.new('localhost').db('my_database')
26
+ collection = db.collection('my_collection')
27
+ EM.next_tick do
28
+ (1..10).each do |i|
29
+ collection.insert( { :revolution => i } )
30
+ end
31
+
32
+ #find returns an EM::Mongo::Cursor
33
+
34
+ cursor = collection.find
35
+
36
+ #most cursor methods return an EM::Mongo::RequestResponse,
37
+ #which is an EventMachine::Deferrable
38
+
39
+ resp = cursor.defer_as_a
40
+
41
+ #when em-mongo IO methods succeed, they
42
+ #will always call back with the return
43
+ #value you would have expected from the
44
+ #synchronous version of the same method from
45
+ #the mongo-ruby-driver
46
+
47
+ resp.callback do |documents|
48
+ puts "I just got #{documents.length} documents! I'm really cool!"
49
+ end
50
+
51
+ #when em-mongo IO methods fail, they
52
+ #errback with an array in the form
53
+ #[ErrorClass, "error message"]
54
+
55
+ resp.errback do |err|
56
+ raise *err
57
+ end
58
+
59
+ #iterate though each result in a query
60
+
61
+ collection.find( :revolution => { "$gt" => 5 } ).limit(1).skip(1).each do |doc|
62
+ #unlike the mongo-ruby-driver, each returns null at the end of the cursor
63
+ if doc
64
+ puts "Revolution ##{doc['revolution']}"
65
+ end
66
+ end
67
+
68
+ #add an index
69
+
70
+ collection.create_index [[:revolution, -1]]
71
+
72
+ #insert a document and ensure it gets written
73
+
74
+ save_resp = collection.safe_save( { :hi => "there" }, :last_error_params => {:fsync=>true} )
75
+ save_resp.callback { puts "Hi is there, let us give thanks" }
76
+ save_resp.errback { |err| puts "AAAAAAAAAAAAAAAARGH! Oh why! WHY!?!?!" }
77
+
78
+ collection.drop
79
+
80
+ EM.add_periodic_timer(1) { EM.stop }
81
+
82
+ end
83
+
84
+ end
85
+
86
+ == Error handling
87
+
88
+ em-mongo will present errors in two different ways. First, em-mongo will raise exceptions like any other synchronous library if an error is enountered in a method that does not need to perform IO or if an error is encountered prior to peforming IO.
89
+
90
+ Errors returned by the database, or errors communicating with the database, will be delivered via standard EM::Deferrable errbacks. While it is tempting to subscribe just to a callback
91
+
92
+ my_collection.find.defer_as_a.callback {|docs| ... }
93
+
94
+ in the case of an error you will never receive a response. If you are waiting for a response before your program continues, you will be waiting a very long time. A better approach would be to store the deferrable into a variable and subscribe to its callback and errback
95
+
96
+ resp = my_collection.find.defer_as_a
97
+ resp.callback { |docs| ... }
98
+ resp.errback { |err| raise *err }
99
+
100
+ errback's blocks will always be called with a single argument which is a two element array containing the error class and the error message
101
+
102
+ [EM::Mongo::OperationError, "aw snap"]
103
+
104
+ == Safe Writes
105
+
106
+ As you are probably aware the default behavior for the mongo-ruby-driver, and therefore em-mongo, is to send update messages to MongoDB in a fire-and-forget manner. This means that if a unique index is violated, or some other problem causes MongoDB to raise an exception and refuse to apply your changes, you'll never know about it until you go to look for that record later. For many applications such as logging this might be OK, but for many use cases like analytics you will want to know if your writes don't succeed.
107
+
108
+ This is one place where em-mongo diverges substantially from the mongo-ruby-driver because an unsafe write will not receive a response from the server, whereas a safe write will receive a response from the server and requires a deferrable and a callback.
109
+
110
+ #default, unsafe write
111
+ my_collection.insert( {:a => "b" } )
112
+
113
+ #a safe write using em-mongo
114
+ insert_resp = my_collection.safe_insert( {:a => "b" } )
115
+ insert_resp.callback { #all ok }
116
+ insert_resp.errback { |err| puts '<sigh>' }
117
+
118
+ em-mongo has the following safe methods:
119
+ safe_insert, safe_update, safe_save
120
+
121
+ In addition to calling your errback if the write fails, you can provide the usual 'safety' options that you can to Database#get_last_error, such as :fsync => true or :w => 2, to control the degree of safety you want. Please the 10gen documentation on DB#get_last_error for specifics.
122
+
123
+ safe_insert( {:a=>"v"}, :last_error_params => { :fsync => true, :w => 5 } )
124
+
125
+ == Documentation
126
+
127
+ em-mongo now has some YARD docs. These are mostly ported directly from the mongo-ruby-driver. While they have been updated to reflect em-mongo's async API, there are probably a few errors left over in the translation. Please file an issue or submit a pull request if you notice any inaccuracies.
128
+
129
+ http://rubydoc.info/github/bcg/em-mongo/master/frames
130
+
131
+ == Upgrading
132
+
133
+ **The API for em-mongo has changed since version 0.3.6.**
134
+
135
+ em-mongo methods no longer directly accept callbacks and instead return EM::Mongo::RequestResponse objects, which are EM::Deferrable(s). This means you need to convert calls like this
136
+
137
+ my_collection.first() { |doc| p doc }
138
+
139
+ to this
140
+
141
+ my_collection.first().callback { |doc| p doc }
142
+
143
+ EM::Mongo::Collection#find now returns a cursor, not an array, to maintain compatibility with the mongo-ruby-driver. This provides a great deal more flexibility, but requires you to select a specific cursor method to actually fetch data from the server, such as #defer_as_a or #next
144
+
145
+ my_collection.find() { |docs| ... }
146
+
147
+ becomes
148
+
149
+ my_collection.find.defer_as_a.callback { |docs| ... }
150
+
151
+ If for some reason you aren't ready to upgrade your project but you want to be able to use the newer gem, you can require a compatibility file that will revert the new API to the API found in 0.3.6
152
+
153
+ require 'em-mongo'
154
+ require 'em-mongo/prev.rb'
155
+
156
+ This file will not remain in the project forever, though, so it is better to upgrade your projects sooner rather than later.
157
+
158
+ == What's in the box?
159
+
160
+ === Collection
161
+
162
+ CRUD operations
163
+
164
+ #find, #find_one, #save, #safe_save, #insert, #save_insert, #update, #safe_update, #remove, #find_and_modify
165
+
166
+ Index management
167
+
168
+ #create_index, #drop_index
169
+
170
+ Collection management
171
+
172
+ #drop, #stats, #count, #name
173
+
174
+ Server-side aggregations
175
+
176
+ #map_reduce, #group, #distinct
177
+
178
+ === Database
179
+
180
+ Collection management
181
+
182
+ #collection, #collection_names, #collections, #collections_info, #create_collection, #drop_collection
183
+
184
+ Index management
185
+
186
+ #drop_index, #index_information
187
+
188
+ Authentication
189
+
190
+ #authenticate, #add_user
191
+
192
+ Misc
193
+
194
+ #get_last_error, #error?, #name, #command
195
+
196
+ === Cursor
197
+
198
+ Query options
199
+ :selector, :order, :skip, :limit, :explain, :batch_size, :fields, :tailable, :transformer
200
+
201
+ Enumerable-ish
202
+ **EM::Mongo::Cursor does **not** use the Enumerable mixin for obvious reasons**
203
+
204
+ #next_document, #rewind!, #has_next?, #count, #each, #to_a
205
+
206
+ Misc
207
+
208
+ #batch_size, #explain, #close, #closed?
209
+
210
+ Query modifier methods
211
+
212
+ #sort, #limit, #skip
213
+
214
+ == Compatibility
215
+ * em-mongo has been tested on Ruby 1.8.7 and 1.9.2
216
+ * em-mongo will not run under JRuby. We'd love some help figuring out why :)
217
+ * Compatibility with other runtimes is unknown
218
+
219
+ == Still Missing / TODO
220
+ * Replica Sets
221
+ * GRIDFS support
222
+ * Connection pooling
223
+ * PK factories
224
+ * JRuby support
225
+
226
+ == Contact
227
+
228
+ * Twitter: @brendengrace
229
+ * IRC: bcg
230
+ * Email: brenden.grace@gmail.com
231
+
232
+ == Credit
233
+
234
+ Aman Gupta (tmm1) wrote the original RMongo which em-mongo is based on.
235
+
236
+ == References
237
+
238
+ * Rmongo: http://github.com/tmm1/rmongo
239
+ * EM-Mongo: http://github.com/bcg/em-mongo
240
+ * mongo-ruby-driver: http://github.com/mongodb/mongo-ruby-driver
241
+ * Mongo Wire Protocol: http://www.mongodb.org/display/DOCS/Mongo+Wire+Protocol
242
+
243
+ == License
244
+
245
+ (The MIT License)
246
+
247
+ Copyright © 2010 Brenden Grace
248
+
249
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
250
+
251
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
252
+
253
+ THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
254
+
255
+
data/Rakefile ADDED
@@ -0,0 +1,127 @@
1
+
2
+ require 'fileutils'
3
+ require 'tmpdir'
4
+
5
+ def em_mongo_version
6
+ File.read("VERSION").strip
7
+ end
8
+
9
+ def root_dir
10
+ File.dirname(__FILE__)
11
+ end
12
+
13
+ task :default => 'spec:integration:default'
14
+
15
+ class MongoRunner
16
+ def self.run(options={})
17
+ auth = "--auth" if options[:auth]
18
+ dir = Dir.tmpdir + "/em-mongo-tests-#$$"
19
+ FileUtils.mkdir dir
20
+ pidf = "#{dir}/mongod.pid"
21
+ logf = "#{dir}/mongo.log"
22
+ begin
23
+ system "mongod run #{auth} --fork -vvvvvvv --dbpath #{dir} --pidfilepath #{pidf} --logpath #{logf} >> /dev/null "
24
+ yield if block_given?
25
+ ensure
26
+ if File.exists?(pidf) and File.read(pidf).to_i != 0
27
+ Process.kill("KILL", File.read(pidf).to_i)
28
+ FileUtils.rm_r dir unless options[:noclean]
29
+ end
30
+ end
31
+ end
32
+ end
33
+
34
+ spec = eval(File.read('em-mongo.gemspec'))
35
+
36
+ namespace :bundle do
37
+ task :install do
38
+ if `bundle check` =~ /bundle install/
39
+ system("bundle install --path vendor/gems")
40
+ end
41
+ end
42
+ end
43
+
44
+ namespace :gem do
45
+
46
+ desc "build gem"
47
+ task :build do
48
+ puts "Building em-mongo #{em_mongo_version}"
49
+ system "gem build em-mongo.gemspec -q"
50
+ end
51
+
52
+ desc "release gem"
53
+ task :release do
54
+ system "gem push em-mongo-#{em_mongo_version}.gem"
55
+ end
56
+
57
+ end
58
+
59
+ namespace :spec do
60
+
61
+ namespace :gem do
62
+
63
+ desc "bundler tests"
64
+ task :bundler do
65
+ MongoRunner.run do
66
+ print "Testing Bundler integration ... "
67
+ if system "cd spec/gem && bundle install --quiet && ./bundler.rb"
68
+ puts "SUCCESS."
69
+ else
70
+ puts "FAILURE."
71
+ end
72
+ end
73
+ end
74
+
75
+ desc "rubygems tests"
76
+ task :rubygems do
77
+ MongoRunner.run do
78
+ print "Testing Rubygems integration ... "
79
+ steps =[]
80
+ steps << "cd spec/gem"
81
+
82
+ if `gem list -i em-mongo` == 'true'
83
+ steps << "gem uninstall --force -a em-mongo >/dev/null"
84
+ end
85
+ steps << "gem install #{root_dir}/em-mongo-#{em_mongo_version}.gem >/dev/null "
86
+ steps << "./rubygems.rb"
87
+ if system steps.join(" && ")
88
+ puts "SUCCESS."
89
+ else
90
+ puts "FAILURE."
91
+ end
92
+ end
93
+ end
94
+
95
+ desc "all gem tests"
96
+ task :all => [:bundler, :rubygems]
97
+ end
98
+
99
+ namespace :integration do
100
+
101
+ desc "default tests"
102
+ task :default => ['bundle:install'] do
103
+ MongoRunner.run do
104
+ system "bundle exec spec #{spec.test_files.join(' ')} -t -b -fs -color"
105
+ end
106
+ end
107
+
108
+ desc "exhaustive tests"
109
+ task :exhaustive => ['bundle:install'] do
110
+ MongoRunner.run({:noclean => true}) do
111
+ system "bundle exec spec #{spec.test_files.join(' ')} -t -b -fs -color"
112
+ end
113
+ MongoRunner.run({:auth => true}) do
114
+ system "bundle exec spec #{spec.test_files.join(' ')} -t -b -fs -color"
115
+ end
116
+ end
117
+
118
+ desc "default tests, but don't start mongodb for me"
119
+ task :no_mongo => ['bundle:install'] do
120
+ system "bundle exec spec #{spec.test_files.join(' ')} -t -b -fs -color"
121
+ end
122
+
123
+ end
124
+
125
+ desc "release testing"
126
+ task :release => ['spec:integration:default','gem:build','spec:gem:bundler','spec:gem:rubygems']
127
+ end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.4.3
1
+ 0.5.0
data/em-mongo.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ version = File.read("VERSION").strip
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'em-mongo'
5
+ s.version = version
6
+
7
+ s.authors = ['bcg', 'PlasticLizard']
8
+ s.email = 'brenden.grace@gmail.com'
9
+ s.date = "2010-12-01"
10
+
11
+ s.description = 'EventMachine driver for MongoDB.'
12
+ s.homepage = 'https://github.com/bcg/em-mongo'
13
+ s.rubyforge_project = 'em-mongo'
14
+
15
+ s.files = `git ls-files`.split("\n")
16
+
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+
19
+ s.extra_rdoc_files = ["README.rdoc"]
20
+ s.rdoc_options = ["--charset=UTF-8"]
21
+ s.require_paths = ["lib"]
22
+
23
+ s.rubygems_version = '1.3.6'
24
+
25
+ s.summary = 'An EventMachine driver for MongoDB.'
26
+
27
+ s.add_dependency 'eventmachine', ['>= 0.12.10']
28
+ s.add_dependency 'bson', ['>= 1.1.3']
29
+
30
+ end
@@ -0,0 +1,38 @@
1
+ #bundle exec ruby examples/legacy.rb
2
+ require 'em-mongo'
3
+ require 'em-mongo/prev.rb'
4
+
5
+ require 'eventmachine'
6
+
7
+ EM.run do
8
+ conn = EM::Mongo::Connection.new('localhost')
9
+ db = conn.db('my_database')
10
+ collection = db.collection('my_collection')
11
+ EM.next_tick do
12
+
13
+ (1..10).each do |i|
14
+ conn.insert('my_database.my_collection', { :revolution => i } )
15
+ end
16
+
17
+ conn.update('my_database.my_collection', {:revolution => 9}, {:revolution => 8.5})
18
+
19
+ conn.delete('my_database.my_collection', {:revolution => 1})
20
+
21
+ collection.find do |documents|
22
+ puts "I just got #{documents.length} documents! I'm really cool!"
23
+ end
24
+
25
+ #iterate though each result in a query
26
+ collection.find( {:revolution => { "$gt" => 5 }}, :limit =>1, :skip => 1, :order => [:revolution, -1]) do |docs|
27
+ docs.each do |doc|
28
+ puts "Revolution ##{doc['revolution']}"
29
+ end
30
+ end
31
+
32
+ collection.drop
33
+
34
+ EM.add_periodic_timer(1) { EM.stop }
35
+
36
+ end
37
+
38
+ end
@@ -0,0 +1,58 @@
1
+ #bundle exec ruby examples/readme.rb
2
+ require 'em-mongo'
3
+ require 'eventmachine'
4
+
5
+ EM.run do
6
+ db = EM::Mongo::Connection.new('localhost').db('my_database')
7
+ collection = db.collection('my_collection')
8
+ EM.next_tick do
9
+ (1..10).each do |i|
10
+ collection.insert( { :revolution => i } )
11
+ end
12
+
13
+ #find returns an EM::Mongo::Cursor
14
+ cursor = collection.find
15
+
16
+ #most cursor methods return an EM::Mongo::RequestResponse,
17
+ #which is an EventMachine::Deferrable
18
+ resp = cursor.to_a
19
+
20
+ #when em-mongo IO methods succeed, they
21
+ #will always call back with the return
22
+ #value you would have expected from the
23
+ #synchronous version of the method from
24
+ #the mongo-ruby-driver
25
+ resp.callback do |documents|
26
+ puts "I just got #{documents.length} documents! I'm really cool!"
27
+ end
28
+
29
+ #when em-mongo IO methods fail, they
30
+ #errback with an array in the form
31
+ #[ErrorClass, "error message"]
32
+ resp.errback do |err|
33
+ raise *err
34
+ end
35
+
36
+ #iterate though each result in a query
37
+ collection.find( :revolution => { "$gt" => 5 } ).limit(1).skip(1).each do |doc|
38
+ #unlike the mongo-ruby-driver, each returns null at the end of the cursor
39
+ if doc
40
+ puts "Revolution ##{doc['revolution']}"
41
+ end
42
+ end
43
+
44
+ #add an index
45
+ collection.create_index [[:revolution, -1]]
46
+
47
+ #insert a document and ensure it gets written
48
+ save_resp = collection.safe_save( { :hi => "there" }, :last_error_params => {:fsync=>true} )
49
+ save_resp.callback { puts "Hi is there, let us give thanks" }
50
+ save_resp.errback { |err| puts "AAAAAAAAAAAAAAAARGH! Oh why! WHY!?!?!" }
51
+
52
+ collection.drop
53
+
54
+ EM.add_periodic_timer(1) { EM.stop }
55
+
56
+ end
57
+
58
+ end
@@ -597,7 +597,10 @@ module EM::Mongo
597
597
  # @param [String, Array] spec
598
598
  # should be either a single field name or an array of
599
599
  # [field name, direction] pairs. Directions should be specified
600
- # as Mongo::ASCENDING, Mongo::DESCENDING, or Mongo::GEO2D.
600
+ # as EM::Mongo::ASCENDING, EM::Mongo::DESCENDING, EM::Mongo::FLAT2D, EM::Mongo::SPHERE2D
601
+ #
602
+ # Note that MongoDB 2.2 used 2d flat indexes and called them geo, MongoDB 2.4 has 2d and 2dsphere indexes
603
+ # EM::Mongo::GEO2D is kept for backward compatiblity and is creating a flat 2d index
601
604
  #
602
605
  # Note that geospatial indexing only works with versions of MongoDB >= 1.3.3+. Keep in mind, too,
603
606
  # that in order to geo-index a given field, that field must reference either an array or a sub-object
@@ -618,10 +621,10 @@ module EM::Mongo
618
621
  # @option opts [Integer] :max (nil) specify the maximum longitude and latitude for a geo index.
619
622
  #
620
623
  # @example Creating a compound index:
621
- # @posts.create_index([['subject', Mongo::ASCENDING], ['created_at', Mongo::DESCENDING]])
624
+ # @posts.create_index([['subject', EM::Mongo::ASCENDING], ['created_at', EM::Mongo::DESCENDING]])
622
625
  #
623
626
  # @example Creating a geospatial index:
624
- # @restaurants.create_index([['location', Mongo::GEO2D]])
627
+ # @restaurants.create_index([['location', EM::Mongo::SPHERE2D]])
625
628
  #
626
629
  # # Note that this will work only if 'location' represents x,y coordinates:
627
630
  # {'location': [0, 50]}
@@ -629,7 +632,7 @@ module EM::Mongo
629
632
  # {'location': {'latitude' => 0, 'longitude' => 50}}
630
633
  #
631
634
  # @example A geospatial index with alternate longitude and latitude:
632
- # @restaurants.create_index([['location', Mongo::GEO2D]], :min => 500, :max => 500)
635
+ # @restaurants.create_index([['location', EM::Mongo::SPHERE2D]], :min => 500, :max => 500)
633
636
  #
634
637
  # @return [String] the name of the index created.
635
638
  #
@@ -770,11 +773,13 @@ module EM::Mongo
770
773
  field_spec[spec.to_s] = 1
771
774
  elsif spec.is_a?(Array) && spec.all? {|field| field.is_a?(Array) }
772
775
  spec.each do |f|
773
- if [EM::Mongo::ASCENDING, EM::Mongo::DESCENDING, EM::Mongo::GEO2D].include?(f[1])
776
+ if [EM::Mongo::ASCENDING, EM::Mongo::DESCENDING,
777
+ EM::Mongo::SPHERE2D, EM::Mongo::FLAT2D, EM::Mongo::GEO2D].include?(f[1])
774
778
  field_spec[f[0].to_s] = f[1]
775
779
  else
776
780
  raise MongoArgumentError, "Invalid index field #{f[1].inspect}; " +
777
- "should be one of Mongo::ASCENDING (1), Mongo::DESCENDING (-1) or Mongo::GEO2D ('2d')."
781
+ "should be one of EM::Mongo::ASCENDING (1), EM::Mongo::DESCENDING (-1), EM::Mongo::SPHERE2D ('2dsphere')" +
782
+ " or EM::Mongo::FLAT2D ('2d') (GEO2D is deprecated)"
778
783
  end
779
784
  end
780
785
  else
@@ -23,6 +23,8 @@ module EM::Mongo
23
23
 
24
24
  ASCENDING = 1
25
25
  DESCENDING = -1
26
+ FLAT2D = '2d'
27
+ SPHERE2D = '2dsphere'
26
28
  GEO2D = '2d'
27
29
 
28
30
  DEFAULT_MAX_BSON_SIZE = 4 * 1024 * 1024
data/spec/gem/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source :gemcutter
2
+
3
+ gem 'eventmachine'
4
+ gem 'bson'
5
+ gem 'em-mongo', :path => '../../'
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env bundle exec ruby
2
+
3
+ require "rubygems"
4
+ require "bundler"
5
+ Bundler.setup(:default)
6
+ require "eventmachine"
7
+ require "em-mongo"
8
+
9
+ $return = -1
10
+
11
+ EM.run do
12
+ @conn = EM::Mongo::Connection.new
13
+ EM.next_tick do
14
+ id = @conn.db.collection('test').insert({:hello => "world"})
15
+ @conn.db.collection('test').first(:_id => id) do |document|
16
+ $return = 0 if document
17
+ EM.stop
18
+ end
19
+ end
20
+ end
21
+ exit($return)
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "eventmachine"
5
+ require "em-mongo"
6
+
7
+ $return = -1
8
+
9
+ EM.run do
10
+ @conn = EM::Mongo::Connection.new
11
+ EM.next_tick do
12
+ id = @conn.db.collection('test').insert({:hello => "world"})
13
+ @conn.db.collection('test').first(:_id => id) do |document|
14
+ $return = 0 if document
15
+ EM.stop
16
+ end
17
+ end
18
+ end
19
+ exit($return)
@@ -642,16 +642,26 @@ describe EMMongo::Collection do
642
642
  end
643
643
  end
644
644
 
645
- it "should create a geospatial index" do
646
- @conn, @geo = connection_and_collection('geo')
645
+ it "should create a flat 2d index" do
646
+ @conn, @geo = connection_and_collection('2d')
647
647
  @geo.save({'loc' => [-100, 100]})
648
- @geo.create_index([['loc', EM::Mongo::GEO2D]])
648
+ @geo.create_index([['loc', EM::Mongo::FLAT2D]])
649
649
  @geo.index_information.callback do |info|
650
650
  info['loc_2d'].should_not be_nil
651
651
  done
652
652
  end
653
653
  end
654
654
 
655
+ it "should create a sphere 2d index" do
656
+ @conn, @geo = connection_and_collection('2dsphere')
657
+ @geo.save({'loc' => [-100, 100]})
658
+ @geo.create_index([['loc', EM::Mongo::SPHERE2D]])
659
+ @geo.index_information.callback do |info|
660
+ info['loc_2dsphere'].should_not be_nil
661
+ done
662
+ end
663
+ end
664
+
655
665
  it "should create a unique index" do
656
666
  @conn, @collection = connection_and_collection('test-collection')
657
667
  @collection.create_index([['a', EM::Mongo::ASCENDING]], :unique => true)
@@ -0,0 +1,37 @@
1
+ require "rubygems"
2
+ require "bundler"
3
+ Bundler.setup(:default, :development)
4
+ require "eventmachine"
5
+ begin
6
+ require "bson_ext"
7
+ rescue LoadError
8
+ require "bson"
9
+ end
10
+
11
+ require File.expand_path('../lib/em-mongo', File.dirname(__FILE__))
12
+
13
+ require "em-spec/rspec"
14
+
15
+ def connection_and_collection(collection_name=EM::Mongo::DEFAULT_NS)
16
+ conn = EMMongo::Connection.new
17
+ return conn, collection(conn, collection_name)
18
+ end
19
+
20
+ def collection(conn, name)
21
+ conn.db.collection(name).remove
22
+ conn.db.collection(name)
23
+ end
24
+
25
+ def number_hash
26
+ @numbers = {
27
+ 1 => 'one',
28
+ 2 => 'two',
29
+ 3 => 'three',
30
+ 4 => 'four',
31
+ 5 => 'five',
32
+ 6 => 'six',
33
+ 7 => 'seven',
34
+ 8 => 'eight',
35
+ 9 => 'nine'
36
+ }
37
+ end
@@ -0,0 +1,21 @@
1
+ require File.expand_path('spec_helper', File.dirname(__FILE__) + '/../')
2
+
3
+ # This is to prove how BSON works so we can code around it where appropriate
4
+ # BSON documents and Ruby Hashes are not the same thing afterall.
5
+ #
6
+ # http://www.mongodb.org/display/DOCS/BSON
7
+
8
+ describe BSON do
9
+
10
+ it 'should do what it does' do
11
+ doc = {:_id => 12345, :foo => 'notbar', "foo" => "bar", :hello => :world }
12
+ doc = BSON::BSON_CODER.deserialize(BSON::BSON_CODER.serialize(doc, false, true).to_s)
13
+ # 1. An ID passed as Symbol is really a String
14
+ doc['_id'].should == 12345
15
+ # 2. More to the point, all keys are Strings.
16
+ doc['hello'].should == :world
17
+ # 3. The last String/Symbol wins
18
+ doc['foo'].should == 'bar'
19
+ end
20
+
21
+ end
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-mongo
3
3
  version: !ruby/object:Gem::Version
4
- version: !binary |-
5
- MC40LjM=
4
+ version: 0.5.0
6
5
  prerelease:
7
6
  platform: ruby
8
7
  authors:
@@ -49,9 +48,19 @@ description: EventMachine driver for MongoDB.
49
48
  email: brenden.grace@gmail.com
50
49
  executables: []
51
50
  extensions: []
52
- extra_rdoc_files: []
51
+ extra_rdoc_files:
52
+ - README.rdoc
53
53
  files:
54
+ - .gitignore
55
+ - CHANGELOG
56
+ - Gemfile
57
+ - README.rdoc
58
+ - Rakefile
54
59
  - VERSION
60
+ - em-mongo.gemspec
61
+ - examples/legacy.rb
62
+ - examples/readme.rb
63
+ - lib/em-mongo.rb
55
64
  - lib/em-mongo/collection.rb
56
65
  - lib/em-mongo/connection.rb
57
66
  - lib/em-mongo/conversions.rb
@@ -63,13 +72,17 @@ files:
63
72
  - lib/em-mongo/request_response.rb
64
73
  - lib/em-mongo/server_response.rb
65
74
  - lib/em-mongo/support.rb
66
- - lib/em-mongo.rb
75
+ - spec/gem/Gemfile
76
+ - spec/gem/bundler.rb
77
+ - spec/gem/rubygems.rb
67
78
  - spec/integration/collection_spec.rb
68
79
  - spec/integration/connection_spec.rb
69
80
  - spec/integration/cursor_spec.rb
70
81
  - spec/integration/database_spec.rb
71
82
  - spec/integration/request_response_spec.rb
72
- homepage: http://github.com/bcg/em-mongo
83
+ - spec/spec_helper.rb
84
+ - spec/unit/bson_spec.rb
85
+ homepage: https://github.com/bcg/em-mongo
73
86
  licenses: []
74
87
  post_install_message:
75
88
  rdoc_options:
@@ -94,9 +107,4 @@ rubygems_version: 1.8.23
94
107
  signing_key:
95
108
  specification_version: 3
96
109
  summary: An EventMachine driver for MongoDB.
97
- test_files:
98
- - spec/integration/collection_spec.rb
99
- - spec/integration/connection_spec.rb
100
- - spec/integration/cursor_spec.rb
101
- - spec/integration/database_spec.rb
102
- - spec/integration/request_response_spec.rb
110
+ test_files: []