mongo 0.0.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/README.rdoc +134 -0
- data/Rakefile +86 -0
- data/bin/mongo_console +21 -0
- data/lib/mongo.rb +7 -0
- data/lib/mongo/admin.rb +86 -0
- data/lib/mongo/collection.rb +136 -0
- data/lib/mongo/cursor.rb +180 -0
- data/lib/mongo/db.rb +307 -0
- data/lib/mongo/message.rb +4 -0
- data/lib/mongo/message/get_more_message.rb +21 -0
- data/lib/mongo/message/insert_message.rb +19 -0
- data/lib/mongo/message/kill_cursors_message.rb +20 -0
- data/lib/mongo/message/message.rb +68 -0
- data/lib/mongo/message/message_header.rb +34 -0
- data/lib/mongo/message/msg_message.rb +17 -0
- data/lib/mongo/message/opcodes.rb +16 -0
- data/lib/mongo/message/query_message.rb +45 -0
- data/lib/mongo/message/remove_message.rb +20 -0
- data/lib/mongo/message/update_message.rb +21 -0
- data/lib/mongo/mongo.rb +52 -0
- data/lib/mongo/objectid.rb +107 -0
- data/lib/mongo/query.rb +103 -0
- data/lib/mongo/util/bson.rb +339 -0
- data/lib/mongo/util/byte_buffer.rb +163 -0
- data/lib/mongo/util/ordered_hash.rb +54 -0
- data/tests/test_admin.rb +59 -0
- data/tests/test_bson.rb +79 -0
- data/tests/test_byte_buffer.rb +69 -0
- data/tests/test_db_api.rb +357 -0
- data/tests/test_db_connection.rb +17 -0
- data/tests/test_message.rb +35 -0
- data/tests/test_objectid.rb +68 -0
- data/tests/test_ordered_hash.rb +82 -0
- metadata +85 -0
@@ -0,0 +1,54 @@
|
|
1
|
+
# --
|
2
|
+
# Copyright (C) 2008-2009 10gen Inc.
|
3
|
+
#
|
4
|
+
# This program is free software: you can redistribute it and/or modify it
|
5
|
+
# under the terms of the GNU Affero General Public License, version 3, as
|
6
|
+
# published by the Free Software Foundation.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful, but WITHOUT
|
9
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
10
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License
|
11
|
+
# for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU Affero General Public License
|
14
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
# ++
|
16
|
+
|
17
|
+
# A hash in which the order of keys are preserved.
|
18
|
+
class OrderedHash < Hash
|
19
|
+
|
20
|
+
attr_accessor :ordered_keys
|
21
|
+
|
22
|
+
def keys
|
23
|
+
@ordered_keys || []
|
24
|
+
end
|
25
|
+
|
26
|
+
def []=(key, value)
|
27
|
+
@ordered_keys ||= []
|
28
|
+
@ordered_keys << key unless @ordered_keys.include?(key)
|
29
|
+
super(key, value)
|
30
|
+
end
|
31
|
+
|
32
|
+
def each
|
33
|
+
@ordered_keys ||= []
|
34
|
+
@ordered_keys.each { |k| yield k, self[k] }
|
35
|
+
end
|
36
|
+
|
37
|
+
def values
|
38
|
+
collect { |k, v| v }
|
39
|
+
end
|
40
|
+
|
41
|
+
def merge(other)
|
42
|
+
oh = self.dup
|
43
|
+
oh.merge!(other)
|
44
|
+
oh
|
45
|
+
end
|
46
|
+
|
47
|
+
def merge!(other)
|
48
|
+
@ordered_keys ||= []
|
49
|
+
@ordered_keys += other.keys # unordered if not an OrderedHash
|
50
|
+
@ordered_keys.uniq!
|
51
|
+
super(other)
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
data/tests/test_admin.rb
ADDED
@@ -0,0 +1,59 @@
|
|
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 AdminTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
include XGen::Mongo::Driver
|
9
|
+
|
10
|
+
def setup
|
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-test')
|
14
|
+
# Insert some data to make sure the database itself exists.
|
15
|
+
@coll = @db.collection('test')
|
16
|
+
@coll.clear
|
17
|
+
@r1 = @coll.insert('a' => 1) # collection not created until it's used
|
18
|
+
@coll_full_name = 'ruby-mongo-test.test'
|
19
|
+
@admin = @db.admin
|
20
|
+
end
|
21
|
+
|
22
|
+
def teardown
|
23
|
+
unless @db.socket.closed?
|
24
|
+
@admin.profiling_level = :off
|
25
|
+
@coll.clear unless @coll == nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_default_profiling_level
|
30
|
+
assert_equal :off, @admin.profiling_level
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_change_profiling_level
|
34
|
+
@admin.profiling_level = :slow_only
|
35
|
+
assert_equal :slow_only, @admin.profiling_level
|
36
|
+
@admin.profiling_level = :off
|
37
|
+
assert_equal :off, @admin.profiling_level
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_profiling_info
|
41
|
+
# Perform at least one query while profiling so we have something to see.
|
42
|
+
@admin.profiling_level = :all
|
43
|
+
@coll.find()
|
44
|
+
@admin.profiling_level = :off
|
45
|
+
|
46
|
+
info = @admin.profiling_info
|
47
|
+
assert_kind_of Array, info
|
48
|
+
assert info.length >= 1
|
49
|
+
first = info.first
|
50
|
+
assert_kind_of String, first['info']
|
51
|
+
assert_kind_of Time, first['ts']
|
52
|
+
assert_kind_of Numeric, first['millis']
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_validate_collection
|
56
|
+
assert @admin.validate_collection(@coll.name)
|
57
|
+
end
|
58
|
+
|
59
|
+
end
|
data/tests/test_bson.rb
ADDED
@@ -0,0 +1,79 @@
|
|
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 BSONTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
include XGen::Mongo::Driver
|
9
|
+
|
10
|
+
def setup
|
11
|
+
@b = BSON.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def test_string
|
15
|
+
doc = {'doc' => 'hello, world'}
|
16
|
+
@b.serialize(doc)
|
17
|
+
assert_equal doc, @b.deserialize
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_code
|
21
|
+
doc = {'$where' => 'this.a.b < this.b'}
|
22
|
+
@b.serialize(doc)
|
23
|
+
assert_equal doc, @b.deserialize
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_number
|
27
|
+
doc = {'doc' => 41.99}
|
28
|
+
@b.serialize(doc)
|
29
|
+
assert_equal doc, @b.deserialize
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_int
|
33
|
+
doc = {'doc' => 42}
|
34
|
+
@b.serialize(doc)
|
35
|
+
assert_equal doc, @b.deserialize
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_object
|
39
|
+
doc = {'doc' => {'age' => 42, 'name' => 'Spongebob', 'shoe_size' => 9.5}}
|
40
|
+
@b.serialize(doc)
|
41
|
+
assert_equal doc, @b.deserialize
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_oid
|
45
|
+
doc = {'doc' => ObjectID.new}
|
46
|
+
@b.serialize(doc)
|
47
|
+
assert_equal doc, @b.deserialize
|
48
|
+
end
|
49
|
+
|
50
|
+
def test_array
|
51
|
+
doc = {'doc' => [1, 2, 'a', 'b']}
|
52
|
+
@b.serialize(doc)
|
53
|
+
assert_equal doc, @b.deserialize
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_regex
|
57
|
+
doc = {'doc' => /foobar/i}
|
58
|
+
@b.serialize(doc)
|
59
|
+
assert_equal doc, @b.deserialize
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_boolean
|
63
|
+
doc = {'doc' => true}
|
64
|
+
@b.serialize(doc)
|
65
|
+
assert_equal doc, @b.deserialize
|
66
|
+
end
|
67
|
+
|
68
|
+
def test_date
|
69
|
+
doc = {'date' => Time.now}
|
70
|
+
@b.serialize(doc)
|
71
|
+
doc2 = @b.deserialize
|
72
|
+
# Mongo only stores seconds, so comparing raw Time objects will fail
|
73
|
+
# because the fractional seconds will be different.
|
74
|
+
assert_equal doc['date'].to_i, doc2['date'].to_i
|
75
|
+
end
|
76
|
+
|
77
|
+
def test_null
|
78
|
+
end
|
79
|
+
end
|
@@ -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
|
@@ -0,0 +1,357 @@
|
|
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
|
+
|
8
|
+
include XGen::Mongo::Driver
|
9
|
+
|
10
|
+
def setup
|
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-test')
|
14
|
+
@coll = @db.collection('test')
|
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 unless @coll == nil || @db.socket.closed?
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_clear
|
25
|
+
assert_equal 1, @coll.count
|
26
|
+
@coll.clear
|
27
|
+
assert_equal 0, @coll.count
|
28
|
+
end
|
29
|
+
|
30
|
+
def test_insert
|
31
|
+
@coll.insert('a' => 2)
|
32
|
+
@coll.insert('b' => 3)
|
33
|
+
|
34
|
+
assert_equal 3, @coll.count
|
35
|
+
docs = @coll.find().to_a
|
36
|
+
assert_equal 3, docs.length
|
37
|
+
assert docs.detect { |row| row['a'] == 1 }
|
38
|
+
assert docs.detect { |row| row['a'] == 2 }
|
39
|
+
assert docs.detect { |row| row['b'] == 3 }
|
40
|
+
|
41
|
+
@coll << {'b' => 4}
|
42
|
+
docs = @coll.find().to_a
|
43
|
+
assert_equal 4, docs.length
|
44
|
+
assert docs.detect { |row| row['b'] == 4 }
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_find_simple
|
48
|
+
@r2 = @coll.insert('a' => 2)
|
49
|
+
@r3 = @coll.insert('b' => 3)
|
50
|
+
# Check sizes
|
51
|
+
docs = @coll.find().to_a
|
52
|
+
assert_equal 3, docs.size
|
53
|
+
assert_equal 3, @coll.count
|
54
|
+
|
55
|
+
# Find by other value
|
56
|
+
docs = @coll.find('a' => @r1['a']).to_a
|
57
|
+
assert_equal 1, docs.size
|
58
|
+
doc = docs.first
|
59
|
+
assert_equal doc['_id'], @r1['_id']
|
60
|
+
assert_equal doc['a'], @r1['a']
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_find_advanced
|
64
|
+
@coll.insert('a' => 2)
|
65
|
+
@coll.insert('b' => 3)
|
66
|
+
|
67
|
+
# Find by advanced query (less than)
|
68
|
+
docs = @coll.find('a' => { '$lt' => 10 }).to_a
|
69
|
+
assert_equal 2, docs.size
|
70
|
+
assert docs.detect { |row| row['a'] == 1 }
|
71
|
+
assert docs.detect { |row| row['a'] == 2 }
|
72
|
+
|
73
|
+
# Find by advanced query (greater than)
|
74
|
+
docs = @coll.find('a' => { '$gt' => 1 }).to_a
|
75
|
+
assert_equal 1, docs.size
|
76
|
+
assert docs.detect { |row| row['a'] == 2 }
|
77
|
+
|
78
|
+
# Find by advanced query (less than or equal to)
|
79
|
+
docs = @coll.find('a' => { '$lte' => 1 }).to_a
|
80
|
+
assert_equal 1, docs.size
|
81
|
+
assert docs.detect { |row| row['a'] == 1 }
|
82
|
+
|
83
|
+
# Find by advanced query (greater than or equal to)
|
84
|
+
docs = @coll.find('a' => { '$gte' => 1 }).to_a
|
85
|
+
assert_equal 2, docs.size
|
86
|
+
assert docs.detect { |row| row['a'] == 1 }
|
87
|
+
assert docs.detect { |row| row['a'] == 2 }
|
88
|
+
|
89
|
+
# Find by advanced query (between)
|
90
|
+
docs = @coll.find('a' => { '$gt' => 1, '$lt' => 3 }).to_a
|
91
|
+
assert_equal 1, docs.size
|
92
|
+
assert docs.detect { |row| row['a'] == 2 }
|
93
|
+
|
94
|
+
# Find by advanced query (in clause)
|
95
|
+
docs = @coll.find('a' => {'$in' => [1,2]}).to_a
|
96
|
+
assert_equal 2, docs.size
|
97
|
+
assert docs.detect { |row| row['a'] == 1 }
|
98
|
+
assert docs.detect { |row| row['a'] == 2 }
|
99
|
+
|
100
|
+
# Find by advanced query (regexp)
|
101
|
+
docs = @coll.find('a' => /[1|2]/).to_a
|
102
|
+
assert_equal 2, docs.size
|
103
|
+
assert docs.detect { |row| row['a'] == 1 }
|
104
|
+
assert docs.detect { |row| row['a'] == 2 }
|
105
|
+
end
|
106
|
+
|
107
|
+
def test_find_sorting
|
108
|
+
@coll.clear
|
109
|
+
@coll.insert('a' => 1, 'b' => 2)
|
110
|
+
@coll.insert('a' => 2, 'b' => 1)
|
111
|
+
@coll.insert('a' => 3, 'b' => 2)
|
112
|
+
@coll.insert('a' => 4, 'b' => 1)
|
113
|
+
|
114
|
+
# Sorting (ascending)
|
115
|
+
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => {'a' => 1}).to_a
|
116
|
+
assert_equal 4, docs.size
|
117
|
+
assert_equal 1, docs[0]['a']
|
118
|
+
assert_equal 2, docs[1]['a']
|
119
|
+
assert_equal 3, docs[2]['a']
|
120
|
+
assert_equal 4, docs[3]['a']
|
121
|
+
|
122
|
+
# Sorting (descending)
|
123
|
+
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => {'a' => -1}).to_a
|
124
|
+
assert_equal 4, docs.size
|
125
|
+
assert_equal 4, docs[0]['a']
|
126
|
+
assert_equal 3, docs[1]['a']
|
127
|
+
assert_equal 2, docs[2]['a']
|
128
|
+
assert_equal 1, docs[3]['a']
|
129
|
+
|
130
|
+
# Sorting using array of names; assumes ascending order.
|
131
|
+
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => ['a']).to_a
|
132
|
+
assert_equal 4, docs.size
|
133
|
+
assert_equal 1, docs[0]['a']
|
134
|
+
assert_equal 2, docs[1]['a']
|
135
|
+
assert_equal 3, docs[2]['a']
|
136
|
+
assert_equal 4, docs[3]['a']
|
137
|
+
|
138
|
+
# Sorting using single name; assumes ascending order.
|
139
|
+
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => 'a').to_a
|
140
|
+
assert_equal 4, docs.size
|
141
|
+
assert_equal 1, docs[0]['a']
|
142
|
+
assert_equal 2, docs[1]['a']
|
143
|
+
assert_equal 3, docs[2]['a']
|
144
|
+
assert_equal 4, docs[3]['a']
|
145
|
+
|
146
|
+
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => ['b', 'a']).to_a
|
147
|
+
assert_equal 4, docs.size
|
148
|
+
assert_equal 2, docs[0]['a']
|
149
|
+
assert_equal 4, docs[1]['a']
|
150
|
+
assert_equal 1, docs[2]['a']
|
151
|
+
assert_equal 3, docs[3]['a']
|
152
|
+
|
153
|
+
# Sorting using empty array; no order guarantee but should not blow up.
|
154
|
+
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => []).to_a
|
155
|
+
assert_equal 4, docs.size
|
156
|
+
|
157
|
+
# Sorting using ordered hash. You can use an unordered one, but then the
|
158
|
+
# order of the keys won't be guaranteed thus your sort won't make sense.
|
159
|
+
oh = OrderedHash.new
|
160
|
+
oh['a'] = -1
|
161
|
+
docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a
|
162
|
+
assert_equal 4, docs.size
|
163
|
+
assert_equal 4, docs[0]['a']
|
164
|
+
assert_equal 3, docs[1]['a']
|
165
|
+
assert_equal 2, docs[2]['a']
|
166
|
+
assert_equal 1, docs[3]['a']
|
167
|
+
|
168
|
+
# TODO this will not pass due to known Mongo bug #898
|
169
|
+
# oh = OrderedHash.new
|
170
|
+
# oh['b'] = -1
|
171
|
+
# oh['a'] = 1
|
172
|
+
# docs = @coll.find({'a' => { '$lt' => 10 }}, :sort => oh).to_a
|
173
|
+
# assert_equal 4, docs.size
|
174
|
+
# assert_equal 1, docs[0]['a']
|
175
|
+
# assert_equal 3, docs[1]['a']
|
176
|
+
# assert_equal 2, docs[2]['a']
|
177
|
+
# assert_equal 4, docs[3]['a']
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_find_limits
|
181
|
+
@coll.insert('b' => 2)
|
182
|
+
@coll.insert('c' => 3)
|
183
|
+
@coll.insert('d' => 4)
|
184
|
+
|
185
|
+
docs = @coll.find({}, :limit => 1).to_a
|
186
|
+
assert_equal 1, docs.size
|
187
|
+
docs = @coll.find({}, :limit => 2).to_a
|
188
|
+
assert_equal 2, docs.size
|
189
|
+
docs = @coll.find({}, :limit => 3).to_a
|
190
|
+
assert_equal 3, docs.size
|
191
|
+
docs = @coll.find({}, :limit => 4).to_a
|
192
|
+
assert_equal 4, docs.size
|
193
|
+
docs = @coll.find({}).to_a
|
194
|
+
assert_equal 4, docs.size
|
195
|
+
docs = @coll.find({}, :limit => 99).to_a
|
196
|
+
assert_equal 4, docs.size
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_close
|
200
|
+
@db.close
|
201
|
+
assert @db.socket.closed?
|
202
|
+
begin
|
203
|
+
@coll.insert('a' => 1)
|
204
|
+
fail "expected IOError exception"
|
205
|
+
rescue IOError => ex
|
206
|
+
assert_match /closed stream/, ex.to_s
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
def test_drop_collection
|
211
|
+
assert @db.drop_collection(@coll.name), "drop of collection #{@coll.name} failed"
|
212
|
+
assert !@db.collection_names.include?(@coll_full_name)
|
213
|
+
@coll = nil
|
214
|
+
end
|
215
|
+
|
216
|
+
def test_collection_names
|
217
|
+
names = @db.collection_names
|
218
|
+
assert names.length >= 1
|
219
|
+
assert names.include?(@coll_full_name)
|
220
|
+
|
221
|
+
coll2 = @db.collection('test2')
|
222
|
+
coll2.insert('a' => 1) # collection not created until it's used
|
223
|
+
names = @db.collection_names
|
224
|
+
assert names.length >= 2
|
225
|
+
assert names.include?(@coll_full_name)
|
226
|
+
assert names.include?('ruby-mongo-test.test2')
|
227
|
+
ensure
|
228
|
+
@db.drop_collection('test2')
|
229
|
+
end
|
230
|
+
|
231
|
+
def test_collections_info
|
232
|
+
cursor = @db.collections_info
|
233
|
+
rows = cursor.to_a
|
234
|
+
assert rows.length >= 1
|
235
|
+
row = rows.detect { |r| r['name'] == @coll_full_name }
|
236
|
+
assert_not_nil row
|
237
|
+
assert_equal @coll.name, row['options']['create']
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_collection_options
|
241
|
+
@db.drop_collection('foobar')
|
242
|
+
@db.strict = true
|
243
|
+
|
244
|
+
begin
|
245
|
+
coll = @db.create_collection('foobar', :capped => true, :size => 1024)
|
246
|
+
options = coll.options()
|
247
|
+
assert_equal 'foobar', options['create']
|
248
|
+
assert_equal true, options['capped']
|
249
|
+
assert_equal 1024, options['size']
|
250
|
+
rescue => ex
|
251
|
+
@db.drop_collection('foobar')
|
252
|
+
fail "did not expect exception \"#{ex}\""
|
253
|
+
end
|
254
|
+
end
|
255
|
+
|
256
|
+
def test_full_coll_name
|
257
|
+
assert_equal @coll_full_name, @db.full_coll_name(@coll.name)
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_index_information
|
261
|
+
@db.create_index(@coll.name, 'index_name', ['a'])
|
262
|
+
list = @db.index_information(@coll.name)
|
263
|
+
assert_equal 1, list.length
|
264
|
+
|
265
|
+
info = list[0]
|
266
|
+
assert_equal 'index_name', info[:name]
|
267
|
+
assert_equal 1, info[:keys]['a']
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_array
|
271
|
+
@coll << {'b' => [1, 2, 3]}
|
272
|
+
rows = @coll.find({}, {:fields => ['b']}).to_a
|
273
|
+
assert_equal 1, rows.length
|
274
|
+
assert_equal [1, 2, 3], rows[0]['b']
|
275
|
+
end
|
276
|
+
|
277
|
+
def test_regex
|
278
|
+
regex = /foobar/i
|
279
|
+
@coll << {'b' => regex}
|
280
|
+
rows = @coll.find({}, {:fields => ['b']}).to_a
|
281
|
+
assert_equal 1, rows.length
|
282
|
+
assert_equal regex, rows[0]['b']
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_strict
|
286
|
+
assert !@db.strict?
|
287
|
+
@db.strict = true
|
288
|
+
assert @db.strict?
|
289
|
+
end
|
290
|
+
|
291
|
+
def test_strict_access_collection
|
292
|
+
@db.strict = true
|
293
|
+
begin
|
294
|
+
@db.collection('does-not-exist')
|
295
|
+
fail "expected exception"
|
296
|
+
rescue => ex
|
297
|
+
assert_equal "Collection does-not-exist doesn't exist. Currently in strict mode.", ex.to_s
|
298
|
+
ensure
|
299
|
+
@db.strict = false
|
300
|
+
@db.drop_collection('does-not-exist')
|
301
|
+
end
|
302
|
+
end
|
303
|
+
|
304
|
+
def test_strict_create_collection
|
305
|
+
@db.drop_collection('foobar')
|
306
|
+
@db.strict = true
|
307
|
+
|
308
|
+
begin
|
309
|
+
@db.create_collection('foobar')
|
310
|
+
assert true
|
311
|
+
rescue => ex
|
312
|
+
fail "did not expect exception \"#{ex}\""
|
313
|
+
end
|
314
|
+
|
315
|
+
# Now the collection exists. This time we should see an exception.
|
316
|
+
begin
|
317
|
+
@db.create_collection('foobar')
|
318
|
+
fail "expected exception"
|
319
|
+
rescue => ex
|
320
|
+
assert_equal "Collection foobar already exists. Currently in strict mode.", ex.to_s
|
321
|
+
ensure
|
322
|
+
@db.strict = false
|
323
|
+
@db.drop_collection('foobar')
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
def test_to_a
|
328
|
+
cursor = @coll.find()
|
329
|
+
rows = cursor.to_a
|
330
|
+
|
331
|
+
# Make sure we get back exactly the same array the next time we ask
|
332
|
+
rows2 = cursor.to_a
|
333
|
+
assert_same rows, rows2
|
334
|
+
|
335
|
+
# Make sure we can still iterate after calling to_a
|
336
|
+
rows_with_each = cursor.collect{|row| row}
|
337
|
+
assert_equal rows, rows_with_each
|
338
|
+
|
339
|
+
# Make sure we can iterate more than once after calling to_a
|
340
|
+
end
|
341
|
+
|
342
|
+
def test_to_a_after_each
|
343
|
+
cursor = @coll.find
|
344
|
+
cursor.each { |row| row }
|
345
|
+
begin
|
346
|
+
cursor.to_a
|
347
|
+
fail "expected \"can't call\" error"
|
348
|
+
rescue => ex
|
349
|
+
assert_equal "can't call Cursor#to_a after calling Cursor#each", ex.to_s
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
def test_ismaster
|
354
|
+
assert @db.master?
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|