animehunter-mongo 0.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.
- data/README.rdoc +311 -0
- data/Rakefile +62 -0
- data/bin/bson_benchmark.rb +59 -0
- data/bin/mongo_console +21 -0
- data/bin/run_test_script +19 -0
- data/bin/standard_benchmark +109 -0
- data/examples/admin.rb +41 -0
- data/examples/benchmarks.rb +42 -0
- data/examples/blog.rb +76 -0
- data/examples/capped.rb +23 -0
- data/examples/cursor.rb +47 -0
- data/examples/gridfs.rb +87 -0
- data/examples/index_test.rb +125 -0
- data/examples/info.rb +30 -0
- data/examples/queries.rb +69 -0
- data/examples/simple.rb +23 -0
- data/examples/strict.rb +34 -0
- data/examples/types.rb +40 -0
- data/lib/mongo.rb +19 -0
- data/lib/mongo/admin.rb +87 -0
- data/lib/mongo/collection.rb +235 -0
- data/lib/mongo/cursor.rb +227 -0
- data/lib/mongo/db.rb +538 -0
- data/lib/mongo/gridfs.rb +16 -0
- data/lib/mongo/gridfs/chunk.rb +96 -0
- data/lib/mongo/gridfs/grid_store.rb +468 -0
- data/lib/mongo/message.rb +20 -0
- data/lib/mongo/message/get_more_message.rb +37 -0
- data/lib/mongo/message/insert_message.rb +35 -0
- data/lib/mongo/message/kill_cursors_message.rb +36 -0
- data/lib/mongo/message/message.rb +84 -0
- data/lib/mongo/message/message_header.rb +50 -0
- data/lib/mongo/message/msg_message.rb +33 -0
- data/lib/mongo/message/opcodes.rb +32 -0
- data/lib/mongo/message/query_message.rb +77 -0
- data/lib/mongo/message/remove_message.rb +36 -0
- data/lib/mongo/message/update_message.rb +37 -0
- data/lib/mongo/mongo.rb +164 -0
- data/lib/mongo/query.rb +119 -0
- data/lib/mongo/types/binary.rb +42 -0
- data/lib/mongo/types/code.rb +34 -0
- data/lib/mongo/types/dbref.rb +37 -0
- data/lib/mongo/types/objectid.rb +137 -0
- data/lib/mongo/types/regexp_of_holding.rb +44 -0
- data/lib/mongo/types/undefined.rb +31 -0
- data/lib/mongo/util/bson.rb +534 -0
- data/lib/mongo/util/byte_buffer.rb +167 -0
- data/lib/mongo/util/ordered_hash.rb +96 -0
- data/lib/mongo/util/xml_to_ruby.rb +107 -0
- data/mongo-ruby-driver.gemspec +99 -0
- data/tests/mongo-qa/_common.rb +8 -0
- data/tests/mongo-qa/admin +26 -0
- data/tests/mongo-qa/capped +22 -0
- data/tests/mongo-qa/count1 +18 -0
- data/tests/mongo-qa/dbs +22 -0
- data/tests/mongo-qa/find +10 -0
- data/tests/mongo-qa/find1 +15 -0
- data/tests/mongo-qa/gridfs_in +16 -0
- data/tests/mongo-qa/gridfs_out +17 -0
- data/tests/mongo-qa/indices +49 -0
- data/tests/mongo-qa/remove +25 -0
- data/tests/mongo-qa/stress1 +35 -0
- data/tests/mongo-qa/test1 +11 -0
- data/tests/mongo-qa/update +18 -0
- data/tests/test_admin.rb +69 -0
- data/tests/test_bson.rb +246 -0
- data/tests/test_byte_buffer.rb +69 -0
- data/tests/test_chunk.rb +84 -0
- data/tests/test_cursor.rb +121 -0
- data/tests/test_db.rb +160 -0
- data/tests/test_db_api.rb +701 -0
- data/tests/test_db_connection.rb +18 -0
- data/tests/test_grid_store.rb +284 -0
- data/tests/test_message.rb +35 -0
- data/tests/test_mongo.rb +78 -0
- data/tests/test_objectid.rb +98 -0
- data/tests/test_ordered_hash.rb +129 -0
- data/tests/test_round_trip.rb +116 -0
- metadata +133 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
|
2
|
+
require 'mongo'
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
|
|
5
|
+
class ByteBufferTest < Test::Unit::TestCase
|
|
6
|
+
|
|
7
|
+
def setup
|
|
8
|
+
@buf = ByteBuffer.new
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def test_nil_get_returns_one_byte
|
|
12
|
+
@buf.put_array([1, 2, 3, 4])
|
|
13
|
+
@buf.rewind
|
|
14
|
+
assert_equal 1, @buf.get
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def test_one_get_returns_array_length_one
|
|
18
|
+
@buf.put_array([1, 2, 3, 4])
|
|
19
|
+
@buf.rewind
|
|
20
|
+
assert_equal [1], @buf.get(1)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def test_zero_get_returns_empty_array
|
|
24
|
+
@buf.put_array([1, 2, 3, 4])
|
|
25
|
+
@buf.rewind
|
|
26
|
+
assert_equal [], @buf.get(0)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def test_empty
|
|
30
|
+
assert_equal 0, @buf.length
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_length
|
|
34
|
+
@buf.put_int 3
|
|
35
|
+
assert_equal 4, @buf.length
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_default_order
|
|
39
|
+
assert_equal :little_endian, @buf.order
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def test_long_length
|
|
43
|
+
@buf.put_long 1027
|
|
44
|
+
assert_equal 8, @buf.length
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def test_get_long
|
|
48
|
+
@buf.put_long 1027
|
|
49
|
+
@buf.rewind
|
|
50
|
+
assert_equal 1027, @buf.get_long
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_get_double
|
|
54
|
+
@buf.put_double 41.2
|
|
55
|
+
@buf.rewind
|
|
56
|
+
assert_equal 41.2, @buf.get_double
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_rewrite
|
|
60
|
+
@buf.put_int(0)
|
|
61
|
+
@buf.rewind
|
|
62
|
+
@buf.put_int(1027)
|
|
63
|
+
assert_equal 4, @buf.length
|
|
64
|
+
@buf.rewind
|
|
65
|
+
assert_equal 1027, @buf.get_int
|
|
66
|
+
assert_equal 4, @buf.position
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
end
|
data/tests/test_chunk.rb
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
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 ChunkTest < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
include XGen::Mongo::Driver
|
|
9
|
+
include XGen::Mongo::GridFS
|
|
10
|
+
|
|
11
|
+
@@db = Mongo.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
|
|
12
|
+
ENV['MONGO_RUBY_DRIVER_PORT'] || Mongo::DEFAULT_PORT).db('ruby-mongo-utils-test')
|
|
13
|
+
@@files = @@db.collection('gridfs.files')
|
|
14
|
+
@@chunks = @@db.collection('gridfs.chunks')
|
|
15
|
+
|
|
16
|
+
def setup
|
|
17
|
+
@@chunks.clear
|
|
18
|
+
@@files.clear
|
|
19
|
+
|
|
20
|
+
@f = GridStore.new(@@db, 'foobar', 'w')
|
|
21
|
+
@c = @f.instance_variable_get('@curr_chunk')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def teardown
|
|
25
|
+
@@chunks.clear
|
|
26
|
+
@@files.clear
|
|
27
|
+
@@db.error
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def test_pos
|
|
31
|
+
assert_equal 0, @c.pos
|
|
32
|
+
assert @c.eof? # since data is empty
|
|
33
|
+
|
|
34
|
+
b = ByteBuffer.new
|
|
35
|
+
3.times { |i| b.put(i) }
|
|
36
|
+
c = Chunk.new(@f, 'data' => b)
|
|
37
|
+
assert !c.eof?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def test_getc
|
|
41
|
+
b = ByteBuffer.new
|
|
42
|
+
3.times { |i| b.put(i) }
|
|
43
|
+
c = Chunk.new(@f, 'data' => b)
|
|
44
|
+
|
|
45
|
+
assert !c.eof?
|
|
46
|
+
assert_equal 0, c.getc
|
|
47
|
+
assert !c.eof?
|
|
48
|
+
assert_equal 1, c.getc
|
|
49
|
+
assert !c.eof?
|
|
50
|
+
assert_equal 2, c.getc
|
|
51
|
+
assert c.eof?
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_putc
|
|
55
|
+
3.times { |i| @c.putc(i) }
|
|
56
|
+
@c.pos = 0
|
|
57
|
+
|
|
58
|
+
assert !@c.eof?
|
|
59
|
+
assert_equal 0, @c.getc
|
|
60
|
+
assert !@c.eof?
|
|
61
|
+
assert_equal 1, @c.getc
|
|
62
|
+
assert !@c.eof?
|
|
63
|
+
assert_equal 2, @c.getc
|
|
64
|
+
assert @c.eof?
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def test_truncate
|
|
68
|
+
10.times { |i| @c.putc(i) }
|
|
69
|
+
assert_equal 10, @c.size
|
|
70
|
+
@c.pos = 3
|
|
71
|
+
@c.truncate
|
|
72
|
+
assert_equal 3, @c.size
|
|
73
|
+
|
|
74
|
+
@c.pos = 0
|
|
75
|
+
assert !@c.eof?
|
|
76
|
+
assert_equal 0, @c.getc
|
|
77
|
+
assert !@c.eof?
|
|
78
|
+
assert_equal 1, @c.getc
|
|
79
|
+
assert !@c.eof?
|
|
80
|
+
assert_equal 2, @c.getc
|
|
81
|
+
assert @c.eof?
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
end
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
|
2
|
+
require 'mongo'
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
|
|
5
|
+
# NOTE: assumes Mongo is running
|
|
6
|
+
class CursorTest < Test::Unit::TestCase
|
|
7
|
+
|
|
8
|
+
include XGen::Mongo::Driver
|
|
9
|
+
|
|
10
|
+
@@db = Mongo.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
|
|
11
|
+
ENV['MONGO_RUBY_DRIVER_PORT'] || Mongo::DEFAULT_PORT).db('ruby-mongo-test')
|
|
12
|
+
@@coll = @@db.collection('test')
|
|
13
|
+
|
|
14
|
+
def setup
|
|
15
|
+
@@coll.clear
|
|
16
|
+
@@coll.insert('a' => 1) # collection not created until it's used
|
|
17
|
+
@@coll_full_name = 'ruby-mongo-test.test'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def teardown
|
|
21
|
+
@@coll.clear
|
|
22
|
+
@@db.error
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_explain
|
|
26
|
+
cursor = @@coll.find('a' => 1)
|
|
27
|
+
explaination = cursor.explain
|
|
28
|
+
assert_not_nil explaination['cursor']
|
|
29
|
+
assert_kind_of Numeric, explaination['n']
|
|
30
|
+
assert_kind_of Numeric, explaination['millis']
|
|
31
|
+
assert_kind_of Numeric, explaination['nscanned']
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def test_close_no_query_sent
|
|
35
|
+
begin
|
|
36
|
+
cursor = @@coll.find('a' => 1)
|
|
37
|
+
cursor.close
|
|
38
|
+
assert cursor.closed?
|
|
39
|
+
rescue => ex
|
|
40
|
+
fail ex.to_s
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def test_refill_via_get_more
|
|
45
|
+
begin
|
|
46
|
+
assert_equal 1, @@coll.count
|
|
47
|
+
1000.times { |i|
|
|
48
|
+
assert_equal 1 + i, @@coll.count
|
|
49
|
+
@@coll.insert('a' => i)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
assert_equal 1001, @@coll.count
|
|
53
|
+
count = 0
|
|
54
|
+
@@coll.find.each { |obj|
|
|
55
|
+
count += obj['a']
|
|
56
|
+
}
|
|
57
|
+
assert_equal 1001, @@coll.count
|
|
58
|
+
|
|
59
|
+
# do the same thing again for debugging
|
|
60
|
+
assert_equal 1001, @@coll.count
|
|
61
|
+
count2 = 0
|
|
62
|
+
@@coll.find.each { |obj|
|
|
63
|
+
count2 += obj['a']
|
|
64
|
+
}
|
|
65
|
+
assert_equal 1001, @@coll.count
|
|
66
|
+
|
|
67
|
+
assert_equal count, count2
|
|
68
|
+
assert_equal 499501, count
|
|
69
|
+
rescue Test::Unit::AssertionFailedError => ex
|
|
70
|
+
p @@db.collection_names
|
|
71
|
+
Process.exit 1
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def test_refill_via_get_more_alt_coll
|
|
76
|
+
begin
|
|
77
|
+
coll = @@db.collection('test-alt-coll')
|
|
78
|
+
coll.clear
|
|
79
|
+
coll.insert('a' => 1) # collection not created until it's used
|
|
80
|
+
assert_equal 1, coll.count
|
|
81
|
+
|
|
82
|
+
1000.times { |i|
|
|
83
|
+
assert_equal 1 + i, coll.count
|
|
84
|
+
coll.insert('a' => i)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
assert_equal 1001, coll.count
|
|
88
|
+
count = 0
|
|
89
|
+
coll.find.each { |obj|
|
|
90
|
+
count += obj['a']
|
|
91
|
+
}
|
|
92
|
+
assert_equal 1001, coll.count
|
|
93
|
+
|
|
94
|
+
# do the same thing again for debugging
|
|
95
|
+
assert_equal 1001, coll.count
|
|
96
|
+
count2 = 0
|
|
97
|
+
coll.find.each { |obj|
|
|
98
|
+
count2 += obj['a']
|
|
99
|
+
}
|
|
100
|
+
assert_equal 1001, coll.count
|
|
101
|
+
|
|
102
|
+
assert_equal count, count2
|
|
103
|
+
assert_equal 499501, count
|
|
104
|
+
rescue Test::Unit::AssertionFailedError => ex
|
|
105
|
+
p @@db.collection_names
|
|
106
|
+
Process.exit 1
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def test_close_after_query_sent
|
|
111
|
+
begin
|
|
112
|
+
cursor = @@coll.find('a' => 1)
|
|
113
|
+
cursor.next_object
|
|
114
|
+
cursor.close
|
|
115
|
+
assert cursor.closed?
|
|
116
|
+
rescue => ex
|
|
117
|
+
fail ex.to_s
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
end
|
data/tests/test_db.rb
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
|
2
|
+
require 'digest/md5'
|
|
3
|
+
require 'mongo'
|
|
4
|
+
require 'test/unit'
|
|
5
|
+
|
|
6
|
+
class TestPKFactory
|
|
7
|
+
def create_pk(row)
|
|
8
|
+
row['_id'] ||= XGen::Mongo::Driver::ObjectID.new
|
|
9
|
+
row
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# NOTE: assumes Mongo is running
|
|
14
|
+
class DBTest < Test::Unit::TestCase
|
|
15
|
+
|
|
16
|
+
include XGen::Mongo::Driver
|
|
17
|
+
|
|
18
|
+
@@host = ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost'
|
|
19
|
+
@@port = ENV['MONGO_RUBY_DRIVER_PORT'] || Mongo::DEFAULT_PORT
|
|
20
|
+
@@db = Mongo.new(@@host, @@port).db('ruby-mongo-test')
|
|
21
|
+
@@users = @@db.collection('system.users')
|
|
22
|
+
|
|
23
|
+
def setup
|
|
24
|
+
@spongebob = 'spongebob'
|
|
25
|
+
@spongebob_password = 'squarepants'
|
|
26
|
+
@@users.clear
|
|
27
|
+
@@users.insert(:user => @spongebob, :pwd => @@db.send(:hash_password, @spongebob, @spongebob_password))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def teardown
|
|
31
|
+
@@users.clear if @@users
|
|
32
|
+
@@db.error
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def test_close
|
|
36
|
+
@@db.close
|
|
37
|
+
assert !@@db.connected?
|
|
38
|
+
begin
|
|
39
|
+
@@db.collection('test').insert('a' => 1)
|
|
40
|
+
fail "expected 'NilClass' exception"
|
|
41
|
+
rescue => ex
|
|
42
|
+
assert_match /NilClass/, ex.to_s
|
|
43
|
+
ensure
|
|
44
|
+
@@db = Mongo.new(@@host, @@port).db('ruby-mongo-test')
|
|
45
|
+
@@users = @@db.collection('system.users')
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def test_full_coll_name
|
|
50
|
+
coll = @@db.collection('test')
|
|
51
|
+
assert_equal 'ruby-mongo-test.test', @@db.full_coll_name(coll.name)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def test_pair
|
|
55
|
+
@@db.close
|
|
56
|
+
@@users = nil
|
|
57
|
+
@@db = Mongo.new({:left => "this-should-fail", :right => [@@host, @@port]}).db('ruby-mongo-test')
|
|
58
|
+
assert @@db.connected?
|
|
59
|
+
ensure
|
|
60
|
+
@@db = Mongo.new(@@host, @@port).db('ruby-mongo-test') unless @@db.connected?
|
|
61
|
+
@@users = @@db.collection('system.users')
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_pk_factory
|
|
65
|
+
db = Mongo.new(@@host, @@port).db('ruby-mongo-test', :pk => TestPKFactory.new)
|
|
66
|
+
coll = db.collection('test')
|
|
67
|
+
coll.clear
|
|
68
|
+
|
|
69
|
+
# new id gets added to returned object
|
|
70
|
+
obj = coll.insert('name' => 'Fred', 'age' => 42)
|
|
71
|
+
row = coll.find_first({'name' => 'Fred'}, :limit => 1)
|
|
72
|
+
oid = row['_id']
|
|
73
|
+
assert_not_nil oid
|
|
74
|
+
assert_equal obj, row
|
|
75
|
+
|
|
76
|
+
oid = XGen::Mongo::Driver::ObjectID.new
|
|
77
|
+
obj = coll.insert('_id' => oid, 'name' => 'Barney', 'age' => 41)
|
|
78
|
+
row = coll.find_first({'name' => 'Barney'}, :limit => 1)
|
|
79
|
+
db_oid = row['_id']
|
|
80
|
+
assert_equal oid, db_oid
|
|
81
|
+
assert_equal obj, row
|
|
82
|
+
|
|
83
|
+
coll.clear
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def test_pk_factory_reset
|
|
87
|
+
db = Mongo.new(@@host, @@port).db('ruby-mongo-test')
|
|
88
|
+
db.pk_factory = Object.new # first time
|
|
89
|
+
begin
|
|
90
|
+
db.pk_factory = Object.new
|
|
91
|
+
fail "error: expected exception"
|
|
92
|
+
rescue => ex
|
|
93
|
+
assert_match /can not change PK factory/, ex.to_s
|
|
94
|
+
ensure
|
|
95
|
+
db.close
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def test_authenticate
|
|
100
|
+
assert !@@db.authenticate('nobody', 'nopassword')
|
|
101
|
+
assert !@@db.authenticate(@spongebob, 'squareliederhosen')
|
|
102
|
+
assert @@db.authenticate(@spongebob, @spongebob_password)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def test_logout
|
|
106
|
+
@@db.logout # only testing that we don't throw exception
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def test_auto_connect
|
|
110
|
+
@@db.close
|
|
111
|
+
db = Mongo.new(@@host, @@port, :auto_reconnect => true).db('ruby-mongo-test')
|
|
112
|
+
assert db.connected?
|
|
113
|
+
assert db.auto_reconnect?
|
|
114
|
+
db.close
|
|
115
|
+
assert !db.connected?
|
|
116
|
+
assert db.auto_reconnect?
|
|
117
|
+
db.collection('test').insert('a' => 1)
|
|
118
|
+
assert db.connected?
|
|
119
|
+
ensure
|
|
120
|
+
@@db = Mongo.new(@@host, @@port).db('ruby-mongo-test')
|
|
121
|
+
@@users = @@db.collection('system.users')
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def test_error
|
|
125
|
+
@@db.reset_error_history
|
|
126
|
+
assert_nil @@db.error
|
|
127
|
+
assert !@@db.error?
|
|
128
|
+
assert_nil @@db.previous_error
|
|
129
|
+
|
|
130
|
+
@@db.send(:db_command, :forceerror => 1)
|
|
131
|
+
assert @@db.error?
|
|
132
|
+
assert_not_nil @@db.error
|
|
133
|
+
assert_not_nil @@db.previous_error
|
|
134
|
+
|
|
135
|
+
@@db.send(:db_command, :forceerror => 1)
|
|
136
|
+
assert @@db.error?
|
|
137
|
+
assert @@db.error
|
|
138
|
+
prev_error = @@db.previous_error
|
|
139
|
+
assert_equal 1, prev_error['nPrev']
|
|
140
|
+
assert_equal prev_error["err"], @@db.error
|
|
141
|
+
|
|
142
|
+
@@db.collection('test').find_first
|
|
143
|
+
assert_nil @@db.error
|
|
144
|
+
assert !@@db.error?
|
|
145
|
+
assert @@db.previous_error
|
|
146
|
+
assert_equal 2, @@db.previous_error['nPrev']
|
|
147
|
+
|
|
148
|
+
@@db.reset_error_history
|
|
149
|
+
assert_nil @@db.error
|
|
150
|
+
assert !@@db.error?
|
|
151
|
+
assert_nil @@db.previous_error
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def test_text_port_number
|
|
155
|
+
db = DB.new('ruby-mongo-test', [[@@host, @@port.to_s]])
|
|
156
|
+
# If there is no error, all is well
|
|
157
|
+
db.collection('users').clear
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
end
|
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
$LOAD_PATH[0,0] = File.join(File.dirname(__FILE__), '..', 'lib')
|
|
2
|
+
require 'mongo'
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
|
|
5
|
+
# NOTE: assumes Mongo is running
|
|
6
|
+
class DBAPITest < Test::Unit::TestCase
|
|
7
|
+
include XGen::Mongo
|
|
8
|
+
include XGen::Mongo::Driver
|
|
9
|
+
|
|
10
|
+
@@db = Mongo.new(ENV['MONGO_RUBY_DRIVER_HOST'] || 'localhost',
|
|
11
|
+
ENV['MONGO_RUBY_DRIVER_PORT'] || Mongo::DEFAULT_PORT).db('ruby-mongo-test')
|
|
12
|
+
@@coll = @@db.collection('test')
|
|
13
|
+
|
|
14
|
+
def setup
|
|
15
|
+
@@coll.clear
|
|
16
|
+
@r1 = @@coll.insert('a' => 1) # collection not created until it's used
|
|
17
|
+
@@coll_full_name = 'ruby-mongo-test.test'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def teardown
|
|
21
|
+
@@coll.clear
|
|
22
|
+
@@db.error
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def test_clear
|
|
26
|
+
assert_equal 1, @@coll.count
|
|
27
|
+
@@coll.clear
|
|
28
|
+
assert_equal 0, @@coll.count
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_insert
|
|
32
|
+
@@coll.insert('a' => 2)
|
|
33
|
+
@@coll.insert('b' => 3)
|
|
34
|
+
|
|
35
|
+
assert_equal 3, @@coll.count
|
|
36
|
+
docs = @@coll.find().to_a
|
|
37
|
+
assert_equal 3, docs.length
|
|
38
|
+
assert docs.detect { |row| row['a'] == 1 }
|
|
39
|
+
assert docs.detect { |row| row['a'] == 2 }
|
|
40
|
+
assert docs.detect { |row| row['b'] == 3 }
|
|
41
|
+
|
|
42
|
+
@@coll << {'b' => 4}
|
|
43
|
+
docs = @@coll.find().to_a
|
|
44
|
+
assert_equal 4, docs.length
|
|
45
|
+
assert docs.detect { |row| row['b'] == 4 }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_insert_multiple
|
|
49
|
+
@@coll.insert({'a' => 2}, {'b' => 3})
|
|
50
|
+
|
|
51
|
+
assert_equal 3, @@coll.count
|
|
52
|
+
docs = @@coll.find().to_a
|
|
53
|
+
assert_equal 3, docs.length
|
|
54
|
+
assert docs.detect { |row| row['a'] == 1 }
|
|
55
|
+
assert docs.detect { |row| row['a'] == 2 }
|
|
56
|
+
assert docs.detect { |row| row['b'] == 3 }
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def test_count_on_nonexisting
|
|
60
|
+
@@db.drop_collection('foo')
|
|
61
|
+
assert_equal 0, @@db.collection('foo').count()
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def test_find_simple
|
|
65
|
+
@r2 = @@coll.insert('a' => 2)
|
|
66
|
+
@r3 = @@coll.insert('b' => 3)
|
|
67
|
+
# Check sizes
|
|
68
|
+
docs = @@coll.find().to_a
|
|
69
|
+
assert_equal 3, docs.size
|
|
70
|
+
assert_equal 3, @@coll.count
|
|
71
|
+
|
|
72
|
+
# Find by other value
|
|
73
|
+
docs = @@coll.find('a' => @r1['a']).to_a
|
|
74
|
+
assert_equal 1, docs.size
|
|
75
|
+
doc = docs.first
|
|
76
|
+
# Can't compare _id values because at insert, an _id was added to @r1 by
|
|
77
|
+
# the database but we don't know what it is without re-reading the record
|
|
78
|
+
# (which is what we are doing right now).
|
|
79
|
+
# assert_equal doc['_id'], @r1['_id']
|
|
80
|
+
assert_equal doc['a'], @r1['a']
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_find_advanced
|
|
84
|
+
@@coll.insert('a' => 2)
|
|
85
|
+
@@coll.insert('b' => 3)
|
|
86
|
+
|
|
87
|
+
# Find by advanced query (less than)
|
|
88
|
+
docs = @@coll.find('a' => { '$lt' => 10 }).to_a
|
|
89
|
+
assert_equal 2, docs.size
|
|
90
|
+
assert docs.detect { |row| row['a'] == 1 }
|
|
91
|
+
assert docs.detect { |row| row['a'] == 2 }
|
|
92
|
+
|
|
93
|
+
# Find by advanced query (greater than)
|
|
94
|
+
docs = @@coll.find('a' => { '$gt' => 1 }).to_a
|
|
95
|
+
assert_equal 1, docs.size
|
|
96
|
+
assert docs.detect { |row| row['a'] == 2 }
|
|
97
|
+
|
|
98
|
+
# Find by advanced query (less than or equal to)
|
|
99
|
+
docs = @@coll.find('a' => { '$lte' => 1 }).to_a
|
|
100
|
+
assert_equal 1, docs.size
|
|
101
|
+
assert docs.detect { |row| row['a'] == 1 }
|
|
102
|
+
|
|
103
|
+
# Find by advanced query (greater than or equal to)
|
|
104
|
+
docs = @@coll.find('a' => { '$gte' => 1 }).to_a
|
|
105
|
+
assert_equal 2, docs.size
|
|
106
|
+
assert docs.detect { |row| row['a'] == 1 }
|
|
107
|
+
assert docs.detect { |row| row['a'] == 2 }
|
|
108
|
+
|
|
109
|
+
# Find by advanced query (between)
|
|
110
|
+
docs = @@coll.find('a' => { '$gt' => 1, '$lt' => 3 }).to_a
|
|
111
|
+
assert_equal 1, docs.size
|
|
112
|
+
assert docs.detect { |row| row['a'] == 2 }
|
|
113
|
+
|
|
114
|
+
# Find by advanced query (in clause)
|
|
115
|
+
docs = @@coll.find('a' => {'$in' => [1,2]}).to_a
|
|
116
|
+
assert_equal 2, docs.size
|
|
117
|
+
assert docs.detect { |row| row['a'] == 1 }
|
|
118
|
+
assert docs.detect { |row| row['a'] == 2 }
|
|
119
|
+
|
|
120
|
+
# Find by advanced query (regexp)
|
|
121
|
+
docs = @@coll.find('a' => /[1|2]/).to_a
|
|
122
|
+
assert_equal 2, docs.size
|
|
123
|
+
assert docs.detect { |row| row['a'] == 1 }
|
|
124
|
+
assert docs.detect { |row| row['a'] == 2 }
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def test_find_sorting
|
|
128
|
+
@@coll.clear
|
|
129
|
+
@@coll.insert('a' => 1, 'b' => 2)
|
|
130
|
+
@@coll.insert('a' => 2, 'b' => 1)
|
|
131
|
+
@@coll.insert('a' => 3, 'b' => 2)
|
|
132
|
+
@@coll.insert('a' => 4, 'b' => 1)
|
|
133
|
+
|
|
134
|
+
# Sorting (ascending)
|
|
135
|
+
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => {'a' => 1}).to_a
|
|
136
|
+
assert_equal 4, docs.size
|
|
137
|
+
assert_equal 1, docs[0]['a']
|
|
138
|
+
assert_equal 2, docs[1]['a']
|
|
139
|
+
assert_equal 3, docs[2]['a']
|
|
140
|
+
assert_equal 4, docs[3]['a']
|
|
141
|
+
|
|
142
|
+
# Sorting (descending)
|
|
143
|
+
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => {'a' => -1}).to_a
|
|
144
|
+
assert_equal 4, docs.size
|
|
145
|
+
assert_equal 4, docs[0]['a']
|
|
146
|
+
assert_equal 3, docs[1]['a']
|
|
147
|
+
assert_equal 2, docs[2]['a']
|
|
148
|
+
assert_equal 1, docs[3]['a']
|
|
149
|
+
|
|
150
|
+
# Sorting using array of names; assumes ascending order.
|
|
151
|
+
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => ['a']).to_a
|
|
152
|
+
assert_equal 4, docs.size
|
|
153
|
+
assert_equal 1, docs[0]['a']
|
|
154
|
+
assert_equal 2, docs[1]['a']
|
|
155
|
+
assert_equal 3, docs[2]['a']
|
|
156
|
+
assert_equal 4, docs[3]['a']
|
|
157
|
+
|
|
158
|
+
# Sorting using single name; assumes ascending order.
|
|
159
|
+
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => 'a').to_a
|
|
160
|
+
assert_equal 4, docs.size
|
|
161
|
+
assert_equal 1, docs[0]['a']
|
|
162
|
+
assert_equal 2, docs[1]['a']
|
|
163
|
+
assert_equal 3, docs[2]['a']
|
|
164
|
+
assert_equal 4, docs[3]['a']
|
|
165
|
+
|
|
166
|
+
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => ['b', 'a']).to_a
|
|
167
|
+
assert_equal 4, docs.size
|
|
168
|
+
assert_equal 2, docs[0]['a']
|
|
169
|
+
assert_equal 4, docs[1]['a']
|
|
170
|
+
assert_equal 1, docs[2]['a']
|
|
171
|
+
assert_equal 3, docs[3]['a']
|
|
172
|
+
|
|
173
|
+
# Sorting using empty array; no order guarantee (Mongo bug #898) but
|
|
174
|
+
# should not blow up.
|
|
175
|
+
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => []).to_a
|
|
176
|
+
assert_equal 4, docs.size
|
|
177
|
+
|
|
178
|
+
# Sorting using array of hashes; no order guarantee (Mongo bug #898) but
|
|
179
|
+
# should not blow up.
|
|
180
|
+
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => [{'b' => 1}, {'a' => -1}]).to_a
|
|
181
|
+
assert_equal 4, docs.size
|
|
182
|
+
|
|
183
|
+
# Sorting using ordered hash. You can use an unordered one, but then the
|
|
184
|
+
# order of the keys won't be guaranteed thus your sort won't make sense.
|
|
185
|
+
oh = OrderedHash.new
|
|
186
|
+
oh['a'] = -1
|
|
187
|
+
docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a
|
|
188
|
+
assert_equal 4, docs.size
|
|
189
|
+
assert_equal 4, docs[0]['a']
|
|
190
|
+
assert_equal 3, docs[1]['a']
|
|
191
|
+
assert_equal 2, docs[2]['a']
|
|
192
|
+
assert_equal 1, docs[3]['a']
|
|
193
|
+
|
|
194
|
+
# TODO this will not pass due to known Mongo bug #898
|
|
195
|
+
# oh = OrderedHash.new
|
|
196
|
+
# oh['b'] = -1
|
|
197
|
+
# oh['a'] = 1
|
|
198
|
+
# docs = @@coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a
|
|
199
|
+
# assert_equal 4, docs.size
|
|
200
|
+
# assert_equal 1, docs[0]['a']
|
|
201
|
+
# assert_equal 3, docs[1]['a']
|
|
202
|
+
# assert_equal 2, docs[2]['a']
|
|
203
|
+
# assert_equal 4, docs[3]['a']
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def test_find_limits
|
|
207
|
+
@@coll.insert('b' => 2)
|
|
208
|
+
@@coll.insert('c' => 3)
|
|
209
|
+
@@coll.insert('d' => 4)
|
|
210
|
+
|
|
211
|
+
docs = @@coll.find({}, :limit => 1).to_a
|
|
212
|
+
assert_equal 1, docs.size
|
|
213
|
+
docs = @@coll.find({}, :limit => 2).to_a
|
|
214
|
+
assert_equal 2, docs.size
|
|
215
|
+
docs = @@coll.find({}, :limit => 3).to_a
|
|
216
|
+
assert_equal 3, docs.size
|
|
217
|
+
docs = @@coll.find({}, :limit => 4).to_a
|
|
218
|
+
assert_equal 4, docs.size
|
|
219
|
+
docs = @@coll.find({}).to_a
|
|
220
|
+
assert_equal 4, docs.size
|
|
221
|
+
docs = @@coll.find({}, :limit => 99).to_a
|
|
222
|
+
assert_equal 4, docs.size
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
def test_find_first
|
|
226
|
+
x = @@coll.find_first('a' => 1)
|
|
227
|
+
assert_not_nil x
|
|
228
|
+
assert_equal 1, x['a']
|
|
229
|
+
end
|
|
230
|
+
|
|
231
|
+
def test_find_first_no_records
|
|
232
|
+
@@coll.clear
|
|
233
|
+
x = @@coll.find_first('a' => 1)
|
|
234
|
+
assert_nil x
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
def test_drop_collection
|
|
238
|
+
assert @@db.drop_collection(@@coll.name), "drop of collection #{@@coll.name} failed"
|
|
239
|
+
assert !@@db.collection_names.include?(@@coll_full_name)
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def test_other_drop
|
|
243
|
+
assert @@db.collection_names.include?(@@coll_full_name)
|
|
244
|
+
@@coll.drop
|
|
245
|
+
assert !@@db.collection_names.include?(@@coll_full_name)
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def test_collection_names
|
|
249
|
+
names = @@db.collection_names
|
|
250
|
+
assert names.length >= 1
|
|
251
|
+
assert names.include?(@@coll_full_name)
|
|
252
|
+
|
|
253
|
+
coll2 = @@db.collection('test2')
|
|
254
|
+
coll2.insert('a' => 1) # collection not created until it's used
|
|
255
|
+
names = @@db.collection_names
|
|
256
|
+
assert names.length >= 2
|
|
257
|
+
assert names.include?(@@coll_full_name)
|
|
258
|
+
assert names.include?('ruby-mongo-test.test2')
|
|
259
|
+
ensure
|
|
260
|
+
@@db.drop_collection('test2')
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
def test_collections_info
|
|
264
|
+
cursor = @@db.collections_info
|
|
265
|
+
rows = cursor.to_a
|
|
266
|
+
assert rows.length >= 1
|
|
267
|
+
row = rows.detect { |r| r['name'] == @@coll_full_name }
|
|
268
|
+
assert_not_nil row
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
def test_collection_options
|
|
272
|
+
@@db.drop_collection('foobar')
|
|
273
|
+
@@db.strict = true
|
|
274
|
+
|
|
275
|
+
begin
|
|
276
|
+
coll = @@db.create_collection('foobar', :capped => true, :size => 1024)
|
|
277
|
+
options = coll.options()
|
|
278
|
+
assert_equal 'foobar', options['create']
|
|
279
|
+
assert_equal true, options['capped']
|
|
280
|
+
assert_equal 1024, options['size']
|
|
281
|
+
rescue => ex
|
|
282
|
+
@@db.drop_collection('foobar')
|
|
283
|
+
fail "did not expect exception \"#{ex}\""
|
|
284
|
+
ensure
|
|
285
|
+
@@db.strict = false
|
|
286
|
+
end
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
def test_index_information
|
|
290
|
+
assert_equal @@coll.index_information.length, 1
|
|
291
|
+
|
|
292
|
+
name = @@db.create_index(@@coll.name, 'a')
|
|
293
|
+
info = @@db.index_information(@@coll.name)
|
|
294
|
+
assert_equal name, "a_1"
|
|
295
|
+
assert_equal @@coll.index_information, info
|
|
296
|
+
assert_equal 2, info.length
|
|
297
|
+
|
|
298
|
+
assert info.has_key?(name)
|
|
299
|
+
assert_equal info[name], [["a", ASCENDING]]
|
|
300
|
+
ensure
|
|
301
|
+
@@db.drop_index(@@coll.name, name)
|
|
302
|
+
end
|
|
303
|
+
|
|
304
|
+
def test_index_create_with_symbol
|
|
305
|
+
assert_equal @@coll.index_information.length, 1
|
|
306
|
+
|
|
307
|
+
name = @@db.create_index(@@coll.name, :a)
|
|
308
|
+
info = @@db.index_information(@@coll.name)
|
|
309
|
+
assert_equal name, "a_1"
|
|
310
|
+
assert_equal @@coll.index_information, info
|
|
311
|
+
assert_equal 2, info.length
|
|
312
|
+
|
|
313
|
+
assert info.has_key?(name)
|
|
314
|
+
assert_equal info[name], [["a", ASCENDING]]
|
|
315
|
+
ensure
|
|
316
|
+
@@db.drop_index(@@coll.name, name)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def test_multiple_index_cols
|
|
320
|
+
name = @@db.create_index(@@coll.name, [['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]])
|
|
321
|
+
info = @@db.index_information(@@coll.name)
|
|
322
|
+
assert_equal 2, info.length
|
|
323
|
+
|
|
324
|
+
assert_equal name, 'a_-1_b_1_c_-1'
|
|
325
|
+
assert info.has_key?(name)
|
|
326
|
+
assert_equal [['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]], info[name]
|
|
327
|
+
ensure
|
|
328
|
+
@@db.drop_index(@@coll.name, name)
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
def test_multiple_index_cols_with_symbols
|
|
332
|
+
name = @@db.create_index(@@coll.name, [[:a, DESCENDING], [:b, ASCENDING], [:c, DESCENDING]])
|
|
333
|
+
info = @@db.index_information(@@coll.name)
|
|
334
|
+
assert_equal 2, info.length
|
|
335
|
+
|
|
336
|
+
assert_equal name, 'a_-1_b_1_c_-1'
|
|
337
|
+
assert info.has_key?(name)
|
|
338
|
+
assert_equal [['a', DESCENDING], ['b', ASCENDING], ['c', DESCENDING]], info[name]
|
|
339
|
+
ensure
|
|
340
|
+
@@db.drop_index(@@coll.name, name)
|
|
341
|
+
end
|
|
342
|
+
|
|
343
|
+
def test_unique_index
|
|
344
|
+
@@db.drop_collection("blah")
|
|
345
|
+
test = @@db.collection("blah")
|
|
346
|
+
test.create_index("hello")
|
|
347
|
+
|
|
348
|
+
test.insert("hello" => "world")
|
|
349
|
+
test.insert("hello" => "mike")
|
|
350
|
+
test.insert("hello" => "world")
|
|
351
|
+
assert !@@db.error?
|
|
352
|
+
|
|
353
|
+
@@db.drop_collection("blah")
|
|
354
|
+
test = @@db.collection("blah")
|
|
355
|
+
test.create_index("hello", unique=true)
|
|
356
|
+
|
|
357
|
+
test.insert("hello" => "world")
|
|
358
|
+
test.insert("hello" => "mike")
|
|
359
|
+
test.insert("hello" => "world")
|
|
360
|
+
assert @@db.error?
|
|
361
|
+
end
|
|
362
|
+
|
|
363
|
+
def test_index_on_subfield
|
|
364
|
+
@@db.drop_collection("blah")
|
|
365
|
+
test = @@db.collection("blah")
|
|
366
|
+
|
|
367
|
+
test.insert("hello" => {"a" => 4, "b" => 5})
|
|
368
|
+
test.insert("hello" => {"a" => 7, "b" => 2})
|
|
369
|
+
test.insert("hello" => {"a" => 4, "b" => 10})
|
|
370
|
+
assert !@@db.error?
|
|
371
|
+
|
|
372
|
+
@@db.drop_collection("blah")
|
|
373
|
+
test = @@db.collection("blah")
|
|
374
|
+
test.create_index("hello.a", unique=true)
|
|
375
|
+
|
|
376
|
+
test.insert("hello" => {"a" => 4, "b" => 5})
|
|
377
|
+
test.insert("hello" => {"a" => 7, "b" => 2})
|
|
378
|
+
test.insert("hello" => {"a" => 4, "b" => 10})
|
|
379
|
+
assert @@db.error?
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
def test_array
|
|
383
|
+
@@coll << {'b' => [1, 2, 3]}
|
|
384
|
+
rows = @@coll.find({}, {:fields => ['b']}).to_a
|
|
385
|
+
assert_equal 1, rows.length
|
|
386
|
+
assert_equal [1, 2, 3], rows[0]['b']
|
|
387
|
+
end
|
|
388
|
+
|
|
389
|
+
def test_regex
|
|
390
|
+
regex = /foobar/i
|
|
391
|
+
@@coll << {'b' => regex}
|
|
392
|
+
rows = @@coll.find({}, {:fields => ['b']}).to_a
|
|
393
|
+
assert_equal 1, rows.length
|
|
394
|
+
assert_equal regex, rows[0]['b']
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def test_non_oid_id
|
|
398
|
+
# Note: can't use Time.new because that will include fractional seconds,
|
|
399
|
+
# which Mongo does not store.
|
|
400
|
+
t = Time.at(1234567890)
|
|
401
|
+
@@coll << {'_id' => t}
|
|
402
|
+
rows = @@coll.find({'_id' => t}).to_a
|
|
403
|
+
assert_equal 1, rows.length
|
|
404
|
+
assert_equal t, rows[0]['_id']
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def test_strict
|
|
408
|
+
assert !@@db.strict?
|
|
409
|
+
@@db.strict = true
|
|
410
|
+
assert @@db.strict?
|
|
411
|
+
ensure
|
|
412
|
+
@@db.strict = false
|
|
413
|
+
end
|
|
414
|
+
|
|
415
|
+
def test_strict_access_collection
|
|
416
|
+
@@db.strict = true
|
|
417
|
+
begin
|
|
418
|
+
@@db.collection('does-not-exist')
|
|
419
|
+
fail "expected exception"
|
|
420
|
+
rescue => ex
|
|
421
|
+
assert_equal "Collection does-not-exist doesn't exist. Currently in strict mode.", ex.to_s
|
|
422
|
+
ensure
|
|
423
|
+
@@db.strict = false
|
|
424
|
+
@@db.drop_collection('does-not-exist')
|
|
425
|
+
end
|
|
426
|
+
end
|
|
427
|
+
|
|
428
|
+
def test_strict_create_collection
|
|
429
|
+
@@db.drop_collection('foobar')
|
|
430
|
+
@@db.strict = true
|
|
431
|
+
|
|
432
|
+
begin
|
|
433
|
+
@@db.create_collection('foobar')
|
|
434
|
+
assert true
|
|
435
|
+
rescue => ex
|
|
436
|
+
fail "did not expect exception \"#{ex}\""
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
# Now the collection exists. This time we should see an exception.
|
|
440
|
+
begin
|
|
441
|
+
@@db.create_collection('foobar')
|
|
442
|
+
fail "expected exception"
|
|
443
|
+
rescue => ex
|
|
444
|
+
assert_equal "Collection foobar already exists. Currently in strict mode.", ex.to_s
|
|
445
|
+
ensure
|
|
446
|
+
@@db.strict = false
|
|
447
|
+
@@db.drop_collection('foobar')
|
|
448
|
+
end
|
|
449
|
+
|
|
450
|
+
# Now we're not in strict mode - should succeed
|
|
451
|
+
@@db.create_collection('foobar')
|
|
452
|
+
@@db.create_collection('foobar')
|
|
453
|
+
@@db.drop_collection('foobar')
|
|
454
|
+
end
|
|
455
|
+
|
|
456
|
+
def test_replace
|
|
457
|
+
assert_equal @@coll.count, 1
|
|
458
|
+
assert_equal @@coll.find_first["a"], 1
|
|
459
|
+
|
|
460
|
+
@@coll.replace({"a" => 1}, {"a" => 2})
|
|
461
|
+
assert_equal @@coll.count, 1
|
|
462
|
+
assert_equal @@coll.find_first["a"], 2
|
|
463
|
+
|
|
464
|
+
@@coll.replace({"b" => 1}, {"a" => 3})
|
|
465
|
+
assert_equal @@coll.count, 1
|
|
466
|
+
assert_equal @@coll.find_first["a"], 2
|
|
467
|
+
end
|
|
468
|
+
|
|
469
|
+
def test_repsert
|
|
470
|
+
assert_equal @@coll.count, 1
|
|
471
|
+
assert_equal @@coll.find_first["a"], 1
|
|
472
|
+
|
|
473
|
+
@@coll.repsert({"a" => 1}, {"a" => 2})
|
|
474
|
+
assert_equal @@coll.count, 1
|
|
475
|
+
assert_equal @@coll.find_first["a"], 2
|
|
476
|
+
|
|
477
|
+
@@coll.repsert({"b" => 1}, {"a" => 3})
|
|
478
|
+
assert_equal @@coll.count, 2
|
|
479
|
+
assert @@coll.find_first({"a" => 3})
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
def test_to_a
|
|
483
|
+
cursor = @@coll.find()
|
|
484
|
+
rows = cursor.to_a
|
|
485
|
+
|
|
486
|
+
# Make sure we get back exactly the same array the next time we ask
|
|
487
|
+
rows2 = cursor.to_a
|
|
488
|
+
assert_same rows, rows2
|
|
489
|
+
|
|
490
|
+
# Make sure we can still iterate after calling to_a
|
|
491
|
+
rows_with_each = cursor.collect{|row| row}
|
|
492
|
+
assert_equal rows, rows_with_each
|
|
493
|
+
|
|
494
|
+
# Make sure we can iterate more than once after calling to_a
|
|
495
|
+
end
|
|
496
|
+
|
|
497
|
+
def test_to_a_after_each
|
|
498
|
+
cursor = @@coll.find
|
|
499
|
+
cursor.each { |row| row }
|
|
500
|
+
begin
|
|
501
|
+
cursor.to_a
|
|
502
|
+
fail "expected \"can't call\" error"
|
|
503
|
+
rescue => ex
|
|
504
|
+
assert_equal "can't call Cursor#to_a after calling Cursor#each", ex.to_s
|
|
505
|
+
end
|
|
506
|
+
end
|
|
507
|
+
|
|
508
|
+
def test_ismaster
|
|
509
|
+
assert @@db.master?
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
def test_master
|
|
513
|
+
assert_equal "#{@@db.host}:#{@@db.port}", @@db.master
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
def test_where
|
|
517
|
+
@@coll.insert('a' => 2)
|
|
518
|
+
@@coll.insert('a' => 3)
|
|
519
|
+
|
|
520
|
+
assert_equal 3, @@coll.count
|
|
521
|
+
assert_equal 1, @@coll.count('$where' => Code.new('this.a > 2'))
|
|
522
|
+
assert_equal 2, @@coll.count('$where' => Code.new('this.a > i', {'i' => 1}))
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
def test_eval
|
|
526
|
+
assert_equal 3, @@db.eval('function (x) {return x;}', 3)
|
|
527
|
+
|
|
528
|
+
assert_equal nil, @@db.eval("function (x) {db.test_eval.save({y:x});}", 5)
|
|
529
|
+
assert_equal 5, @@db.collection('test_eval').find_first['y']
|
|
530
|
+
|
|
531
|
+
assert_equal 5, @@db.eval("function (x, y) {return x + y;}", 2, 3)
|
|
532
|
+
assert_equal 5, @@db.eval("function () {return 5;}")
|
|
533
|
+
assert_equal 5, @@db.eval("2 + 3;")
|
|
534
|
+
|
|
535
|
+
assert_equal 5, @@db.eval(Code.new("2 + 3;"))
|
|
536
|
+
assert_equal 2, @@db.eval(Code.new("return i;", {"i" => 2}))
|
|
537
|
+
assert_equal 5, @@db.eval(Code.new("i + 3;", {"i" => 2}))
|
|
538
|
+
|
|
539
|
+
assert_raise RuntimeError do
|
|
540
|
+
@@db.eval("5 ++ 5;")
|
|
541
|
+
end
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
def test_hint
|
|
545
|
+
name = @@coll.create_index('a')
|
|
546
|
+
begin
|
|
547
|
+
assert_nil @@coll.hint
|
|
548
|
+
assert_equal 1, @@coll.find({'a' => 1}, :hint => 'a').to_a.size
|
|
549
|
+
assert_equal 1, @@coll.find({'a' => 1}, :hint => ['a']).to_a.size
|
|
550
|
+
assert_equal 1, @@coll.find({'a' => 1}, :hint => {'a' => 1}).to_a.size
|
|
551
|
+
|
|
552
|
+
@@coll.hint = 'a'
|
|
553
|
+
assert_equal({'a' => 1}, @@coll.hint)
|
|
554
|
+
assert_equal 1, @@coll.find('a' => 1).to_a.size
|
|
555
|
+
|
|
556
|
+
@@coll.hint = ['a']
|
|
557
|
+
assert_equal({'a' => 1}, @@coll.hint)
|
|
558
|
+
assert_equal 1, @@coll.find('a' => 1).to_a.size
|
|
559
|
+
|
|
560
|
+
@@coll.hint = {'a' => 1}
|
|
561
|
+
assert_equal({'a' => 1}, @@coll.hint)
|
|
562
|
+
assert_equal 1, @@coll.find('a' => 1).to_a.size
|
|
563
|
+
|
|
564
|
+
@@coll.hint = nil
|
|
565
|
+
assert_nil @@coll.hint
|
|
566
|
+
assert_equal 1, @@coll.find('a' => 1).to_a.size
|
|
567
|
+
ensure
|
|
568
|
+
@@coll.drop_index(name)
|
|
569
|
+
end
|
|
570
|
+
end
|
|
571
|
+
|
|
572
|
+
def test_hash_default_value_id
|
|
573
|
+
val = Hash.new(0)
|
|
574
|
+
val["x"] = 5
|
|
575
|
+
@@coll.insert val
|
|
576
|
+
id = @@coll.find_first("x" => 5)["_id"]
|
|
577
|
+
assert id != 0
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
def test_group
|
|
581
|
+
@@db.drop_collection("test")
|
|
582
|
+
test = @@db.collection("test")
|
|
583
|
+
|
|
584
|
+
assert_equal [], test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")
|
|
585
|
+
|
|
586
|
+
test.insert("a" => 2)
|
|
587
|
+
test.insert("b" => 5)
|
|
588
|
+
test.insert("a" => 1)
|
|
589
|
+
|
|
590
|
+
assert_equal 3, test.group([], {}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
|
|
591
|
+
assert_equal 1, test.group([], {"a" => {"$gt" => 1}}, {"count" => 0}, "function (obj, prev) { prev.count++; }")[0]["count"]
|
|
592
|
+
end
|
|
593
|
+
|
|
594
|
+
def test_deref
|
|
595
|
+
@@coll.clear
|
|
596
|
+
|
|
597
|
+
assert_equal nil, @@db.dereference(DBRef.new("test", ObjectID.new))
|
|
598
|
+
@@coll.insert({"x" => "hello"})
|
|
599
|
+
key = @@coll.find_first()["_id"]
|
|
600
|
+
assert_equal "hello", @@db.dereference(DBRef.new("test", key))["x"]
|
|
601
|
+
|
|
602
|
+
assert_equal nil, @@db.dereference(DBRef.new("test", 4))
|
|
603
|
+
obj = {"_id" => 4}
|
|
604
|
+
@@coll.insert(obj)
|
|
605
|
+
assert_equal obj, @@db.dereference(DBRef.new("test", 4))
|
|
606
|
+
|
|
607
|
+
@@coll.clear
|
|
608
|
+
@@coll.insert({"x" => "hello"})
|
|
609
|
+
assert_equal nil, @@db.dereference(DBRef.new("test", nil))
|
|
610
|
+
end
|
|
611
|
+
|
|
612
|
+
def test_save
|
|
613
|
+
@@coll.clear
|
|
614
|
+
|
|
615
|
+
a = {"hello" => "world"}
|
|
616
|
+
|
|
617
|
+
@@coll.save(a)
|
|
618
|
+
assert_equal 1, @@coll.count
|
|
619
|
+
|
|
620
|
+
@@coll.save(@@coll.find_first)
|
|
621
|
+
assert_equal 1, @@coll.count
|
|
622
|
+
|
|
623
|
+
assert_equal "world", @@coll.find_first()["hello"]
|
|
624
|
+
|
|
625
|
+
doc = @@coll.find_first
|
|
626
|
+
doc["hello"] = "mike"
|
|
627
|
+
@@coll.save(doc)
|
|
628
|
+
assert_equal 1, @@coll.count
|
|
629
|
+
|
|
630
|
+
assert_equal "mike", @@coll.find_first()["hello"]
|
|
631
|
+
|
|
632
|
+
@@coll.save(a)
|
|
633
|
+
assert_equal 2, @@coll.count
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
def test_save_with_object_that_has_id_but_does_not_actually_exist_in_collection
|
|
637
|
+
@@coll.clear
|
|
638
|
+
|
|
639
|
+
a = {'_id' => '1', 'hello' => 'world'}
|
|
640
|
+
@@coll.save(a)
|
|
641
|
+
assert_equal(1, @@coll.count)
|
|
642
|
+
assert_equal("world", @@coll.find_first()["hello"])
|
|
643
|
+
|
|
644
|
+
a["hello"] = "mike"
|
|
645
|
+
@@coll.save(a)
|
|
646
|
+
assert_equal(1, @@coll.count)
|
|
647
|
+
assert_equal("mike", @@coll.find_first()["hello"])
|
|
648
|
+
end
|
|
649
|
+
|
|
650
|
+
def test_invalid_key_names
|
|
651
|
+
@@coll.clear
|
|
652
|
+
|
|
653
|
+
@@coll.insert({"hello" => "world"})
|
|
654
|
+
@@coll.insert({"hello" => {"hello" => "world"}})
|
|
655
|
+
|
|
656
|
+
assert_raise RuntimeError do
|
|
657
|
+
@@coll.insert({"$hello" => "world"})
|
|
658
|
+
end
|
|
659
|
+
assert_raise RuntimeError do
|
|
660
|
+
@@coll.insert({"hello" => {"$hello" => "world"}})
|
|
661
|
+
end
|
|
662
|
+
|
|
663
|
+
@@coll.insert({"he$llo" => "world"})
|
|
664
|
+
@@coll.insert({"hello" => {"hell$o" => "world"}})
|
|
665
|
+
|
|
666
|
+
assert_raise RuntimeError do
|
|
667
|
+
@@coll.insert({".hello" => "world"})
|
|
668
|
+
end
|
|
669
|
+
assert_raise RuntimeError do
|
|
670
|
+
@@coll.insert({"hello" => {".hello" => "world"}})
|
|
671
|
+
end
|
|
672
|
+
assert_raise RuntimeError do
|
|
673
|
+
@@coll.insert({"hello." => "world"})
|
|
674
|
+
end
|
|
675
|
+
assert_raise RuntimeError do
|
|
676
|
+
@@coll.insert({"hello" => {"hello." => "world"}})
|
|
677
|
+
end
|
|
678
|
+
assert_raise RuntimeError do
|
|
679
|
+
@@coll.insert({"hel.lo" => "world"})
|
|
680
|
+
end
|
|
681
|
+
assert_raise RuntimeError do
|
|
682
|
+
@@coll.insert({"hello" => {"hel.lo" => "world"}})
|
|
683
|
+
end
|
|
684
|
+
|
|
685
|
+
@@coll.modify({"hello" => "world"}, {"$inc" => "hello"})
|
|
686
|
+
end
|
|
687
|
+
|
|
688
|
+
# TODO this test fails with error message "Undefed Before end of object"
|
|
689
|
+
# That is a database error. The undefined type may go away.
|
|
690
|
+
|
|
691
|
+
# def test_insert_undefined
|
|
692
|
+
# doc = {'undef' => Undefined.new}
|
|
693
|
+
# @@coll.clear
|
|
694
|
+
# @@coll.insert(doc)
|
|
695
|
+
# p @@db.error # DEBUG
|
|
696
|
+
# assert_equal 1, @@coll.count
|
|
697
|
+
# row = @@coll.find().next_object
|
|
698
|
+
# assert_not_nil row
|
|
699
|
+
# end
|
|
700
|
+
|
|
701
|
+
end
|