mongo 1.0.9 → 1.1

Sign up to get free protection for your applications and to get access to all the features.
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