mongo 1.10.0-java

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.
Files changed (116) hide show
  1. checksums.yaml +7 -0
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +190 -0
  5. data/README.md +149 -0
  6. data/Rakefile +31 -0
  7. data/VERSION +1 -0
  8. data/bin/mongo_console +43 -0
  9. data/ext/jsasl/target/jsasl.jar +0 -0
  10. data/lib/mongo.rb +90 -0
  11. data/lib/mongo/bulk_write_collection_view.rb +380 -0
  12. data/lib/mongo/collection.rb +1164 -0
  13. data/lib/mongo/collection_writer.rb +364 -0
  14. data/lib/mongo/connection.rb +19 -0
  15. data/lib/mongo/connection/node.rb +239 -0
  16. data/lib/mongo/connection/pool.rb +347 -0
  17. data/lib/mongo/connection/pool_manager.rb +325 -0
  18. data/lib/mongo/connection/sharding_pool_manager.rb +67 -0
  19. data/lib/mongo/connection/socket.rb +18 -0
  20. data/lib/mongo/connection/socket/socket_util.rb +37 -0
  21. data/lib/mongo/connection/socket/ssl_socket.rb +95 -0
  22. data/lib/mongo/connection/socket/tcp_socket.rb +86 -0
  23. data/lib/mongo/connection/socket/unix_socket.rb +39 -0
  24. data/lib/mongo/cursor.rb +719 -0
  25. data/lib/mongo/db.rb +735 -0
  26. data/lib/mongo/exception.rb +88 -0
  27. data/lib/mongo/functional.rb +21 -0
  28. data/lib/mongo/functional/authentication.rb +318 -0
  29. data/lib/mongo/functional/logging.rb +85 -0
  30. data/lib/mongo/functional/read_preference.rb +174 -0
  31. data/lib/mongo/functional/sasl_java.rb +48 -0
  32. data/lib/mongo/functional/uri_parser.rb +374 -0
  33. data/lib/mongo/functional/write_concern.rb +66 -0
  34. data/lib/mongo/gridfs.rb +18 -0
  35. data/lib/mongo/gridfs/grid.rb +112 -0
  36. data/lib/mongo/gridfs/grid_ext.rb +53 -0
  37. data/lib/mongo/gridfs/grid_file_system.rb +163 -0
  38. data/lib/mongo/gridfs/grid_io.rb +484 -0
  39. data/lib/mongo/legacy.rb +140 -0
  40. data/lib/mongo/mongo_client.rb +702 -0
  41. data/lib/mongo/mongo_replica_set_client.rb +523 -0
  42. data/lib/mongo/mongo_sharded_client.rb +159 -0
  43. data/lib/mongo/networking.rb +370 -0
  44. data/lib/mongo/utils.rb +19 -0
  45. data/lib/mongo/utils/conversions.rb +110 -0
  46. data/lib/mongo/utils/core_ext.rb +70 -0
  47. data/lib/mongo/utils/server_version.rb +69 -0
  48. data/lib/mongo/utils/support.rb +80 -0
  49. data/lib/mongo/utils/thread_local_variable_manager.rb +25 -0
  50. data/mongo.gemspec +36 -0
  51. data/test/functional/authentication_test.rb +35 -0
  52. data/test/functional/bulk_api_stress_test.rb +133 -0
  53. data/test/functional/bulk_write_collection_view_test.rb +1129 -0
  54. data/test/functional/client_test.rb +565 -0
  55. data/test/functional/collection_test.rb +2073 -0
  56. data/test/functional/collection_writer_test.rb +83 -0
  57. data/test/functional/conversions_test.rb +163 -0
  58. data/test/functional/cursor_fail_test.rb +63 -0
  59. data/test/functional/cursor_message_test.rb +57 -0
  60. data/test/functional/cursor_test.rb +625 -0
  61. data/test/functional/db_api_test.rb +819 -0
  62. data/test/functional/db_connection_test.rb +27 -0
  63. data/test/functional/db_test.rb +344 -0
  64. data/test/functional/grid_file_system_test.rb +285 -0
  65. data/test/functional/grid_io_test.rb +252 -0
  66. data/test/functional/grid_test.rb +273 -0
  67. data/test/functional/pool_test.rb +62 -0
  68. data/test/functional/safe_test.rb +98 -0
  69. data/test/functional/ssl_test.rb +29 -0
  70. data/test/functional/support_test.rb +62 -0
  71. data/test/functional/timeout_test.rb +58 -0
  72. data/test/functional/uri_test.rb +330 -0
  73. data/test/functional/write_concern_test.rb +118 -0
  74. data/test/helpers/general.rb +50 -0
  75. data/test/helpers/test_unit.rb +317 -0
  76. data/test/replica_set/authentication_test.rb +35 -0
  77. data/test/replica_set/basic_test.rb +174 -0
  78. data/test/replica_set/client_test.rb +341 -0
  79. data/test/replica_set/complex_connect_test.rb +77 -0
  80. data/test/replica_set/connection_test.rb +138 -0
  81. data/test/replica_set/count_test.rb +64 -0
  82. data/test/replica_set/cursor_test.rb +212 -0
  83. data/test/replica_set/insert_test.rb +140 -0
  84. data/test/replica_set/max_values_test.rb +145 -0
  85. data/test/replica_set/pinning_test.rb +55 -0
  86. data/test/replica_set/query_test.rb +73 -0
  87. data/test/replica_set/read_preference_test.rb +214 -0
  88. data/test/replica_set/refresh_test.rb +175 -0
  89. data/test/replica_set/replication_ack_test.rb +94 -0
  90. data/test/replica_set/ssl_test.rb +32 -0
  91. data/test/sharded_cluster/basic_test.rb +197 -0
  92. data/test/shared/authentication/basic_auth_shared.rb +286 -0
  93. data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
  94. data/test/shared/authentication/gssapi_shared.rb +164 -0
  95. data/test/shared/authentication/sasl_plain_shared.rb +96 -0
  96. data/test/shared/ssl_shared.rb +235 -0
  97. data/test/test_helper.rb +56 -0
  98. data/test/threading/basic_test.rb +120 -0
  99. data/test/tools/mongo_config.rb +608 -0
  100. data/test/tools/mongo_config_test.rb +160 -0
  101. data/test/unit/client_test.rb +347 -0
  102. data/test/unit/collection_test.rb +166 -0
  103. data/test/unit/connection_test.rb +325 -0
  104. data/test/unit/cursor_test.rb +299 -0
  105. data/test/unit/db_test.rb +136 -0
  106. data/test/unit/grid_test.rb +76 -0
  107. data/test/unit/mongo_sharded_client_test.rb +48 -0
  108. data/test/unit/node_test.rb +93 -0
  109. data/test/unit/pool_manager_test.rb +142 -0
  110. data/test/unit/read_pref_test.rb +115 -0
  111. data/test/unit/read_test.rb +159 -0
  112. data/test/unit/safe_test.rb +158 -0
  113. data/test/unit/sharding_pool_manager_test.rb +84 -0
  114. data/test/unit/write_concern_test.rb +175 -0
  115. metadata +260 -0
  116. metadata.gz.sig +0 -0
@@ -0,0 +1,83 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License")
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'test_helper'
16
+
17
+ module Mongo
18
+ class Collection
19
+ public :batch_write
20
+ end
21
+ class CollectionWriter
22
+ public :sort_by_first_sym, :ordered_group_by_first
23
+ end
24
+ end
25
+
26
+ class CollectionWriterTest < Test::Unit::TestCase
27
+
28
+ DATABASE_NAME = 'ruby_test_collection_writer'
29
+ COLLECTION_NAME = 'test'
30
+
31
+ def default_setup
32
+ @client = MongoClient.new
33
+ @db = @client[DATABASE_NAME]
34
+ @collection = @db[COLLECTION_NAME]
35
+ @collection.drop
36
+ end
37
+
38
+ context "Bulk API Execute" do
39
+ setup do
40
+ default_setup
41
+ end
42
+
43
+ should "sort_by_first_sym for grouping unordered ops" do
44
+ pairs = [
45
+ [:insert, {:n => 0}],
46
+ [:update, {:n => 1}], [:update, {:n => 2}],
47
+ [:delete, {:n => 3}],
48
+ [:insert, {:n => 5}], [:insert, {:n => 6}], [:insert, {:n => 7}],
49
+ [:update, {:n => 8}],
50
+ [:delete, {:n => 9}], [:delete, {:n => 10}]
51
+ ]
52
+ result = @collection.command_writer.sort_by_first_sym(pairs)
53
+ expected = [
54
+ :delete, :delete, :delete,
55
+ :insert, :insert, :insert, :insert,
56
+ :update, :update, :update
57
+ ]
58
+ assert_equal expected, result.collect{|first, rest| first}
59
+ end
60
+
61
+ should "calculate ordered_group_by_first" do
62
+ pairs = [
63
+ [:insert, {:n => 0}],
64
+ [:update, {:n => 1}], [:update, {:n => 2}],
65
+ [:delete, {:n => 3}],
66
+ [:insert, {:n => 5}], [:insert, {:n => 6}], [:insert, {:n => 7}],
67
+ [:update, {:n => 8}],
68
+ [:delete, {:n => 9}], [:delete, {:n => 10}]
69
+ ]
70
+ result = @collection.command_writer.ordered_group_by_first(pairs)
71
+ expected = [
72
+ [:insert, [{:n => 0}]],
73
+ [:update, [{:n => 1}, {:n => 2}]],
74
+ [:delete, [{:n => 3}]],
75
+ [:insert, [{:n => 5}, {:n => 6}, {:n => 7}]],
76
+ [:update, [{:n => 8}]],
77
+ [:delete, [{:n => 9}, {:n => 10}]]
78
+ ]
79
+ assert_equal expected, result
80
+ end
81
+
82
+ end
83
+ end
@@ -0,0 +1,163 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'test_helper'
16
+
17
+ class ConversionsTest < Test::Unit::TestCase
18
+ include Mongo::Conversions
19
+
20
+ def test_array_as_sort_parameters_with_array_of_key_and_value
21
+ params = array_as_sort_parameters(["field1", "asc"])
22
+ assert_equal({"field1" => 1}, params)
23
+ end
24
+
25
+ def test_array_as_sort_parameters_with_array_of_string_and_values
26
+ params = array_as_sort_parameters([["field1", :asc], ["field2", :desc]])
27
+ assert_equal({ "field1" => 1, "field2" => -1 }, params)
28
+ end
29
+
30
+ def test_array_as_sort_parameters_with_array_of_key_and_hash
31
+ params = array_as_sort_parameters(["score", {"$meta" => "textScore"}])
32
+ assert_equal({"score" => {"$meta" => "textScore"}}, params)
33
+ end
34
+
35
+ def test_array_as_sort_parameters_with_array_of_key_and_hashes
36
+ params = array_as_sort_parameters([["field1", :asc],["score", {"$meta" => "textScore"}]])
37
+ assert_equal({"field1" => 1, "score" => {"$meta" => "textScore"}}, params)
38
+ end
39
+
40
+ def test_hash_as_sort_parameters_with_string
41
+ sort = BSON::OrderedHash["field", "asc"]
42
+ params = hash_as_sort_parameters(sort)
43
+ assert_equal({"field" => 1}, params)
44
+ end
45
+
46
+ def test_hash_as_sort_parameters_with_hash
47
+ sort = BSON::OrderedHash["score", {"$meta" => "textScore"}]
48
+ params = hash_as_sort_parameters(sort)
49
+ assert_equal({"score" => {"$meta" => "textScore"}}, params)
50
+ end
51
+
52
+ def test_hash_as_sort_parameters_with_hash_and_string
53
+ sort = BSON::OrderedHash["score", {"$meta" => "textScore"}, "field", "asc"]
54
+ params = hash_as_sort_parameters(sort)
55
+ assert_equal({ "score" => {"$meta" => "textScore"}, "field" => 1 }, params)
56
+ end
57
+
58
+ def test_string_as_sort_parameters_with_string
59
+ params = string_as_sort_parameters("field")
60
+ assert_equal({ "field" => 1 }, params)
61
+ end
62
+
63
+ def test_string_as_sort_parameters_with_empty_string
64
+ params = string_as_sort_parameters("")
65
+ assert_equal({}, params)
66
+ end
67
+
68
+ def test_symbol_as_sort_parameters
69
+ params = string_as_sort_parameters(:field)
70
+ assert_equal({ "field" => 1 }, params)
71
+ end
72
+
73
+ def test_sort_value_when_value_is_one
74
+ assert_equal 1, sort_value(1)
75
+ end
76
+
77
+ def test_sort_value_when_value_is_one_as_a_string
78
+ assert_equal 1, sort_value("1")
79
+ end
80
+
81
+ def test_sort_value_when_value_is_negative_one
82
+ assert_equal(-1, sort_value(-1))
83
+ end
84
+
85
+ def test_sort_value_when_value_is_negative_one_as_a_string
86
+ assert_equal(-1, sort_value("-1"))
87
+ end
88
+
89
+ def test_sort_value_when_value_is_ascending
90
+ assert_equal 1, sort_value("ascending")
91
+ end
92
+
93
+ def test_sort_value_when_value_is_asc
94
+ assert_equal 1, sort_value("asc")
95
+ end
96
+
97
+ def test_sort_value_when_value_is_uppercase_ascending
98
+ assert_equal 1, sort_value("ASCENDING")
99
+ end
100
+
101
+ def test_sort_value_when_value_is_uppercase_asc
102
+ assert_equal 1, sort_value("ASC")
103
+ end
104
+
105
+ def test_sort_value_when_value_is_symbol_ascending
106
+ assert_equal 1, sort_value(:ascending)
107
+ end
108
+
109
+ def test_sort_value_when_value_is_symbol_asc
110
+ assert_equal 1, sort_value(:asc)
111
+ end
112
+
113
+ def test_sort_value_when_value_is_symbol_uppercase_ascending
114
+ assert_equal 1, sort_value(:ASCENDING)
115
+ end
116
+
117
+ def test_sort_value_when_value_is_symbol_uppercase_asc
118
+ assert_equal 1, sort_value(:ASC)
119
+ end
120
+
121
+ def test_sort_value_when_value_is_descending
122
+ assert_equal(-1, sort_value("descending"))
123
+ end
124
+
125
+ def test_sort_value_when_value_is_desc
126
+ assert_equal(-1, sort_value("desc"))
127
+ end
128
+
129
+ def test_sort_value_when_value_is_uppercase_descending
130
+ assert_equal(-1, sort_value("DESCENDING"))
131
+ end
132
+
133
+ def test_sort_value_when_value_is_uppercase_desc
134
+ assert_equal(-1, sort_value("DESC"))
135
+ end
136
+
137
+ def test_sort_value_when_value_is_symbol_descending
138
+ assert_equal(-1, sort_value(:descending))
139
+ end
140
+
141
+ def test_sort_value_when_value_is_symbol_desc
142
+ assert_equal(-1, sort_value(:desc))
143
+ end
144
+
145
+ def test_sort_value_when_value_is_uppercase_symbol_descending
146
+ assert_equal(-1, sort_value(:DESCENDING))
147
+ end
148
+
149
+ def test_sort_value_when_value_is_uppercase_symbol_desc
150
+ assert_equal(-1, sort_value(:DESC))
151
+ end
152
+
153
+ def test_sort_value_when_value_is_hash
154
+ assert_equal({"$meta" => "textScore"}, sort_value("$meta" => "textScore"))
155
+ end
156
+
157
+ def test_sort_value_when_value_is_invalid
158
+ assert_raise Mongo::InvalidSortValueError do
159
+ sort_value(2)
160
+ end
161
+ end
162
+
163
+ end
@@ -0,0 +1,63 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'test_helper'
16
+ require 'logger'
17
+
18
+ class CursorFailTest < Test::Unit::TestCase
19
+
20
+ include Mongo
21
+
22
+ @@connection = standard_connection
23
+ @@db = @@connection.db(TEST_DB)
24
+ @@coll = @@db.collection('test')
25
+ @@version = @@connection.server_version
26
+
27
+ def setup
28
+ @@coll.remove({})
29
+ @@coll.insert({'a' => 1}) # collection not created until it's used
30
+ @@coll_full_name = "#{TEST_DB}.test"
31
+ end
32
+
33
+ def test_refill_via_get_more_alt_coll
34
+ coll = @@db.collection('test-alt-coll')
35
+ coll.remove
36
+ coll.insert('a' => 1) # collection not created until it's used
37
+ assert_equal 1, coll.count
38
+
39
+ 1000.times { |i|
40
+ assert_equal 1 + i, coll.count
41
+ coll.insert('a' => i)
42
+ }
43
+
44
+ assert_equal 1001, coll.count
45
+ count = 0
46
+ coll.find.each { |obj|
47
+ count += obj['a']
48
+ }
49
+ assert_equal 1001, coll.count
50
+
51
+ # do the same thing again for debugging
52
+ assert_equal 1001, coll.count
53
+ count2 = 0
54
+ coll.find.each { |obj|
55
+ count2 += obj['a']
56
+ }
57
+ assert_equal 1001, coll.count
58
+
59
+ assert_equal count, count2
60
+ assert_equal 499501, count
61
+ end
62
+
63
+ end
@@ -0,0 +1,57 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'test_helper'
16
+ require 'logger'
17
+
18
+ class CursorMessageTest < Test::Unit::TestCase
19
+
20
+ include Mongo
21
+
22
+ @@connection = standard_connection
23
+ @@db = @@connection.db(TEST_DB)
24
+ @@coll = @@db.collection('test')
25
+ @@version = @@connection.server_version
26
+
27
+ def setup
28
+ @@coll.remove
29
+ @@coll.insert('a' => 1) # collection not created until it's used
30
+ @@coll_full_name = "#{TEST_DB}.test"
31
+ end
32
+
33
+ def test_valid_batch_sizes
34
+ assert_raise ArgumentError do
35
+ @@coll.find({}, :batch_size => 1, :limit => 5)
36
+ end
37
+
38
+ assert_raise ArgumentError do
39
+ @@coll.find({}, :batch_size => -1, :limit => 5)
40
+ end
41
+
42
+ assert @@coll.find({}, :batch_size => 0, :limit => 5)
43
+ end
44
+
45
+ def test_batch_size
46
+ @@coll.remove
47
+ 200.times do |n|
48
+ @@coll.insert({:a => n})
49
+ end
50
+
51
+ list = @@coll.find({}, :batch_size => 2, :limit => 6).to_a
52
+ assert_equal 6, list.length
53
+
54
+ list = @@coll.find({}, :batch_size => 100, :limit => 101).to_a
55
+ assert_equal 101, list.length
56
+ end
57
+ end
@@ -0,0 +1,625 @@
1
+ # Copyright (C) 2009-2013 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'test_helper'
16
+ require 'logger'
17
+
18
+ class CursorTest < Test::Unit::TestCase
19
+ include Mongo
20
+ include Mongo::Constants
21
+
22
+ @@connection = standard_connection
23
+ @@db = @@connection.db(TEST_DB)
24
+ @@coll = @@db.collection('test')
25
+ @@version = @@connection.server_version
26
+
27
+ def setup
28
+ @@coll.remove
29
+ @@coll.insert('a' => 1) # collection not created until it's used
30
+ @@coll_full_name = "#{TEST_DB}.test"
31
+ end
32
+
33
+ def test_alive
34
+ batch = []
35
+ 5000.times do |n|
36
+ batch << {:a => n}
37
+ end
38
+
39
+ @@coll.insert(batch)
40
+ cursor = @@coll.find
41
+ assert !cursor.alive?
42
+ cursor.next
43
+ assert cursor.alive?
44
+ cursor.close
45
+ assert !cursor.alive?
46
+ @@coll.remove
47
+ end
48
+
49
+ def test_add_and_remove_options
50
+ c = @@coll.find
51
+ assert_equal 0, c.options & OP_QUERY_EXHAUST
52
+ c.add_option(OP_QUERY_EXHAUST)
53
+ assert_equal OP_QUERY_EXHAUST, c.options & OP_QUERY_EXHAUST
54
+ c.remove_option(OP_QUERY_EXHAUST)
55
+ assert_equal 0, c.options & OP_QUERY_EXHAUST
56
+
57
+ c.next
58
+ assert_raise Mongo::InvalidOperation do
59
+ c.add_option(OP_QUERY_EXHAUST)
60
+ end
61
+
62
+ assert_raise Mongo::InvalidOperation do
63
+ c.add_option(OP_QUERY_EXHAUST)
64
+ end
65
+ end
66
+
67
+ def test_exhaust
68
+ if @@version >= "2.0"
69
+ @@coll.remove
70
+ data = "1" * 10_000
71
+ 5000.times do |n|
72
+ @@coll.insert({:n => n, :data => data})
73
+ end
74
+
75
+ c = Cursor.new(@@coll)
76
+ c.add_option(OP_QUERY_EXHAUST)
77
+ assert_equal @@coll.count, c.to_a.size
78
+ assert c.closed?
79
+
80
+ c = Cursor.new(@@coll)
81
+ c.add_option(OP_QUERY_EXHAUST)
82
+ 4999.times do
83
+ c.next
84
+ end
85
+ assert c.has_next?
86
+ assert c.next
87
+ assert !c.has_next?
88
+ assert c.closed?
89
+
90
+ @@coll.remove
91
+ end
92
+ end
93
+
94
+ def test_compile_regex_get_more
95
+ return unless defined?(BSON::BSON_RUBY) && BSON::BSON_CODER == BSON::BSON_RUBY
96
+ @@coll.remove
97
+ n_docs = 3
98
+ n_docs.times { |n| @@coll.insert({ 'n' => /.*/ }) }
99
+ cursor = @@coll.find({}, :batch_size => (n_docs-1), :compile_regex => false)
100
+ cursor.expects(:send_get_more)
101
+ cursor.to_a.each do |doc|
102
+ assert_kind_of BSON::Regex, doc['n']
103
+ end
104
+ end
105
+
106
+ def test_max_time_ms_error
107
+ cursor = @@coll.find
108
+ cursor.stubs(:send_initial_query).returns(true)
109
+
110
+ cursor.instance_variable_set(:@cache, [{
111
+ '$err' => 'operation exceeded time limit',
112
+ 'code' => 50
113
+ }])
114
+
115
+ assert_raise ExecutionTimeout do
116
+ cursor.to_a
117
+ end
118
+ end
119
+
120
+ def test_max_time_ms
121
+ with_forced_timeout(@@connection) do
122
+ assert_raise ExecutionTimeout do
123
+ cursor = @@coll.find.max_time_ms(100)
124
+ cursor.to_a
125
+ end
126
+ end
127
+ end
128
+
129
+ def test_exhaust_after_limit_error
130
+ c = Cursor.new(@@coll, :limit => 17)
131
+ assert_raise MongoArgumentError do
132
+ c.add_option(OP_QUERY_EXHAUST)
133
+ end
134
+
135
+ assert_raise MongoArgumentError do
136
+ c.add_option(OP_QUERY_EXHAUST + OP_QUERY_SLAVE_OK)
137
+ end
138
+ end
139
+
140
+ def test_limit_after_exhaust_error
141
+ c = Cursor.new(@@coll)
142
+ c.add_option(OP_QUERY_EXHAUST)
143
+ assert_raise MongoArgumentError do
144
+ c.limit(17)
145
+ end
146
+ end
147
+
148
+ def test_exhaust_with_mongos
149
+ @@connection.expects(:mongos?).returns(:true)
150
+ c = Cursor.new(@@coll)
151
+
152
+ assert_raise MongoArgumentError do
153
+ c.add_option(OP_QUERY_EXHAUST)
154
+ end
155
+ end
156
+
157
+ def test_inspect
158
+ selector = {:a => 1}
159
+ cursor = @@coll.find(selector)
160
+ assert_equal "<Mongo::Cursor:0x#{cursor.object_id.to_s(16)} namespace='#{@@db.name}.#{@@coll.name}' " +
161
+ "@selector=#{selector.inspect} @cursor_id=#{cursor.cursor_id}>", cursor.inspect
162
+ end
163
+
164
+ def test_explain
165
+ cursor = @@coll.find('a' => 1)
166
+ explaination = cursor.explain
167
+ assert_not_nil explaination['cursor']
168
+ assert_kind_of Numeric, explaination['n']
169
+ assert_kind_of Numeric, explaination['millis']
170
+ assert_kind_of Numeric, explaination['nscanned']
171
+ end
172
+
173
+ def test_each_with_no_block
174
+ assert_kind_of(Enumerator, @@coll.find().each) if defined? Enumerator
175
+ end
176
+
177
+ def test_count
178
+ @@coll.remove
179
+
180
+ assert_equal 0, @@coll.find().count()
181
+
182
+ 10.times do |i|
183
+ @@coll.save("x" => i)
184
+ end
185
+
186
+ assert_equal 10, @@coll.find().count()
187
+ assert_kind_of Integer, @@coll.find().count()
188
+ assert_equal 10, @@coll.find({}, :limit => 5).count()
189
+ assert_equal 10, @@coll.find({}, :skip => 5).count()
190
+
191
+ assert_equal 5, @@coll.find({}, :limit => 5).count(true)
192
+ assert_equal 5, @@coll.find({}, :skip => 5).count(true)
193
+ assert_equal 2, @@coll.find({}, :skip => 5, :limit => 2).count(true)
194
+
195
+ assert_equal 1, @@coll.find({"x" => 1}).count()
196
+ assert_equal 5, @@coll.find({"x" => {"$lt" => 5}}).count()
197
+
198
+ a = @@coll.find()
199
+ b = a.count()
200
+ a.each do |doc|
201
+ break
202
+ end
203
+ assert_equal b, a.count()
204
+
205
+ assert_equal 0, @@db['acollectionthatdoesn'].count()
206
+ end
207
+
208
+ def test_sort
209
+ @@coll.remove
210
+ 5.times{|x| @@coll.insert({"age" => x}) }
211
+
212
+ assert_kind_of Cursor, @@coll.find().sort(:age, 1)
213
+
214
+ assert_equal 0, @@coll.find().sort(:age, 1).next_document["age"]
215
+ assert_equal 4, @@coll.find().sort(:age, -1).next_document["age"]
216
+ assert_equal 0, @@coll.find().sort([["age", :asc]]).next_document["age"]
217
+
218
+ assert_kind_of Cursor, @@coll.find().sort([[:age, -1], [:b, 1]])
219
+
220
+ assert_equal 4, @@coll.find().sort(:age, 1).sort(:age, -1).next_document["age"]
221
+ assert_equal 0, @@coll.find().sort(:age, -1).sort(:age, 1).next_document["age"]
222
+
223
+ assert_equal 4, @@coll.find().sort([:age, :asc]).sort(:age, -1).next_document["age"]
224
+ assert_equal 0, @@coll.find().sort([:age, :desc]).sort(:age, 1).next_document["age"]
225
+
226
+ cursor = @@coll.find()
227
+ cursor.next_document
228
+ assert_raise InvalidOperation do
229
+ cursor.sort(["age"])
230
+ end
231
+
232
+ assert_raise InvalidSortValueError do
233
+ @@coll.find().sort(:age, 25).next_document
234
+ end
235
+
236
+ assert_raise InvalidSortValueError do
237
+ @@coll.find().sort(25).next_document
238
+ end
239
+ end
240
+
241
+ def test_sort_date
242
+ @@coll.remove
243
+ 5.times{|x| @@coll.insert({"created_at" => Time.utc(2000 + x)}) }
244
+
245
+ assert_equal 2000, @@coll.find().sort(:created_at, :asc).next_document["created_at"].year
246
+ assert_equal 2004, @@coll.find().sort(:created_at, :desc).next_document["created_at"].year
247
+
248
+ assert_equal 2000, @@coll.find().sort([:created_at, :asc]).next_document["created_at"].year
249
+ assert_equal 2004, @@coll.find().sort([:created_at, :desc]).next_document["created_at"].year
250
+
251
+ assert_equal 2000, @@coll.find().sort([[:created_at, :asc]]).next_document["created_at"].year
252
+ assert_equal 2004, @@coll.find().sort([[:created_at, :desc]]).next_document["created_at"].year
253
+ end
254
+
255
+ def test_sort_min_max_keys
256
+ @@coll.remove
257
+ @@coll.insert({"n" => 1000000})
258
+ @@coll.insert({"n" => -1000000})
259
+ @@coll.insert({"n" => MaxKey.new})
260
+ @@coll.insert({"n" => MinKey.new})
261
+
262
+ results = @@coll.find.sort([:n, :asc]).to_a
263
+
264
+ assert_equal MinKey.new, results[0]['n']
265
+ assert_equal(-1000000, results[1]['n'])
266
+ assert_equal 1000000, results[2]['n']
267
+ assert_equal MaxKey.new, results[3]['n']
268
+ end
269
+
270
+ def test_id_range_queries
271
+ @@coll.remove
272
+
273
+ t1 = Time.now
274
+ t1_id = ObjectId.from_time(t1)
275
+ @@coll.save({:t => 't1'})
276
+ @@coll.save({:t => 't1'})
277
+ @@coll.save({:t => 't1'})
278
+ sleep(1)
279
+ t2 = Time.now
280
+ t2_id = ObjectId.from_time(t2)
281
+ @@coll.save({:t => 't2'})
282
+ @@coll.save({:t => 't2'})
283
+ @@coll.save({:t => 't2'})
284
+
285
+ assert_equal 3, @@coll.find({'_id' => {'$gt' => t1_id, '$lt' => t2_id}}).count
286
+ @@coll.find({'_id' => {'$gt' => t2_id}}).each do |doc|
287
+ assert_equal 't2', doc['t']
288
+ end
289
+ end
290
+
291
+ def test_limit
292
+ @@coll.remove
293
+
294
+ 10.times do |i|
295
+ @@coll.save("x" => i)
296
+ end
297
+ assert_equal 10, @@coll.find().count()
298
+
299
+ results = @@coll.find().limit(5).to_a
300
+ assert_equal 5, results.length
301
+ end
302
+
303
+ def test_timeout_options
304
+ cursor = Cursor.new(@@coll)
305
+ assert_equal true, cursor.timeout
306
+
307
+ cursor = @@coll.find
308
+ assert_equal true, cursor.timeout
309
+
310
+ cursor = @@coll.find({}, :timeout => nil)
311
+ assert_equal true, cursor.timeout
312
+
313
+ cursor = Cursor.new(@@coll, :timeout => false)
314
+ assert_equal false, cursor.timeout
315
+
316
+ @@coll.find({}, :timeout => false) do |c|
317
+ assert_equal false, c.timeout
318
+ end
319
+ end
320
+
321
+ def test_timeout
322
+ opts = Cursor.new(@@coll).options
323
+ assert_equal 0, opts & Mongo::Constants::OP_QUERY_NO_CURSOR_TIMEOUT
324
+
325
+ opts = Cursor.new(@@coll, :timeout => false).options
326
+ assert_equal Mongo::Constants::OP_QUERY_NO_CURSOR_TIMEOUT,
327
+ opts & Mongo::Constants::OP_QUERY_NO_CURSOR_TIMEOUT
328
+ end
329
+
330
+ def test_limit_exceptions
331
+ cursor = @@coll.find()
332
+ cursor.next_document
333
+ assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
334
+ cursor.limit(1)
335
+ end
336
+
337
+ cursor = @@coll.find()
338
+ cursor.close
339
+ assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
340
+ cursor.limit(1)
341
+ end
342
+ end
343
+
344
+ def test_skip
345
+ @@coll.remove
346
+
347
+ 10.times do |i|
348
+ @@coll.save("x" => i)
349
+ end
350
+ assert_equal 10, @@coll.find().count()
351
+
352
+ all_results = @@coll.find().to_a
353
+ skip_results = @@coll.find().skip(2).to_a
354
+ assert_equal 10, all_results.length
355
+ assert_equal 8, skip_results.length
356
+
357
+ assert_equal all_results.slice(2...10), skip_results
358
+ end
359
+
360
+ def test_skip_exceptions
361
+ cursor = @@coll.find()
362
+ cursor.next_document
363
+ assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
364
+ cursor.skip(1)
365
+ end
366
+
367
+ cursor = @@coll.find()
368
+ cursor.close
369
+ assert_raise InvalidOperation, "Cannot modify the query once it has been run or closed." do
370
+ cursor.skip(1)
371
+ end
372
+ end
373
+
374
+ def test_limit_skip_chaining
375
+ @@coll.remove
376
+ 10.times do |i|
377
+ @@coll.save("x" => i)
378
+ end
379
+
380
+ all_results = @@coll.find().to_a
381
+ limited_skip_results = @@coll.find().limit(5).skip(3).to_a
382
+
383
+ assert_equal all_results.slice(3...8), limited_skip_results
384
+ end
385
+
386
+ def test_close_no_query_sent
387
+ begin
388
+ cursor = @@coll.find('a' => 1)
389
+ cursor.close
390
+ assert cursor.closed?
391
+ rescue => ex
392
+ fail ex.to_s
393
+ end
394
+ end
395
+
396
+ def test_refill_via_get_more
397
+ assert_equal 1, @@coll.count
398
+ 1000.times { |i|
399
+ assert_equal 1 + i, @@coll.count
400
+ @@coll.insert('a' => i)
401
+ }
402
+
403
+ assert_equal 1001, @@coll.count
404
+ count = 0
405
+ @@coll.find.each { |obj|
406
+ count += obj['a']
407
+ }
408
+ assert_equal 1001, @@coll.count
409
+
410
+ # do the same thing again for debugging
411
+ assert_equal 1001, @@coll.count
412
+ count2 = 0
413
+ @@coll.find.each { |obj|
414
+ count2 += obj['a']
415
+ }
416
+ assert_equal 1001, @@coll.count
417
+
418
+ assert_equal count, count2
419
+ assert_equal 499501, count
420
+ end
421
+
422
+ def test_refill_via_get_more_alt_coll
423
+ coll = @@db.collection('test-alt-coll')
424
+ coll.remove
425
+ coll.insert('a' => 1) # collection not created until it's used
426
+ assert_equal 1, coll.count
427
+
428
+ 1000.times { |i|
429
+ assert_equal 1 + i, coll.count
430
+ coll.insert('a' => i)
431
+ }
432
+
433
+ assert_equal 1001, coll.count
434
+ count = 0
435
+ coll.find.each { |obj|
436
+ count += obj['a']
437
+ }
438
+ assert_equal 1001, coll.count
439
+
440
+ # do the same thing again for debugging
441
+ assert_equal 1001, coll.count
442
+ count2 = 0
443
+ coll.find.each { |obj|
444
+ count2 += obj['a']
445
+ }
446
+ assert_equal 1001, coll.count
447
+
448
+ assert_equal count, count2
449
+ assert_equal 499501, count
450
+ end
451
+
452
+ def test_close_after_query_sent
453
+ begin
454
+ cursor = @@coll.find('a' => 1)
455
+ cursor.next_document
456
+ cursor.close
457
+ assert cursor.closed?
458
+ rescue => ex
459
+ fail ex.to_s
460
+ end
461
+ end
462
+
463
+ def test_kill_cursors
464
+ @@coll.drop
465
+
466
+ client_cursors = @@db.command("cursorInfo" => 1)["clientCursors_size"]
467
+
468
+ 10000.times do |i|
469
+ @@coll.insert("i" => i)
470
+ end
471
+
472
+ assert_equal(client_cursors,
473
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
474
+
475
+ 10.times do |i|
476
+ @@coll.find_one()
477
+ end
478
+
479
+ assert_equal(client_cursors,
480
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
481
+
482
+ 10.times do |i|
483
+ a = @@coll.find()
484
+ a.next_document
485
+ a.close()
486
+ end
487
+
488
+ assert_equal(client_cursors,
489
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
490
+
491
+ a = @@coll.find()
492
+ a.next_document
493
+
494
+ assert_not_equal(client_cursors,
495
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
496
+
497
+ a.close()
498
+
499
+ assert_equal(client_cursors,
500
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
501
+
502
+ a = @@coll.find({}, :limit => 10).next_document
503
+
504
+ assert_equal(client_cursors,
505
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
506
+
507
+ @@coll.find() do |cursor|
508
+ cursor.next_document
509
+ end
510
+
511
+ assert_equal(client_cursors,
512
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
513
+
514
+ @@coll.find() { |cursor|
515
+ cursor.next_document
516
+ }
517
+
518
+ assert_equal(client_cursors,
519
+ @@db.command("cursorInfo" => 1)["clientCursors_size"])
520
+ end
521
+
522
+ def test_count_with_fields
523
+ @@coll.remove
524
+ @@coll.save("x" => 1)
525
+
526
+ if @@version < "1.1.3"
527
+ assert_equal(0, @@coll.find({}, :fields => ["a"]).count())
528
+ else
529
+ assert_equal(1, @@coll.find({}, :fields => ["a"]).count())
530
+ end
531
+ end
532
+
533
+ def test_has_next
534
+ @@coll.remove
535
+ 200.times do |n|
536
+ @@coll.save("x" => n)
537
+ end
538
+
539
+ cursor = @@coll.find
540
+ n = 0
541
+ while cursor.has_next?
542
+ assert cursor.next
543
+ n += 1
544
+ end
545
+
546
+ assert_equal n, 200
547
+ assert_equal false, cursor.has_next?
548
+ end
549
+
550
+ def test_cursor_invalid
551
+ @@coll.remove
552
+ 10000.times do |n|
553
+ @@coll.insert({:a => n})
554
+ end
555
+
556
+ cursor = @@coll.find({})
557
+
558
+ assert_raise_error Mongo::OperationFailure, "CURSOR_NOT_FOUND" do
559
+ 9999.times do
560
+ cursor.next_document
561
+ cursor.instance_variable_set(:@cursor_id, 1234567890)
562
+ end
563
+ end
564
+ end
565
+
566
+ def test_enumberables
567
+ @@coll.remove
568
+ 100.times do |n|
569
+ @@coll.insert({:a => n})
570
+ end
571
+
572
+ assert_equal 100, @@coll.find.to_a.length
573
+ assert_equal 100, @@coll.find.to_set.length
574
+
575
+ cursor = @@coll.find
576
+ 50.times { |n| cursor.next_document }
577
+ assert_equal 50, cursor.to_a.length
578
+ end
579
+
580
+ def test_rewind
581
+ @@coll.remove
582
+ 100.times do |n|
583
+ @@coll.insert({:a => n})
584
+ end
585
+
586
+ cursor = @@coll.find
587
+ cursor.to_a
588
+ assert_equal [], cursor.map {|doc| doc }
589
+
590
+ cursor.rewind!
591
+ assert_equal 100, cursor.map {|doc| doc }.length
592
+
593
+ cursor.rewind!
594
+ 5.times { cursor.next_document }
595
+ cursor.rewind!
596
+ assert_equal 100, cursor.map {|doc| doc }.length
597
+ end
598
+
599
+ def test_transformer
600
+ transformer = Proc.new { |doc| doc }
601
+ cursor = Cursor.new(@@coll, :transformer => transformer)
602
+ assert_equal(transformer, cursor.transformer)
603
+ end
604
+
605
+ def test_instance_transformation_with_next
606
+ klass = Struct.new(:id, :a)
607
+ transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
608
+ cursor = Cursor.new(@@coll, :transformer => transformer)
609
+ instance = cursor.next
610
+
611
+ assert_instance_of(klass, instance)
612
+ assert_instance_of(BSON::ObjectId, instance.id)
613
+ assert_equal(1, instance.a)
614
+ end
615
+
616
+ def test_instance_transformation_with_each
617
+ klass = Struct.new(:id, :a)
618
+ transformer = Proc.new { |doc| klass.new(doc['_id'], doc['a']) }
619
+ cursor = Cursor.new(@@coll, :transformer => transformer)
620
+
621
+ cursor.each do |instance|
622
+ assert_instance_of(klass, instance)
623
+ end
624
+ end
625
+ end