mongo 1.0.9 → 1.1

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.
data/HISTORY CHANGED
@@ -1,3 +1,11 @@
1
+ 1.1 2010-10-4
2
+ * Official JRuby support via Java extensons for BSON (beta)
3
+ * Connection#lock! and Connection#unlock! for easy fsync lock
4
+ * Note: BSON::Code is no longer a subclass of String.
5
+
6
+ 1.0.9 2010-9-20
7
+ * Significant performance improvements
8
+
1
9
  1.0.8 2010-8-27
2
10
 
3
11
  * Cursor#rewind! and more consistent Cursor Enumberable behavior
data/Rakefile CHANGED
@@ -13,6 +13,29 @@ require 'rbconfig'
13
13
  include Config
14
14
  ENV['TEST_MODE'] = 'TRUE'
15
15
 
16
+ task :java do
17
+ Rake::Task['build:java'].invoke
18
+ Rake::Task['test:ruby'].invoke
19
+ end
20
+
21
+ namespace :build do
22
+ desc "Build the java extensions."
23
+ task :java do
24
+ puts "Building Java extensions..."
25
+ java_dir = File.join(File.dirname(__FILE__), 'ext', 'java')
26
+ jar_dir = File.join(java_dir, 'jar')
27
+
28
+ jruby_jar = File.join(jar_dir, 'jruby.jar')
29
+ mongo_jar = File.join(jar_dir, 'mongo.jar')
30
+ bson_jar = File.join(jar_dir, 'bson.jar')
31
+
32
+ src_base = File.join(java_dir, 'src')
33
+
34
+ system("javac -Xlint:unchecked -classpath #{jruby_jar}:#{mongo_jar}:#{bson_jar} #{File.join(src_base, 'org', 'jbson', '*.java')}")
35
+ system("cd #{src_base} && jar cf #{File.join(jar_dir, 'jbson.jar')} #{File.join('.', 'org', 'jbson', '*.class')}")
36
+ end
37
+ end
38
+
16
39
  desc "Test the MongoDB Ruby driver."
17
40
  task :test do
18
41
  puts "\nThis option has changed."
@@ -3,7 +3,7 @@
3
3
  $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
4
 
5
5
  module Mongo
6
- VERSION = "1.0.9"
6
+ VERSION = "1.1"
7
7
  end
8
8
 
9
9
  module Mongo
@@ -168,35 +168,6 @@ module Mongo
168
168
  end
169
169
  end
170
170
 
171
- # @deprecated
172
- #
173
- # Initialize a paired connection to MongoDB.
174
- #
175
- # @param nodes [Array] An array of arrays, each of which specified a host and port.
176
- # @param opts Takes the same options as Connection.new
177
- #
178
- # @example
179
- # Connection.paired([["db1.example.com", 27017],
180
- # ["db2.example.com", 27017]])
181
- #
182
- # @example
183
- # Connection.paired([["db1.example.com", 27017],
184
- # ["db2.example.com", 27017]],
185
- # :pool_size => 20, :timeout => 5)
186
- #
187
- # @return [Mongo::Connection]
188
- def self.paired(nodes, opts={})
189
- warn "Connection.paired is deprecated. Please use Connection.multi instead."
190
- unless nodes.length == 2 && nodes.all? {|n| n.is_a? Array}
191
- raise MongoArgumentError, "Connection.paired requires that exactly two nodes be specified."
192
- end
193
- # Block returns an array, the first element being an array of nodes and the second an array
194
- # of authorizations for the database.
195
- new(nil, nil, opts) do |con|
196
- [con.pair_val_to_connection(nodes[0]), con.pair_val_to_connection(nodes[1])]
197
- end
198
- end
199
-
200
171
  # Initialize a connection to MongoDB using the MongoDB URI spec:
201
172
  #
202
173
  # @param uri [String]
@@ -211,6 +182,31 @@ module Mongo
211
182
  end
212
183
  end
213
184
 
185
+ # Fsync, then lock the mongod process against writes. Use this to get
186
+ # the datafiles in a state safe for snapshotting, backing up, etc.
187
+ #
188
+ # @return [BSON::OrderedHash] the command response
189
+ def lock!
190
+ cmd = BSON::OrderedHash.new
191
+ cmd[:fsync] = 1
192
+ cmd[:lock] = true
193
+ self['admin'].command(cmd)
194
+ end
195
+
196
+ # Is this database locked against writes?
197
+ #
198
+ # @return [Boolean]
199
+ def locked?
200
+ self['admin']['$cmd.sys.inprog'].find_one['fsyncLock'] == 1
201
+ end
202
+
203
+ # Unlock a previously fsync-locked mongod process.
204
+ #
205
+ # @return [BSON::OrderedHash] command response
206
+ def unlock!
207
+ self['admin']['$cmd.sys.unlock'].find_one
208
+ end
209
+
214
210
  # Apply each of the saved database authentications.
215
211
  #
216
212
  # @return [Boolean] returns true if authentications exist and succeeed, false
@@ -483,15 +479,6 @@ module Mongo
483
479
  raise ConnectionFailure, "failed to connect to any given host:port" unless connected?
484
480
  end
485
481
 
486
- # @deprecated
487
- #
488
- # Create a new socket and attempt to connect to master.
489
- # If successful, sets host and port to master and returns the socket.
490
- def connect_to_master
491
- warn "Connection#connect_to_master is deprecated. Use Connection#connect instead."
492
- connect
493
- end
494
-
495
482
  def connected?
496
483
  @host && @port
497
484
  end
@@ -39,7 +39,7 @@ module Mongo
39
39
  @connection = @db.connection
40
40
  @logger = @connection.logger
41
41
 
42
- @selector = convert_selector_for_query(options[:selector])
42
+ @selector = options[:selector] || {}
43
43
  @fields = convert_fields_for_query(options[:fields])
44
44
  @skip = options[:skip] || 0
45
45
  @limit = options[:limit] || 0
@@ -327,26 +327,6 @@ module Mongo
327
327
  end
328
328
  end
329
329
 
330
- # Set the query selector hash. If the selector is a Code or String object,
331
- # the selector will be used in a $where clause.
332
- # See http://www.mongodb.org/display/DOCS/Server-side+Code+Execution
333
- def convert_selector_for_query(selector)
334
- case selector
335
- when Hash
336
- selector
337
- when nil
338
- {}
339
- when BSON::Code
340
- warn "Collection#find will no longer take a JavaScript string in future versions. " +
341
- "Please specify your $where query explicitly."
342
- {"$where" => selector}
343
- when String
344
- warn "Collection#find will no longer take a JavaScript string in future versions. " +
345
- "Please specify your $where query explicitly."
346
- {"$where" => BSON::Code.new(selector)}
347
- end
348
- end
349
-
350
330
  # Return the number of documents remaining for this cursor.
351
331
  def num_remaining
352
332
  refresh if @cache.length == 0
@@ -276,23 +276,6 @@ module Mongo
276
276
  ok?(command(:drop => name))
277
277
  end
278
278
 
279
- # @deprecated
280
- #
281
- # Get the error message from the most recently executed database
282
- # operation for this connection.
283
- #
284
- # @option opts [Boolean] :fsync (false)
285
- # @option opts [Integer] :w (nil)
286
- # @option opts [Integer] :wtimeout (nil)
287
- #
288
- # @return [String, Nil] either the text describing an error or nil if no
289
- # error has occurred.
290
- def error(opts={})
291
- warn "DB#error is deprecated. Please use DB#get_last_error instead"
292
- opts.assert_valid_keys(:w, :wtimeout, :fsync)
293
- get_last_error(opts)['err']
294
- end
295
-
296
279
  # Run the getlasterror command with the specified replication options.
297
280
  #
298
281
  # @option opts [Boolean] :fsync (false)
@@ -311,16 +294,6 @@ module Mongo
311
294
  doc
312
295
  end
313
296
 
314
- # @deprecated
315
- #
316
- # Get status information from the last operation on this connection.
317
- #
318
- # @return [Hash] a hash representing the status of the last db op.
319
- def last_status
320
- warn "DB#last_status is deprecated. Please use the equivalent DB#get_last_error instead"
321
- command(:getlasterror => 1)
322
- end
323
-
324
297
  # Return +true+ if an error was caused by the most recently executed
325
298
  # database operation.
326
299
  #
@@ -0,0 +1,99 @@
1
+ # encoding:utf-8
2
+ require './test/test_helper'
3
+ require 'complex'
4
+ require 'bigdecimal'
5
+ require 'rational'
6
+ require 'benchmark'
7
+
8
+ MEDIUM = {
9
+ 'integer' => 5,
10
+ 'number' => 5.05,
11
+ 'boolean' => false,
12
+ 'array' => ['test', 'benchmark']
13
+ }
14
+
15
+
16
+ LARGE = {
17
+ 'base_url' => 'http://www.example.com/test-me',
18
+ 'total_word_count' => 6743,
19
+ 'access_time' => Time.now,
20
+ 'meta_tags' => {
21
+ 'description' => 'i am a long description string',
22
+ 'author' => 'Holly Man',
23
+ 'dynamically_created_meta_tag' => 'who know\n what'
24
+ },
25
+ 'page_structure' => {
26
+ 'counted_tags' => 3450,
27
+ 'no_of_js_attached' => 10,
28
+ 'no_of_images' => 6
29
+ },
30
+ 'harvested_words' => ['10gen','web','open','source','application','paas',
31
+ 'platform-as-a-service','technology','helps',
32
+ 'developers','focus','building','mongodb','mongo'] * 20
33
+ }
34
+
35
+
36
+
37
+ begin
38
+ require 'active_support/core_ext'
39
+ require 'active_support/hash_with_indifferent_access'
40
+ Time.zone = "Pacific Time (US & Canada)"
41
+ Zone = Time.zone.now
42
+ rescue LoadError
43
+ warn 'Could not test BSON with HashWithIndifferentAccess.'
44
+ module ActiveSupport
45
+ class TimeWithZone
46
+ end
47
+ end
48
+ Zone = ActiveSupport::TimeWithZone.new
49
+ end
50
+
51
+ class BSONTest < Test::Unit::TestCase
52
+ include BSON
53
+
54
+ def test_string
55
+ doc = {'doc' => 'hello, world'}
56
+ bson = bson = BSON::BSON_CODER.serialize(doc)
57
+ assert_equal doc, BSON::BSON_CODER.deserialize(bson)
58
+ end
59
+
60
+ def test_object
61
+ doc = {'doc' => {'age' => 42, 'name' => 'Spongebob', 'shoe_size' => 9.5}}
62
+ bson = BSON::BSON_CODER.serialize(doc)
63
+ assert_equal doc, BSON::BSON_CODER.deserialize(bson)
64
+ end
65
+
66
+ def test_oid
67
+ doc = {'doc' => ObjectID.new}
68
+ bson = BSON::BSON_CODER.serialize(doc)
69
+ assert_equal doc, BSON::BSON_CODER.deserialize(bson)
70
+ end
71
+
72
+ def test_array
73
+ doc = {'doc' => [1, 2, "a", "b"]}
74
+ bson = BSON::BSON_CODER.serialize(doc)
75
+ assert_equal doc, BSON::BSON_CODER.deserialize(bson)
76
+ end
77
+
78
+ def test_speed
79
+
80
+ Benchmark.bm do |x|
81
+ x.report('serialize obj') do
82
+ 1000.times do
83
+ BSON::BSON_CODER.serialize(LARGE)
84
+ end
85
+ end
86
+ end
87
+
88
+
89
+
90
+ Benchmark.bm do |x|
91
+ b = BSON::BSON_CODER.serialize(LARGE)
92
+ x.report('deserialize obj') do
93
+ 1000.times do
94
+ BSON::BSON_CODER.deserialize(b)
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,172 @@
1
+ # encoding:utf-8
2
+ require './test/test_helper'
3
+ require 'complex'
4
+ require 'bigdecimal'
5
+ require 'rational'
6
+ require 'benchmark'
7
+
8
+ MEDIUM = {
9
+ 'integer' => 5,
10
+ 'number' => 5.05,
11
+ 'boolean' => false,
12
+ 'array' => ['test', 'benchmark']
13
+ }
14
+
15
+
16
+ LARGE = {
17
+ 'base_url' => 'http://www.example.com/test-me',
18
+ 'total_word_count' => 6743,
19
+ 'access_time' => 1,# Time.now,
20
+ 'meta_tags' => {
21
+ 'description' => 'i am a long description string',
22
+ 'author' => 'Holly Man',
23
+ 'dynamically_created_meta_tag' => 'who know\n what'
24
+ },
25
+ 'page_structure' => {
26
+ 'counted_tags' => 3450,
27
+ 'no_of_js_attached' => 10,
28
+ 'no_of_images' => 6
29
+ },
30
+ 'harvested_words' => ['10gen','web','open','source','application','paas',
31
+ 'platform-as-a-service','technology','helps',
32
+ 'developers','focus','building','mongodb','mongo'] * 20
33
+ }
34
+
35
+
36
+
37
+ begin
38
+ require 'active_support/core_ext'
39
+ require 'active_support/hash_with_indifferent_access'
40
+ Time.zone = "Pacific Time (US & Canada)"
41
+ Zone = Time.zone.now
42
+ rescue LoadError
43
+ warn 'Could not test BSON with HashWithIndifferentAccess.'
44
+ module ActiveSupport
45
+ class TimeWithZone
46
+ end
47
+ end
48
+ Zone = ActiveSupport::TimeWithZone.new
49
+ end
50
+
51
+ class BSONTest < Test::Unit::TestCase
52
+ include BSON
53
+
54
+ def setup
55
+ @encoder = BSON::BSON_RUBY
56
+ @decoder = BSON::BSON_RUBY
57
+ @con = Mongo::Connection.new
58
+ end
59
+
60
+ def assert_doc_pass(doc, options={})
61
+ bson = @encoder.serialize(doc)
62
+ if options[:debug]
63
+ puts "DEBUGGIN DOC:"
64
+ p bson.to_a
65
+ puts "DESERIALIZES TO:"
66
+ p @decoder.deserialize(bson)
67
+ end
68
+ assert_equal @decoder.serialize(doc).to_a, bson.to_a
69
+ assert_equal doc, @decoder.deserialize(bson)
70
+ end
71
+
72
+ # def test_bench_big_string
73
+ # t0 = Time.now
74
+ # @con['foo']['bar'].remove
75
+ # doc = {'doc' => 'f' * 2_000_000}
76
+ # 10.times do
77
+ # @con['foo']['bar'].save({'d' => doc})
78
+ # @con['foo']['bar'].find.to_a
79
+ # end
80
+ # puts "Big String"
81
+ # puts Time.now - t0
82
+ # end
83
+ #
84
+ # def test_big_array
85
+ # t0 = Time.now
86
+ # @con['foo']['bar'].remove
87
+ # doc = {'doc' => 'f' * 2_000_000}
88
+ # 10.times do
89
+ # @con['foo']['bar'].save({'d' => doc})
90
+ # @con['foo']['bar'].find.to_a
91
+ # end
92
+ # puts "Big String"
93
+ # puts Time.now - t0
94
+ # end
95
+ #
96
+ # def test_string
97
+ # doc = {'doc' => "Hello world!", 'awesome' => true, 'a' => 1, 'b' => 4_333_433_232, 'c' => 2.33, 'd' => nil,
98
+ # 'f' => BSON::Code.new("function"), 'g' => BSON::ObjectId.new, 'h' => [1, 2, 3]}
99
+ # bson = @encoder.serialize(doc)
100
+ # d = @encoder.deserialize(bson)
101
+ # puts "Array"
102
+ # puts d
103
+ # puts d['h']
104
+ # puts "End Array"
105
+ # puts d['h'][0]
106
+ # puts d['h'][1]
107
+ # puts (d['h'][2] + 100).class
108
+ # puts "ObjecId Info"
109
+ # bson2 = @encoder.serialize(d)
110
+ # doc2 = @encoder.deserialize(bson2)
111
+ # assert_equal doc2, @encoder.deserialize(bson)
112
+ # end
113
+ #
114
+
115
+ def test_eval
116
+ code = BSON::Code.new('f')
117
+ oh = BSON::OrderedHash.new
118
+ oh[:$eval] = code
119
+ oh[:args] = [1]
120
+
121
+ assert_equal BSON::BSON_RUBY.serialize(oh).to_a, BSON::BSON_JAVA.serialize(oh).to_a
122
+ assert_equal 3, @con['admin'].eval('function (x) {return x;}', 3)
123
+ end
124
+
125
+ # def test_oid
126
+ # b = Java::OrgBsonTypes::ObjectId.new.toByteArray
127
+ # o = ObjectId.new(b)
128
+ # p o
129
+ # end
130
+ #
131
+ def test_speed
132
+ @con['foo']['bar'].remove
133
+
134
+ puts "Test OID"
135
+ t0 = Time.now
136
+ 5000.times do
137
+ ids = [BSON::ObjectId.new] * 1000
138
+ @encoder.serialize({'doc' => BSON::ObjectId.new})
139
+ end
140
+ puts Time.now - t0
141
+
142
+ puts "Decode OID"
143
+ ids = [BSON::ObjectId.new] * 1000
144
+ doc = {'doc' => ids}
145
+ bson = @encoder.serialize(doc)
146
+ t0 = Time.now
147
+ 50.times do
148
+ @encoder.deserialize(bson)
149
+ end
150
+ puts Time.now - t0
151
+
152
+
153
+ puts "Test insert"
154
+ t0 = Time.now
155
+ 1000.times do |n|
156
+ if n % 1000 == 0
157
+ puts Time.now - t0
158
+ t0 = Time.now
159
+ end
160
+ @con['foo']['bar'].insert({'doc' => MEDIUM})
161
+ end
162
+ puts Time.now - t0
163
+
164
+ puts "Test query / deserialize"
165
+ t0 = Time.now
166
+ @con['foo']['bar'].find.to_a
167
+ t1 = Time.now
168
+ puts t1 - t0
169
+ end
170
+
171
+
172
+ end