mongo 0.1.0 → 0.15

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. data/README.rdoc +268 -71
  2. data/Rakefile +27 -62
  3. data/bin/bson_benchmark.rb +59 -0
  4. data/bin/mongo_console +3 -3
  5. data/bin/run_test_script +19 -0
  6. data/bin/standard_benchmark +109 -0
  7. data/examples/admin.rb +41 -0
  8. data/examples/benchmarks.rb +42 -0
  9. data/examples/blog.rb +76 -0
  10. data/examples/capped.rb +23 -0
  11. data/examples/cursor.rb +47 -0
  12. data/examples/gridfs.rb +87 -0
  13. data/examples/index_test.rb +125 -0
  14. data/examples/info.rb +30 -0
  15. data/examples/queries.rb +69 -0
  16. data/examples/simple.rb +23 -0
  17. data/examples/strict.rb +34 -0
  18. data/examples/types.rb +35 -0
  19. data/lib/mongo.rb +9 -2
  20. data/lib/mongo/admin.rb +65 -68
  21. data/lib/mongo/collection.rb +379 -117
  22. data/lib/mongo/connection.rb +151 -0
  23. data/lib/mongo/cursor.rb +271 -216
  24. data/lib/mongo/db.rb +500 -315
  25. data/lib/mongo/errors.rb +26 -0
  26. data/lib/mongo/gridfs.rb +16 -0
  27. data/lib/mongo/gridfs/chunk.rb +92 -0
  28. data/lib/mongo/gridfs/grid_store.rb +464 -0
  29. data/lib/mongo/message.rb +16 -0
  30. data/lib/mongo/message/get_more_message.rb +24 -13
  31. data/lib/mongo/message/insert_message.rb +29 -11
  32. data/lib/mongo/message/kill_cursors_message.rb +23 -12
  33. data/lib/mongo/message/message.rb +74 -62
  34. data/lib/mongo/message/message_header.rb +35 -24
  35. data/lib/mongo/message/msg_message.rb +21 -9
  36. data/lib/mongo/message/opcodes.rb +26 -15
  37. data/lib/mongo/message/query_message.rb +63 -43
  38. data/lib/mongo/message/remove_message.rb +29 -12
  39. data/lib/mongo/message/update_message.rb +30 -13
  40. data/lib/mongo/query.rb +97 -89
  41. data/lib/mongo/types/binary.rb +25 -21
  42. data/lib/mongo/types/code.rb +30 -0
  43. data/lib/mongo/types/dbref.rb +19 -23
  44. data/lib/mongo/types/objectid.rb +130 -116
  45. data/lib/mongo/types/regexp_of_holding.rb +27 -31
  46. data/lib/mongo/util/bson.rb +273 -160
  47. data/lib/mongo/util/byte_buffer.rb +32 -28
  48. data/lib/mongo/util/ordered_hash.rb +88 -42
  49. data/lib/mongo/util/xml_to_ruby.rb +18 -15
  50. data/mongo-ruby-driver.gemspec +103 -0
  51. data/test/mongo-qa/_common.rb +8 -0
  52. data/test/mongo-qa/admin +26 -0
  53. data/test/mongo-qa/capped +22 -0
  54. data/test/mongo-qa/count1 +18 -0
  55. data/test/mongo-qa/dbs +22 -0
  56. data/test/mongo-qa/find +10 -0
  57. data/test/mongo-qa/find1 +15 -0
  58. data/test/mongo-qa/gridfs_in +16 -0
  59. data/test/mongo-qa/gridfs_out +17 -0
  60. data/test/mongo-qa/indices +49 -0
  61. data/test/mongo-qa/remove +25 -0
  62. data/test/mongo-qa/stress1 +35 -0
  63. data/test/mongo-qa/test1 +11 -0
  64. data/test/mongo-qa/update +18 -0
  65. data/{tests → test}/test_admin.rb +25 -16
  66. data/test/test_bson.rb +268 -0
  67. data/{tests → test}/test_byte_buffer.rb +0 -0
  68. data/test/test_chunk.rb +84 -0
  69. data/test/test_collection.rb +282 -0
  70. data/test/test_connection.rb +101 -0
  71. data/test/test_cursor.rb +321 -0
  72. data/test/test_db.rb +196 -0
  73. data/test/test_db_api.rb +798 -0
  74. data/{tests → test}/test_db_connection.rb +4 -3
  75. data/test/test_grid_store.rb +284 -0
  76. data/{tests → test}/test_message.rb +1 -1
  77. data/test/test_objectid.rb +105 -0
  78. data/{tests → test}/test_ordered_hash.rb +55 -0
  79. data/{tests → test}/test_round_trip.rb +13 -9
  80. data/test/test_threading.rb +37 -0
  81. metadata +74 -32
  82. data/bin/validate +0 -51
  83. data/lib/mongo/mongo.rb +0 -74
  84. data/lib/mongo/types/undefined.rb +0 -31
  85. data/tests/test_bson.rb +0 -135
  86. data/tests/test_cursor.rb +0 -66
  87. data/tests/test_db.rb +0 -51
  88. data/tests/test_db_api.rb +0 -349
  89. data/tests/test_objectid.rb +0 -88
@@ -5,13 +5,14 @@ require 'test/unit'
5
5
  # NOTE: assumes Mongo is running
6
6
  class DBConnectionTest < Test::Unit::TestCase
7
7
 
8
- include XGen::Mongo::Driver
8
+ include Mongo
9
9
 
10
10
  def test_no_exceptions
11
11
  host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
12
- port = ENV['MONGO_RUBY_DRIVER_PORT'] || Mongo::DEFAULT_PORT
13
- db = Mongo.new(host, port).db('ruby-mongo-demo')
12
+ port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
13
+ db = Connection.new(host, port).db('ruby-mongo-demo')
14
14
  coll = db.collection('test')
15
15
  coll.clear
16
+ db.error
16
17
  end
17
18
  end
@@ -0,0 +1,284 @@
1
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'test/unit'
3
+ require 'mongo'
4
+ require 'mongo/gridfs'
5
+
6
+ class GridStoreTest < Test::Unit::TestCase
7
+
8
+ include Mongo
9
+ include GridFS
10
+
11
+ @@db = Connection.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
12
+ ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT).db('ruby-mongo-test')
13
+ @@files = @@db.collection('fs.files')
14
+ @@chunks = @@db.collection('fs.chunks')
15
+
16
+ def setup
17
+ @@chunks.clear
18
+ @@files.clear
19
+ GridStore.open(@@db, 'foobar', 'w') { |f| f.write("hello, world!") }
20
+ end
21
+
22
+ def teardown
23
+ @@chunks.clear
24
+ @@files.clear
25
+ @@db.error
26
+ end
27
+
28
+ def test_exist
29
+ assert GridStore.exist?(@@db, 'foobar')
30
+ assert !GridStore.exist?(@@db, 'does_not_exist')
31
+ assert !GridStore.exist?(@@db, 'foobar', 'another_root')
32
+ end
33
+
34
+ def test_list
35
+ assert_equal ['foobar'], GridStore.list(@@db)
36
+ assert_equal ['foobar'], GridStore.list(@@db, 'fs')
37
+ assert_equal [], GridStore.list(@@db, 'my_fs')
38
+
39
+ GridStore.open(@@db, 'test', 'w') { |f| f.write("my file") }
40
+
41
+ assert_equal ['foobar', 'test'], GridStore.list(@@db)
42
+ end
43
+
44
+ def test_small_write
45
+ rows = @@files.find({'filename' => 'foobar'}).to_a
46
+ assert_not_nil rows
47
+ assert_equal 1, rows.length
48
+ row = rows[0]
49
+ assert_not_nil row
50
+
51
+ file_id = row['_id']
52
+ assert_kind_of ObjectID, file_id
53
+ rows = @@chunks.find({'files_id' => file_id}).to_a
54
+ assert_not_nil rows
55
+ assert_equal 1, rows.length
56
+ end
57
+
58
+ def test_small_file
59
+ rows = @@files.find({'filename' => 'foobar'}).to_a
60
+ assert_not_nil rows
61
+ assert_equal 1, rows.length
62
+ row = rows[0]
63
+ assert_not_nil row
64
+ assert_equal "hello, world!", GridStore.read(@@db, 'foobar')
65
+ end
66
+
67
+ def test_overwrite
68
+ GridStore.open(@@db, 'foobar', 'w') { |f| f.write("overwrite") }
69
+ assert_equal "overwrite", GridStore.read(@@db, 'foobar')
70
+ end
71
+
72
+ def test_read_length
73
+ assert_equal "hello", GridStore.read(@@db, 'foobar', 5)
74
+ end
75
+
76
+ # Also tests seek
77
+ def test_read_with_offset
78
+ assert_equal "world", GridStore.read(@@db, 'foobar', 5, 7)
79
+ assert_equal "world!", GridStore.read(@@db, 'foobar', nil, 7)
80
+ end
81
+
82
+ def test_seek
83
+ GridStore.open(@@db, 'foobar', 'r') { |f|
84
+ f.seek(0)
85
+ assert_equal 'h', f.getc.chr
86
+ f.seek(7)
87
+ assert_equal 'w', f.getc.chr
88
+ f.seek(4)
89
+ assert_equal 'o', f.getc.chr
90
+
91
+ f.seek(-1, IO::SEEK_END)
92
+ assert_equal '!', f.getc.chr
93
+ f.seek(-6, IO::SEEK_END)
94
+ assert_equal 'w', f.getc.chr
95
+
96
+ f.seek(0)
97
+ f.seek(7, IO::SEEK_CUR)
98
+ assert_equal 'w', f.getc.chr
99
+ f.seek(-1, IO::SEEK_CUR)
100
+ assert_equal 'w', f.getc.chr
101
+ f.seek(-4, IO::SEEK_CUR)
102
+ assert_equal 'o', f.getc.chr
103
+ f.seek(3, IO::SEEK_CUR)
104
+ assert_equal 'o', f.getc.chr
105
+ }
106
+ end
107
+
108
+ def test_multi_chunk
109
+ @@chunks.clear
110
+ @@files.clear
111
+
112
+ size = 512
113
+ GridStore.open(@@db, 'biggie', 'w') { |f|
114
+ f.chunk_size = size
115
+ f.write('x' * size)
116
+ f.write('y' * size)
117
+ f.write('z' * size)
118
+ }
119
+
120
+ assert_equal 3, @@chunks.count
121
+ assert_equal ('x' * size) + ('y' * size) + ('z' * size), GridStore.read(@@db, 'biggie')
122
+ end
123
+
124
+ def test_puts_and_readlines
125
+ GridStore.open(@@db, 'multiline', 'w') { |f|
126
+ f.puts "line one"
127
+ f.puts "line two\n"
128
+ f.puts "line three"
129
+ }
130
+
131
+ lines = GridStore.readlines(@@db, 'multiline')
132
+ assert_equal ["line one\n", "line two\n", "line three\n"], lines
133
+ end
134
+
135
+ def test_unlink
136
+ assert_equal 1, @@files.count
137
+ assert_equal 1, @@chunks.count
138
+ GridStore.unlink(@@db, 'foobar')
139
+ assert_equal 0, @@files.count
140
+ assert_equal 0, @@chunks.count
141
+ end
142
+
143
+ def test_append
144
+ GridStore.open(@@db, 'foobar', 'w+') { |f| f.write(" how are you?") }
145
+ assert_equal 1, @@chunks.count
146
+ assert_equal "hello, world! how are you?", GridStore.read(@@db, 'foobar')
147
+ end
148
+
149
+ def test_rewind_and_truncate_on_write
150
+ GridStore.open(@@db, 'foobar', 'w') { |f|
151
+ f.write("some text is inserted here")
152
+ f.rewind
153
+ f.write("abc")
154
+ }
155
+ assert_equal "abc", GridStore.read(@@db, 'foobar')
156
+ end
157
+
158
+ def test_tell
159
+ GridStore.open(@@db, 'foobar', 'r') { |f|
160
+ f.read(5)
161
+ assert_equal 5, f.tell
162
+ }
163
+ end
164
+
165
+ def test_empty_block_ok
166
+ GridStore.open(@@db, 'empty', 'w')
167
+ end
168
+
169
+ def test_save_empty_file
170
+ @@chunks.clear
171
+ @@files.clear
172
+ GridStore.open(@@db, 'empty', 'w') {} # re-write with zero bytes
173
+ assert_equal 1, @@files.count
174
+ assert_equal 0, @@chunks.count
175
+ end
176
+
177
+ def test_empty_file_eof
178
+ GridStore.open(@@db, 'empty', 'w')
179
+ GridStore.open(@@db, 'empty', 'r') { |f|
180
+ assert f.eof?
181
+ }
182
+ end
183
+
184
+ def test_cannot_change_chunk_size_on_read
185
+ begin
186
+ GridStore.open(@@db, 'foobar', 'r') { |f| f.chunk_size = 42 }
187
+ fail "should have seen error"
188
+ rescue => ex
189
+ assert_match /error: can only change chunk size/, ex.to_s
190
+ end
191
+ end
192
+
193
+ def test_cannot_change_chunk_size_after_data_written
194
+ begin
195
+ GridStore.open(@@db, 'foobar', 'w') { |f|
196
+ f.write("some text")
197
+ f.chunk_size = 42
198
+ }
199
+ fail "should have seen error"
200
+ rescue => ex
201
+ assert_match /error: can only change chunk size/, ex.to_s
202
+ end
203
+ end
204
+
205
+ def test_change_chunk_size
206
+ GridStore.open(@@db, 'new-file', 'w') { |f|
207
+ f.chunk_size = 42
208
+ f.write("foo")
209
+ }
210
+ GridStore.open(@@db, 'new-file', 'r') { |f|
211
+ assert f.chunk_size == 42
212
+ }
213
+ end
214
+
215
+ def test_chunk_size_in_option
216
+ GridStore.open(@@db, 'new-file', 'w', :chunk_size => 42) { |f| f.write("foo") }
217
+ GridStore.open(@@db, 'new-file', 'r') { |f|
218
+ assert f.chunk_size == 42
219
+ }
220
+ end
221
+
222
+ def test_md5
223
+ GridStore.open(@@db, 'new-file', 'w') { |f| f.write("hello world\n")}
224
+ GridStore.open(@@db, 'new-file', 'r') { |f|
225
+ assert f.md5 == '6f5902ac237024bdd0c176cb93063dc4'
226
+ begin
227
+ f.md5 = 'cant do this'
228
+ fail "should have seen error"
229
+ rescue => ex
230
+ true
231
+ end
232
+ }
233
+ GridStore.open(@@db, 'new-file', 'w') {}
234
+ GridStore.open(@@db, 'new-file', 'r') { |f|
235
+ assert f.md5 == 'd41d8cd98f00b204e9800998ecf8427e'
236
+ }
237
+ end
238
+
239
+ def test_upload_date
240
+ now = Time.now
241
+ orig_file_upload_date = nil
242
+ GridStore.open(@@db, 'foobar', 'r') { |f| orig_file_upload_date = f.upload_date }
243
+ assert_not_nil orig_file_upload_date
244
+ assert (orig_file_upload_date - now) < 5 # even a really slow system < 5 secs
245
+
246
+ sleep(2)
247
+ GridStore.open(@@db, 'foobar', 'w') { |f| f.write "new data" }
248
+ file_upload_date = nil
249
+ GridStore.open(@@db, 'foobar', 'r') { |f| file_upload_date = f.upload_date }
250
+ assert_equal orig_file_upload_date, file_upload_date
251
+ end
252
+
253
+ def test_content_type
254
+ ct = nil
255
+ GridStore.open(@@db, 'foobar', 'r') { |f| ct = f.content_type }
256
+ assert_equal GridStore::DEFAULT_CONTENT_TYPE, ct
257
+
258
+ GridStore.open(@@db, 'foobar', 'w+') { |f| f.content_type = 'text/html' }
259
+ ct2 = nil
260
+ GridStore.open(@@db, 'foobar', 'r') { |f| ct2 = f.content_type }
261
+ assert_equal 'text/html', ct2
262
+ end
263
+
264
+ def test_content_type_option
265
+ GridStore.open(@@db, 'new-file', 'w', :content_type => 'image/jpg') { |f| f.write('foo') }
266
+ ct = nil
267
+ GridStore.open(@@db, 'new-file', 'r') { |f| ct = f.content_type }
268
+ assert_equal 'image/jpg', ct
269
+ end
270
+
271
+ def test_unknown_mode
272
+ GridStore.open(@@db, 'foobar', 'x')
273
+ fail 'should have seen "illegal mode" error raised'
274
+ rescue => ex
275
+ assert_equal "error: illegal mode x", ex.to_s
276
+ end
277
+
278
+ def test_metadata
279
+ GridStore.open(@@db, 'foobar', 'r') { |f| assert_nil f.metadata }
280
+ GridStore.open(@@db, 'foobar', 'w+') { |f| f.metadata = {'a' => 1} }
281
+ GridStore.open(@@db, 'foobar', 'r') { |f| assert_equal({'a' => 1}, f.metadata) }
282
+ end
283
+
284
+ end
@@ -4,7 +4,7 @@ require 'test/unit'
4
4
 
5
5
  class MessageTest < Test::Unit::TestCase
6
6
 
7
- include XGen::Mongo::Driver
7
+ include Mongo
8
8
 
9
9
  def setup
10
10
  @msg = Message.new(42)
@@ -0,0 +1,105 @@
1
+ $LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
2
+ require 'mongo'
3
+ require 'test/unit'
4
+
5
+ class ObjectIDTest < Test::Unit::TestCase
6
+
7
+ include Mongo
8
+
9
+ def setup
10
+ @o = ObjectID.new()
11
+ end
12
+
13
+ def test_different
14
+ a = ObjectID.new
15
+ b = ObjectID.new
16
+ assert_not_equal a.to_a, b.to_a
17
+ assert_not_equal a, b
18
+ end
19
+
20
+ def test_eql?
21
+ o2 = ObjectID.new(@o.to_a)
22
+ assert_equal @o, o2
23
+ end
24
+
25
+ def test_to_s
26
+ s = @o.to_s
27
+ assert_equal 24, s.length
28
+ s =~ /^([0-9a-f]+)$/
29
+ assert_equal 24, $1.length
30
+ end
31
+
32
+ def test_to_s_legacy
33
+ s = @o.to_s_legacy
34
+ assert_equal 24, s.length
35
+ s =~ /^([0-9a-f]+)$/
36
+ assert_equal 24, $1.length
37
+
38
+ assert_not_equal s, @o.to_s
39
+ end
40
+
41
+ def test_save_and_restore
42
+ host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
43
+ port = ENV['MONGO_RUBY_DRIVER_PORT'] || Connection::DEFAULT_PORT
44
+ db = Connection.new(host, port).db('ruby-mongo-test')
45
+ coll = db.collection('test')
46
+
47
+ coll.clear
48
+ coll << {'a' => 1, '_id' => @o}
49
+
50
+ row = coll.find().collect.first
51
+ assert_equal 1, row['a']
52
+ assert_equal @o, row['_id']
53
+ end
54
+
55
+ def test_from_string
56
+ hex_str = @o.to_s
57
+ o2 = ObjectID.from_string(hex_str)
58
+ assert_equal hex_str, o2.to_s
59
+ assert_equal @o, o2
60
+ assert_equal @o.to_s, o2.to_s
61
+ end
62
+
63
+ def test_from_string_legacy
64
+ hex_str = @o.to_s_legacy
65
+ o2 = ObjectID.from_string_legacy(hex_str)
66
+ assert_equal hex_str, o2.to_s_legacy
67
+ assert_equal @o, o2
68
+ assert_equal @o.to_s, o2.to_s
69
+ end
70
+
71
+ def test_legal
72
+ assert !ObjectID.legal?(nil)
73
+ assert !ObjectID.legal?("fred")
74
+ assert !ObjectID.legal?("0000")
75
+ assert !ObjectID.legal?('000102030405060708090A0')
76
+ assert ObjectID.legal?('000102030405060708090A0B')
77
+ assert ObjectID.legal?('abcdefABCDEF123456789012')
78
+ assert !ObjectID.legal?('abcdefABCDEF12345678901x')
79
+ end
80
+
81
+ def test_from_string_leading_zeroes
82
+ hex_str = '000000000000000000000000'
83
+ o = ObjectID.from_string(hex_str)
84
+ assert_equal hex_str, o.to_s
85
+ end
86
+
87
+ def test_byte_order
88
+ hex_str = '000102030405060708090A0B'
89
+ o = ObjectID.from_string(hex_str)
90
+ assert_equal [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b], o.to_a
91
+ end
92
+
93
+ def test_legacy_byte_order
94
+ hex_str = '000102030405060708090A0B'
95
+ o = ObjectID.from_string_legacy(hex_str)
96
+ assert_equal [0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x0b, 0x0a, 0x09, 0x08], o.to_a
97
+ end
98
+
99
+ def test_legacy_string_convert
100
+ l = @o.to_s_legacy
101
+ s = @o.to_s
102
+ assert_equal s, ObjectID.legacy_string_convert(l)
103
+ end
104
+
105
+ end
@@ -12,10 +12,46 @@ class OrderedHashTest < Test::Unit::TestCase
12
12
  @ordered_keys = %w(c a z)
13
13
  end
14
14
 
15
+ def test_initialize
16
+ a = OrderedHash.new
17
+ a['x'] = 1
18
+ a['y'] = 2
19
+
20
+ b = OrderedHash['x' => 1, 'y' => 2]
21
+ assert_equal a, b
22
+ end
23
+
15
24
  def test_empty
16
25
  assert_equal [], OrderedHash.new.keys
17
26
  end
18
27
 
28
+ def test_equality
29
+ a = OrderedHash.new
30
+ a['x'] = 1
31
+ a['y'] = 2
32
+
33
+ b = OrderedHash.new
34
+ b['y'] = 2
35
+ b['x'] = 1
36
+
37
+ c = OrderedHash.new
38
+ c['x'] = 1
39
+ c['y'] = 2
40
+
41
+ d = OrderedHash.new
42
+ d['x'] = 2
43
+ d['y'] = 3
44
+
45
+ e = OrderedHash.new
46
+ e['z'] = 1
47
+ e['y'] = 2
48
+
49
+ assert_equal a, c
50
+ assert_not_equal a, b
51
+ assert_not_equal a, d
52
+ assert_not_equal a, e
53
+ end
54
+
19
55
  def test_order_preserved
20
56
  assert_equal @ordered_keys, @oh.keys
21
57
  end
@@ -36,6 +72,8 @@ class OrderedHashTest < Test::Unit::TestCase
36
72
 
37
73
  @oh['z'] = 42
38
74
  assert_equal keys, @oh.keys
75
+
76
+ assert_equal @oh, @oh.each {|k,v|}
39
77
  end
40
78
 
41
79
  def test_values
@@ -82,4 +120,21 @@ class OrderedHashTest < Test::Unit::TestCase
82
120
  assert_equal '{"c"=>1, "a"=>2, "z"=>3}', @oh.inspect
83
121
  end
84
122
 
123
+ def test_clear
124
+ @oh.clear
125
+ assert @oh.keys.empty?
126
+ end
127
+
128
+ def test_delete
129
+ assert @oh.keys.include?('z')
130
+ @oh.delete('z')
131
+ assert !@oh.keys.include?('z')
132
+ end
133
+
134
+ def test_delete_if
135
+ assert @oh.keys.include?('z')
136
+ @oh.delete_if { |k,v| k == 'z' }
137
+ assert !@oh.keys.include?('z')
138
+ end
139
+
85
140
  end