mongo 2.0.6 → 2.1.0

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 (317) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +5 -2
  3. data/lib/mongo/address/ipv4.rb +6 -1
  4. data/lib/mongo/address/unix.rb +2 -2
  5. data/lib/mongo/address.rb +18 -10
  6. data/lib/mongo/auth/cr/conversation.rb +1 -1
  7. data/lib/mongo/auth/ldap/conversation.rb +7 -3
  8. data/lib/mongo/auth/scram/conversation.rb +9 -3
  9. data/lib/mongo/auth/user/view.rb +23 -2
  10. data/lib/mongo/auth/x509/conversation.rb +1 -1
  11. data/lib/mongo/bulk_write/combineable.rb +51 -0
  12. data/lib/mongo/bulk_write/ordered_combiner.rb +55 -0
  13. data/lib/mongo/bulk_write/result.rb +191 -0
  14. data/lib/mongo/bulk_write/result_combiner.rb +117 -0
  15. data/lib/mongo/bulk_write/transformable.rb +132 -0
  16. data/lib/mongo/bulk_write/unordered_combiner.rb +52 -0
  17. data/lib/mongo/bulk_write/validatable.rb +62 -0
  18. data/lib/mongo/bulk_write.rb +159 -23
  19. data/lib/mongo/client.rb +52 -16
  20. data/lib/mongo/cluster/topology/replica_set.rb +27 -9
  21. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  22. data/lib/mongo/cluster/topology/unknown.rb +5 -2
  23. data/lib/mongo/cluster.rb +42 -7
  24. data/lib/mongo/collection/view/aggregation.rb +48 -9
  25. data/lib/mongo/collection/view/immutable.rb +6 -6
  26. data/lib/mongo/collection/view/iterable.rb +18 -4
  27. data/lib/mongo/collection/view/map_reduce.rb +58 -17
  28. data/lib/mongo/collection/view/readable.rb +173 -42
  29. data/lib/mongo/collection/view/writable.rb +37 -23
  30. data/lib/mongo/collection/view.rb +2 -2
  31. data/lib/mongo/collection.rb +370 -33
  32. data/lib/mongo/cursor.rb +15 -3
  33. data/lib/mongo/database/view.rb +5 -4
  34. data/lib/mongo/database.rb +14 -4
  35. data/lib/mongo/dbref.rb +113 -0
  36. data/lib/mongo/error/closed_stream.rb +34 -0
  37. data/lib/mongo/error/extra_file_chunk.rb +34 -0
  38. data/lib/mongo/error/{invalid_uri_option.rb → file_not_found.rb} +11 -12
  39. data/lib/mongo/error/invalid_file.rb +2 -2
  40. data/lib/mongo/error/invalid_file_revision.rb +37 -0
  41. data/lib/mongo/error/invalid_uri.rb +5 -4
  42. data/lib/mongo/error/missing_file_chunk.rb +38 -0
  43. data/lib/mongo/error/operation_failure.rb +1 -1
  44. data/lib/mongo/error/parser.rb +1 -1
  45. data/lib/mongo/error/unchangeable_collection_option.rb +38 -0
  46. data/lib/mongo/error/unexpected_chunk_length.rb +39 -0
  47. data/lib/mongo/error.rb +13 -2
  48. data/lib/mongo/event/description_changed.rb +1 -1
  49. data/lib/mongo/grid/file/chunk.rb +6 -6
  50. data/lib/mongo/grid/file/{metadata.rb → info.rb} +41 -39
  51. data/lib/mongo/grid/file.rb +13 -10
  52. data/lib/mongo/grid/fs_bucket.rb +448 -0
  53. data/lib/mongo/grid/stream/read.rb +208 -0
  54. data/lib/mongo/grid/stream/write.rb +187 -0
  55. data/lib/mongo/grid/stream.rb +64 -0
  56. data/lib/mongo/grid.rb +2 -1
  57. data/lib/mongo/index/view.rb +3 -3
  58. data/lib/mongo/index.rb +5 -0
  59. data/lib/mongo/loggable.rb +34 -57
  60. data/lib/mongo/logger.rb +16 -78
  61. data/lib/mongo/monitoring/command_log_subscriber.rb +112 -0
  62. data/lib/mongo/monitoring/event/command_failed.rb +96 -0
  63. data/lib/mongo/monitoring/event/command_started.rb +89 -0
  64. data/lib/mongo/monitoring/event/command_succeeded.rb +118 -0
  65. data/lib/mongo/monitoring/event/secure.rb +58 -0
  66. data/lib/mongo/monitoring/event.rb +18 -0
  67. data/lib/mongo/monitoring/publishable.rb +106 -0
  68. data/lib/mongo/monitoring.rb +195 -0
  69. data/lib/mongo/operation/{aggregate.rb → commands/aggregate.rb} +3 -41
  70. data/lib/mongo/operation/commands/collections_info/result.rb +39 -0
  71. data/lib/mongo/operation/commands/collections_info.rb +68 -0
  72. data/lib/mongo/operation/{command.rb → commands/command.rb} +2 -18
  73. data/lib/mongo/operation/commands/indexes.rb +70 -0
  74. data/lib/mongo/operation/commands/list_collections/result.rb +112 -0
  75. data/lib/mongo/operation/commands/list_collections.rb +54 -0
  76. data/lib/mongo/operation/commands/list_indexes/result.rb +116 -0
  77. data/lib/mongo/operation/commands/list_indexes.rb +56 -0
  78. data/lib/mongo/operation/{map_reduce → commands/map_reduce}/result.rb +1 -1
  79. data/lib/mongo/operation/{map_reduce.rb → commands/map_reduce.rb} +3 -41
  80. data/lib/mongo/operation/commands/parallel_scan/result.rb +72 -0
  81. data/lib/mongo/operation/commands/parallel_scan.rb +56 -0
  82. data/lib/mongo/operation/commands/user_query.rb +69 -0
  83. data/lib/mongo/{bulk_write/ordered_bulk_write.rb → operation/commands/users_info/result.rb} +18 -30
  84. data/lib/mongo/operation/commands/users_info.rb +53 -0
  85. data/lib/mongo/operation/commands.rb +24 -0
  86. data/lib/mongo/operation/executable.rb +4 -68
  87. data/lib/mongo/operation/kill_cursors.rb +3 -3
  88. data/lib/mongo/operation/read/get_more.rb +2 -22
  89. data/lib/mongo/{bulk_write/unordered_bulk_write.rb → operation/read/query/result.rb} +20 -26
  90. data/lib/mongo/operation/read/query.rb +4 -21
  91. data/lib/mongo/operation/read.rb +0 -4
  92. data/lib/mongo/operation/{read_preferrable.rb → read_preference.rb} +3 -2
  93. data/lib/mongo/operation/result.rb +13 -1
  94. data/lib/mongo/operation/specifiable.rb +42 -0
  95. data/lib/mongo/operation/write/bulk/bulkable.rb +82 -0
  96. data/lib/mongo/operation/write/bulk/delete/result.rb +74 -0
  97. data/lib/mongo/operation/write/bulk/delete.rb +71 -0
  98. data/lib/mongo/operation/write/bulk/insert/result.rb +129 -0
  99. data/lib/mongo/operation/write/bulk/insert.rb +96 -0
  100. data/lib/mongo/operation/write/bulk/legacy_mergable.rb +87 -0
  101. data/lib/mongo/operation/write/bulk/mergable.rb +71 -0
  102. data/lib/mongo/operation/write/bulk/update/result.rb +174 -0
  103. data/lib/mongo/operation/write/bulk/update.rb +81 -0
  104. data/lib/mongo/operation/write/bulk.rb +6 -3
  105. data/lib/mongo/operation/write/command/create_index.rb +0 -1
  106. data/lib/mongo/operation/write/command/create_user.rb +0 -1
  107. data/lib/mongo/operation/write/command/delete.rb +0 -1
  108. data/lib/mongo/operation/write/command/drop_index.rb +0 -1
  109. data/lib/mongo/operation/write/command/insert.rb +0 -1
  110. data/lib/mongo/operation/write/command/remove_user.rb +0 -1
  111. data/lib/mongo/operation/write/command/update.rb +0 -1
  112. data/lib/mongo/operation/write/command/update_user.rb +0 -1
  113. data/lib/mongo/operation/write/command/writable.rb +13 -18
  114. data/lib/mongo/operation/write/create_index.rb +4 -27
  115. data/lib/mongo/operation/write/create_user.rb +4 -30
  116. data/lib/mongo/operation/write/delete.rb +6 -29
  117. data/lib/mongo/operation/write/drop_index.rb +3 -3
  118. data/lib/mongo/operation/write/gle.rb +48 -0
  119. data/lib/mongo/operation/write/idable.rb +5 -0
  120. data/lib/mongo/operation/write/insert.rb +2 -24
  121. data/lib/mongo/operation/write/remove_user.rb +4 -27
  122. data/lib/mongo/operation/write/update.rb +13 -36
  123. data/lib/mongo/operation/write/update_user.rb +4 -30
  124. data/lib/mongo/operation/write/write_command_enabled.rb +53 -0
  125. data/lib/mongo/operation/write.rb +2 -0
  126. data/lib/mongo/operation.rb +32 -4
  127. data/lib/mongo/options/mapper.rb +4 -2
  128. data/lib/mongo/options/redacted.rb +156 -0
  129. data/lib/mongo/options.rb +1 -0
  130. data/lib/mongo/protocol/delete.rb +75 -15
  131. data/lib/mongo/protocol/get_more.rb +65 -13
  132. data/lib/mongo/protocol/insert.rb +85 -13
  133. data/lib/mongo/protocol/kill_cursors.rb +59 -14
  134. data/lib/mongo/protocol/message.rb +12 -12
  135. data/lib/mongo/protocol/query.rb +163 -37
  136. data/lib/mongo/protocol/reply.rb +103 -0
  137. data/lib/mongo/protocol/serializers.rb +1 -1
  138. data/lib/mongo/protocol/update.rb +82 -14
  139. data/lib/mongo/retryable.rb +83 -0
  140. data/lib/mongo/server/connectable.rb +21 -25
  141. data/lib/mongo/server/connection.rb +75 -4
  142. data/lib/mongo/server/connection_pool/queue.rb +15 -0
  143. data/lib/mongo/server/connection_pool.rb +12 -0
  144. data/lib/mongo/server/description/features.rb +2 -1
  145. data/lib/mongo/server/description.rb +52 -1
  146. data/lib/mongo/server/monitor/connection.rb +26 -2
  147. data/lib/mongo/server/monitor.rb +19 -3
  148. data/lib/mongo/server.rb +39 -5
  149. data/lib/mongo/server_selector/selectable.rb +40 -31
  150. data/lib/mongo/server_selector.rb +19 -10
  151. data/lib/mongo/socket/ssl.rb +28 -16
  152. data/lib/mongo/socket/tcp.rb +3 -3
  153. data/lib/mongo/socket/unix.rb +5 -8
  154. data/lib/mongo/socket.rb +11 -4
  155. data/lib/mongo/uri.rb +248 -137
  156. data/lib/mongo/version.rb +1 -1
  157. data/lib/mongo.rb +5 -3
  158. data/spec/mongo/address/unix_spec.rb +1 -1
  159. data/spec/mongo/address_spec.rb +25 -0
  160. data/spec/mongo/auth/cr_spec.rb +9 -1
  161. data/spec/mongo/auth/ldap/conversation_spec.rb +43 -0
  162. data/spec/mongo/auth/ldap_spec.rb +9 -1
  163. data/spec/mongo/auth/scram_spec.rb +9 -1
  164. data/spec/mongo/auth/user/view_spec.rb +26 -1
  165. data/spec/mongo/auth/x509_spec.rb +9 -1
  166. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +271 -0
  167. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +239 -0
  168. data/spec/mongo/bulk_write_spec.rb +428 -0
  169. data/spec/mongo/client_spec.rb +167 -17
  170. data/spec/mongo/cluster/topology/replica_set_spec.rb +18 -9
  171. data/spec/mongo/cluster/topology/sharded_spec.rb +11 -3
  172. data/spec/mongo/cluster/topology/single_spec.rb +12 -4
  173. data/spec/mongo/cluster_spec.rb +55 -10
  174. data/spec/mongo/collection/view/aggregation_spec.rb +188 -1
  175. data/spec/mongo/collection/view/explainable_spec.rb +1 -1
  176. data/spec/mongo/collection/view/immutable_spec.rb +103 -0
  177. data/spec/mongo/collection/view/map_reduce_spec.rb +99 -4
  178. data/spec/mongo/collection/view/readable_spec.rb +238 -6
  179. data/spec/mongo/collection/view/writable_spec.rb +4 -4
  180. data/spec/mongo/collection/view_spec.rb +459 -71
  181. data/spec/mongo/collection_spec.rb +1291 -9
  182. data/spec/mongo/command_monitoring_spec.rb +51 -0
  183. data/spec/mongo/connection_string_spec.rb +115 -0
  184. data/spec/mongo/crud_spec.rb +2 -2
  185. data/spec/mongo/cursor_spec.rb +3 -3
  186. data/spec/mongo/database_spec.rb +47 -11
  187. data/spec/mongo/dbref_spec.rb +149 -0
  188. data/spec/mongo/grid/file/chunk_spec.rb +5 -5
  189. data/spec/mongo/grid/file/{metadata_spec.rb → info_spec.rb} +29 -17
  190. data/spec/mongo/grid/file_spec.rb +8 -8
  191. data/spec/mongo/grid/fs_bucket_spec.rb +1020 -0
  192. data/spec/mongo/grid/stream/read_spec.rb +275 -0
  193. data/spec/mongo/grid/stream/write_spec.rb +440 -0
  194. data/spec/mongo/grid/stream_spec.rb +48 -0
  195. data/spec/mongo/gridfs_spec.rb +50 -0
  196. data/spec/mongo/logger_spec.rb +0 -40
  197. data/spec/mongo/monitoring/command_log_subscriber_spec.rb +76 -0
  198. data/spec/mongo/monitoring/event/command_started_spec.rb +26 -0
  199. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +26 -0
  200. data/spec/mongo/monitoring/event/secure_spec.rb +57 -0
  201. data/spec/mongo/monitoring_spec.rb +168 -0
  202. data/spec/mongo/operation/commands/aggregate_spec.rb +69 -0
  203. data/spec/mongo/operation/{read → commands}/collections_info_spec.rb +1 -1
  204. data/spec/mongo/operation/{command_spec.rb → commands/command_spec.rb} +0 -18
  205. data/spec/mongo/operation/{read → commands}/indexes_spec.rb +1 -1
  206. data/spec/mongo/operation/{map_reduce_spec.rb → commands/map_reduce_spec.rb} +1 -19
  207. data/spec/mongo/operation/kill_cursors_spec.rb +1 -17
  208. data/spec/mongo/operation/read/get_more_spec.rb +0 -16
  209. data/spec/mongo/operation/read/query_spec.rb +19 -16
  210. data/spec/mongo/operation/{read_preferrable_spec.rb → read_preference_spec.rb} +11 -11
  211. data/spec/mongo/operation/write/bulk/{bulk_delete_spec.rb → delete_spec.rb} +18 -29
  212. data/spec/mongo/operation/write/bulk/{bulk_insert_spec.rb → insert_spec.rb} +3 -14
  213. data/spec/mongo/operation/write/bulk/{bulk_update_spec.rb → update_spec.rb} +8 -19
  214. data/spec/mongo/operation/write/command/delete_spec.rb +0 -16
  215. data/spec/mongo/operation/write/command/insert_spec.rb +0 -16
  216. data/spec/mongo/operation/write/command/update_spec.rb +0 -16
  217. data/spec/mongo/operation/write/delete_spec.rb +4 -4
  218. data/spec/mongo/operation/write/insert_spec.rb +2 -13
  219. data/spec/mongo/operation/write/update_spec.rb +7 -7
  220. data/spec/mongo/options/redacted_spec.rb +350 -0
  221. data/spec/mongo/protocol/kill_cursors_spec.rb +5 -3
  222. data/spec/mongo/protocol/query_spec.rb +15 -30
  223. data/spec/mongo/retryable_spec.rb +147 -0
  224. data/spec/mongo/server/connection_pool/queue_spec.rb +16 -0
  225. data/spec/mongo/server/connection_pool_spec.rb +50 -6
  226. data/spec/mongo/server/connection_spec.rb +49 -4
  227. data/spec/mongo/server/description_spec.rb +49 -3
  228. data/spec/mongo/server/monitor_spec.rb +51 -0
  229. data/spec/mongo/server_discovery_and_monitoring_spec.rb +32 -59
  230. data/spec/mongo/server_selection_rtt_spec.rb +37 -57
  231. data/spec/mongo/server_selection_spec.rb +19 -9
  232. data/spec/mongo/server_selector/nearest_spec.rb +35 -27
  233. data/spec/mongo/server_selector/primary_preferred_spec.rb +32 -30
  234. data/spec/mongo/server_selector/primary_spec.rb +21 -14
  235. data/spec/mongo/server_selector/secondary_preferred_spec.rb +28 -26
  236. data/spec/mongo/server_selector/secondary_spec.rb +24 -22
  237. data/spec/mongo/server_selector_spec.rb +87 -24
  238. data/spec/mongo/server_spec.rb +94 -8
  239. data/spec/mongo/socket/ssl_spec.rb +123 -13
  240. data/spec/mongo/socket/unix_spec.rb +52 -0
  241. data/spec/mongo/uri_spec.rb +295 -67
  242. data/spec/spec_helper.rb +40 -24
  243. data/spec/support/authorization.rb +23 -9
  244. data/spec/support/certificates/client.pem +4 -4
  245. data/spec/support/command_monitoring/bulkWrite.yml +73 -0
  246. data/spec/support/command_monitoring/command.yml +42 -0
  247. data/spec/support/command_monitoring/deleteMany.yml +55 -0
  248. data/spec/support/command_monitoring/deleteOne.yml +55 -0
  249. data/spec/support/command_monitoring/find.yml +219 -0
  250. data/spec/support/command_monitoring/insertMany.yml +81 -0
  251. data/spec/support/command_monitoring/insertOne.yml +51 -0
  252. data/spec/support/command_monitoring/updateMany.yml +67 -0
  253. data/spec/support/command_monitoring/updateOne.yml +95 -0
  254. data/spec/support/command_monitoring.rb +365 -0
  255. data/spec/support/connection_string.rb +228 -0
  256. data/spec/support/connection_string_tests/invalid-uris.yml +193 -0
  257. data/spec/support/connection_string_tests/valid-auth.yml +256 -0
  258. data/spec/support/connection_string_tests/valid-host_identifiers.yml +121 -0
  259. data/spec/support/connection_string_tests/valid-options.yml +30 -0
  260. data/spec/support/connection_string_tests/valid-unix_socket-absolute.yml +197 -0
  261. data/spec/support/connection_string_tests/valid-unix_socket-relative.yml +213 -0
  262. data/spec/support/connection_string_tests/valid-warnings.yml +55 -0
  263. data/spec/support/crud/read.rb +22 -19
  264. data/spec/support/crud/write.rb +58 -27
  265. data/spec/support/crud.rb +10 -2
  266. data/spec/support/gridfs.rb +637 -0
  267. data/spec/support/gridfs_tests/delete.yml +157 -0
  268. data/spec/support/gridfs_tests/download.yml +210 -0
  269. data/spec/support/gridfs_tests/download_by_name.yml +113 -0
  270. data/spec/support/gridfs_tests/upload.yml +158 -0
  271. data/spec/support/matchers.rb +1 -1
  272. data/spec/support/sdam/rs/equal_electionids.yml +44 -0
  273. data/spec/support/sdam/rs/new_primary_new_electionid.yml +95 -0
  274. data/spec/support/sdam/rs/null_election_id.yml +144 -0
  275. data/spec/support/sdam/rs/primary_disconnect_electionid.yml +124 -0
  276. data/spec/support/sdam/rs/primary_mismatched_me.yml +37 -0
  277. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +75 -0
  278. data/spec/support/sdam/rs/secondary_mismatched_me.yml +37 -0
  279. data/spec/support/sdam/sharded/mongos_disconnect.yml +104 -0
  280. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
  281. data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
  282. data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
  283. data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
  284. data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
  285. data/spec/support/sdam/single/not_ok_response.yml +0 -1
  286. data/spec/support/server_discovery_and_monitoring.rb +22 -3
  287. data/spec/support/server_selection.rb +3 -1
  288. data/spec/support/shared/bulk_write.rb +218 -22
  289. data/spec/support/shared/server_selector.rb +80 -14
  290. data.tar.gz.sig +0 -0
  291. metadata +188 -59
  292. metadata.gz.sig +0 -0
  293. data/lib/mongo/bulk_write/bulk_writable.rb +0 -196
  294. data/lib/mongo/bulk_write/deletable.rb +0 -56
  295. data/lib/mongo/bulk_write/insertable.rb +0 -48
  296. data/lib/mongo/bulk_write/replacable.rb +0 -57
  297. data/lib/mongo/bulk_write/updatable.rb +0 -68
  298. data/lib/mongo/grid/fs.rb +0 -149
  299. data/lib/mongo/operation/list_collections/result.rb +0 -114
  300. data/lib/mongo/operation/list_indexes/result.rb +0 -118
  301. data/lib/mongo/operation/read/collections_info.rb +0 -68
  302. data/lib/mongo/operation/read/indexes.rb +0 -69
  303. data/lib/mongo/operation/read/list_collections.rb +0 -76
  304. data/lib/mongo/operation/read/list_indexes.rb +0 -78
  305. data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +0 -75
  306. data/lib/mongo/operation/write/bulk/bulk_delete.rb +0 -145
  307. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +0 -130
  308. data/lib/mongo/operation/write/bulk/bulk_insert.rb +0 -132
  309. data/lib/mongo/operation/write/bulk/bulk_mergable.rb +0 -67
  310. data/lib/mongo/operation/write/bulk/bulk_update/result.rb +0 -162
  311. data/lib/mongo/operation/write/bulk/bulk_update.rb +0 -154
  312. data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +0 -83
  313. data/spec/mongo/bulk/bulk_write_spec.rb +0 -262
  314. data/spec/mongo/grid/fs_spec.rb +0 -160
  315. data/spec/mongo/loggable_spec.rb +0 -63
  316. data/spec/mongo/operation/aggregate_spec.rb +0 -127
  317. /data/lib/mongo/operation/{aggregate → commands/aggregate}/result.rb +0 -0
@@ -15,7 +15,181 @@ describe Mongo::Collection::View do
15
15
  end
16
16
 
17
17
  after do
18
- authorized_collection.find.delete_many
18
+ authorized_collection.delete_many
19
+ end
20
+
21
+ context 'when query modifiers are provided' do
22
+
23
+ context 'when a selector has a query modifier' do
24
+
25
+ let(:options) do
26
+ {}
27
+ end
28
+
29
+ let(:expected_modifiers) do
30
+ BSON::Document.new(selector)
31
+ end
32
+
33
+ let(:parsed_selector) do
34
+ {}
35
+ end
36
+
37
+ let(:query_selector) do
38
+ BSON::Document.new(selector)
39
+ end
40
+
41
+ context 'when the $query key is a string' do
42
+
43
+ let(:selector) do
44
+ { "$query" => { a: 1 }, :$someMod => 100 }
45
+ end
46
+
47
+ let(:expected_modifiers) do
48
+ BSON::Document.new(selector)
49
+ end
50
+
51
+ it 'sets the modifiers' do
52
+ expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
53
+ end
54
+
55
+ it 'removes the modifiers from the selector' do
56
+ expect(view.selector).to eq(parsed_selector)
57
+ end
58
+
59
+ it 'creates the correct query selector' do
60
+ expect(view.send(:query_spec)[:selector]).to eq(query_selector)
61
+ end
62
+
63
+ end
64
+
65
+ context 'when the $query key is a symbol' do
66
+
67
+ let(:selector) do
68
+ { :$query => { a: 1 }, :$someMod => 100 }
69
+ end
70
+
71
+ let(:expected_modifiers) do
72
+ BSON::Document.new(selector)
73
+ end
74
+
75
+ it 'sets the modifiers' do
76
+ expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
77
+ end
78
+
79
+ it 'removes the modifiers from the selector' do
80
+ expect(view.selector).to eq(parsed_selector)
81
+ end
82
+
83
+ it 'creates the correct query selector' do
84
+ expect(view.send(:query_spec)[:selector]).to eq(query_selector)
85
+ end
86
+ end
87
+ end
88
+
89
+ context 'when a modifiers document is provided in the options' do
90
+
91
+ let(:selector) do
92
+ { a: 1 }
93
+ end
94
+
95
+ let(:options) do
96
+ { :modifiers => { :$someMod => 100 } }
97
+ end
98
+
99
+ let(:expected_modifiers) do
100
+ options[:modifiers]
101
+ end
102
+
103
+ let(:parsed_selector) do
104
+ { a: 1 }
105
+ end
106
+
107
+ let(:query_selector) do
108
+ BSON::Document.new(:$query => { a: 1 }, :$someMod => 100)
109
+ end
110
+
111
+ it 'sets the modifiers' do
112
+ expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
113
+ end
114
+
115
+ it 'removes the modifiers from the selector' do
116
+ expect(view.selector).to eq(parsed_selector)
117
+ end
118
+
119
+ it 'creates the correct query selector' do
120
+ expect(view.send(:query_spec)[:selector]).to eq(query_selector)
121
+ end
122
+
123
+ context 'when modifiers and options are both provided' do
124
+
125
+ let(:selector) do
126
+ { a: 1 }
127
+ end
128
+
129
+ let(:options) do
130
+ { :sort => { a: Mongo::Index::ASCENDING }, :modifiers => { :$orderby => { a: Mongo::Index::DESCENDING } } }
131
+ end
132
+
133
+ let(:expected_modifiers) do
134
+ { :$orderby => options[:sort] }
135
+ end
136
+
137
+ let(:parsed_selector) do
138
+ { a: 1 }
139
+ end
140
+
141
+ let(:query_selector) do
142
+ BSON::Document.new(:$query => selector, :$orderby => { a: Mongo::Index::ASCENDING })
143
+ end
144
+
145
+ it 'sets the modifiers' do
146
+ expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
147
+ end
148
+
149
+ it 'removes the modifiers from the selector' do
150
+ expect(view.selector).to eq(parsed_selector)
151
+ end
152
+
153
+ it 'creates the correct query selector' do
154
+ expect(view.send(:query_spec)[:selector]).to eq(query_selector)
155
+ end
156
+ end
157
+
158
+ context 'when modifiers, options and a query modifier are provided' do
159
+
160
+ let(:selector) do
161
+ { b: 2, :$query => { a: 1 }, :$someMod => 100 }
162
+ end
163
+
164
+ let(:options) do
165
+ { :sort => { a: Mongo::Index::ASCENDING }, :modifiers => { :$someMod => true, :$orderby => { a: Mongo::Index::DESCENDING } } }
166
+ end
167
+
168
+ let(:expected_modifiers) do
169
+ { :$query => { a: 1 }, :$orderby => { a: Mongo::Index::ASCENDING }, :$someMod => 100 }
170
+ end
171
+
172
+ let(:parsed_selector) do
173
+ { b: 2 }
174
+ end
175
+
176
+ let(:query_selector) do
177
+ BSON::Document.new(:$query => { a: 1 }, :$someMod => 100, :$orderby => { a: Mongo::Index::ASCENDING })
178
+ end
179
+
180
+ it 'sets the modifiers' do
181
+ expect(view.instance_variable_get(:@modifiers)).to eq(expected_modifiers)
182
+ end
183
+
184
+ it 'removes the modifiers from the selector' do
185
+ expect(view.selector).to eq(parsed_selector)
186
+ end
187
+
188
+ it 'creates the correct query selector' do
189
+ expect(view.send(:query_spec)[:selector]).to eq(query_selector)
190
+ end
191
+ end
192
+ end
19
193
  end
20
194
 
21
195
  describe '#==' do
@@ -116,32 +290,38 @@ describe Mongo::Collection::View do
116
290
  end
117
291
 
118
292
  after do
119
- authorized_collection.find.delete_many
293
+ authorized_collection.delete_many
120
294
  end
121
295
 
122
296
  context 'when sending the initial query' do
123
297
 
298
+ let(:returned) do
299
+ view.to_a
300
+ end
301
+
302
+ let(:query_spec) do
303
+ view.send(:query_spec)
304
+ end
305
+
124
306
  context 'when limit is specified' do
125
307
 
126
308
  let(:options) do
127
309
  { :limit => 5 }
128
310
  end
129
311
 
130
- before do
131
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
132
- expect(spec[:options][:limit]).to eq(options[:limit])
133
- end.and_call_original
134
- end
135
-
136
312
  let(:returned) do
137
313
  view.to_a
138
314
  end
139
315
 
316
+ it 'sets the limit on the initial query' do
317
+ expect(query_spec[:options][:limit]).to eq(options[:limit])
318
+ end
319
+
140
320
  it 'returns limited documents' do
141
321
  expect(returned.count).to eq(5)
142
322
  end
143
323
 
144
- it 'allows iteration of the documents' do
324
+ it 'iterates over all of the documents' do
145
325
  returned.each do |doc|
146
326
  expect(doc).to have_key('field')
147
327
  end
@@ -154,21 +334,19 @@ describe Mongo::Collection::View do
154
334
  { :batch_size => 5 }
155
335
  end
156
336
 
157
- before do
158
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
159
- expect(spec[:options][:limit]).to eq(options[:batch_size])
160
- end.and_call_original
161
- end
162
-
163
337
  let(:returned) do
164
338
  view.to_a
165
339
  end
166
340
 
341
+ it 'sets the batch size on the initial query' do
342
+ expect(query_spec[:options][:batch_size]).to eq(options[:batch_size])
343
+ end
344
+
167
345
  it 'returns all the documents' do
168
346
  expect(returned.count).to eq(10)
169
347
  end
170
348
 
171
- it 'allows iteration of all documents' do
349
+ it 'iterates over all of the documents' do
172
350
  returned.each do |doc|
173
351
  expect(doc).to have_key('field')
174
352
  end
@@ -177,21 +355,15 @@ describe Mongo::Collection::View do
177
355
 
178
356
  context 'when no limit is specified' do
179
357
 
180
- before do
181
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
182
- expect(spec[:options][:limit]).to eq(nil)
183
- end.and_call_original
184
- end
185
-
186
- let(:returned) do
187
- view.to_a
358
+ it 'does not set a limit on the initial query' do
359
+ expect(query_spec[:options][:limit]).to be_nil
188
360
  end
189
361
 
190
362
  it 'returns all the documents' do
191
363
  expect(returned.count).to eq(10)
192
364
  end
193
365
 
194
- it 'allows iteration of all documents' do
366
+ it 'iterates over all of the documents' do
195
367
  returned.each do |doc|
196
368
  expect(doc).to have_key('field')
197
369
  end
@@ -204,21 +376,19 @@ describe Mongo::Collection::View do
204
376
  { :batch_size => 5, :limit => 3 }
205
377
  end
206
378
 
207
- before do
208
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
209
- expect(spec[:options][:limit]).to eq(options[:limit])
210
- end.and_call_original
211
- end
212
-
213
379
  let(:returned) do
214
380
  view.to_a
215
381
  end
216
382
 
383
+ it 'sets the limit on the initial query' do
384
+ expect(query_spec[:options][:limit]).to eq(options[:limit])
385
+ end
386
+
217
387
  it 'returns the limit of documents' do
218
388
  expect(returned.count).to eq(3)
219
389
  end
220
390
 
221
- it 'allows iteration of the documents' do
391
+ it 'iterates over all of the documents' do
222
392
  returned.each do |doc|
223
393
  expect(doc).to have_key('field')
224
394
  end
@@ -231,21 +401,23 @@ describe Mongo::Collection::View do
231
401
  { :limit => 5, :batch_size => 3 }
232
402
  end
233
403
 
234
- before do
235
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
236
- expect(spec[:options][:limit]).to eq(options[:batch_size])
237
- end.and_call_original
238
- end
239
-
240
404
  let(:returned) do
241
405
  view.to_a
242
406
  end
243
407
 
408
+ it 'sets the batch size on the initial query' do
409
+ expect(query_spec[:options][:batch_size]).to eq(options[:batch_size])
410
+ end
411
+
412
+ it 'sets the limit on the initial query' do
413
+ expect(query_spec[:options][:limit]).to eq(options[:limit])
414
+ end
415
+
244
416
  it 'returns the limit of documents' do
245
417
  expect(returned.count).to eq(5)
246
418
  end
247
419
 
248
- it 'allows iteration of the documents' do
420
+ it 'iterates over all of the documents' do
249
421
  returned.each do |doc|
250
422
  expect(doc).to have_key('field')
251
423
  end
@@ -254,20 +426,22 @@ describe Mongo::Collection::View do
254
426
 
255
427
  context 'when the selector has special fields' do
256
428
 
257
- context 'when a snapshot option is provided' do
429
+ context 'when a snapshot option is specified' do
258
430
 
259
431
  let(:options) do
260
432
  { :snapshot => true }
261
433
  end
262
434
 
263
435
  before do
264
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
265
- expect(spec[:selector][:$query]).to eq(selector)
266
- end.and_call_original
436
+ expect(view).to receive(:special_selector).and_call_original
267
437
  end
268
438
 
269
439
  it 'creates a special query selector' do
270
- view.each do |doc|
440
+ expect(query_spec[:selector][:$snapshot]).to eq(options[:snapshot])
441
+ end
442
+
443
+ it 'iterates over all of the documents' do
444
+ returned.each do |doc|
271
445
  expect(doc).to have_key('field')
272
446
  end
273
447
  end
@@ -280,13 +454,36 @@ describe Mongo::Collection::View do
280
454
  end
281
455
 
282
456
  before do
283
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
284
- expect(spec[:selector][:$query]).to eq(selector)
285
- end.and_call_original
457
+ expect(view).to receive(:special_selector).and_call_original
286
458
  end
287
459
 
288
460
  it 'creates a special query selector' do
289
- view.each do |doc|
461
+ expect(query_spec[:selector][:$maxScan]).to eq(options[:max_scan])
462
+ end
463
+
464
+ it 'iterates over all of the documents' do
465
+ returned.each do |doc|
466
+ expect(doc).to have_key('field')
467
+ end
468
+ end
469
+ end
470
+
471
+ context 'when a max_time_ms option is provided' do
472
+
473
+ let(:options) do
474
+ { :max_time_ms => 100 }
475
+ end
476
+
477
+ before do
478
+ expect(view).to receive(:special_selector).and_call_original
479
+ end
480
+
481
+ it 'creates a special query selector' do
482
+ expect(query_spec[:selector][:$maxTimeMS]).to eq(options[:max_time_ms])
483
+ end
484
+
485
+ it 'iterates over all of the documents' do
486
+ returned.each do |doc|
290
487
  expect(doc).to have_key('field')
291
488
  end
292
489
  end
@@ -299,15 +496,16 @@ describe Mongo::Collection::View do
299
496
  end
300
497
 
301
498
  before do
302
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
303
- expect(spec[:selector][:$query]).to eq(selector)
304
- end.and_call_original
499
+ expect(view).to receive(:special_selector).and_call_original
305
500
  end
306
501
 
307
502
  it 'creates a special query selector' do
308
- view.each do |doc|
503
+ expect(query_spec[:selector][:$showDiskLoc]).to eq(options[:show_disk_loc])
504
+ end
505
+
506
+ it 'iterates over all of the documents' do
507
+ returned.each do |doc|
309
508
  expect(doc).to have_key('field')
310
- break
311
509
  end
312
510
  end
313
511
  end
@@ -320,13 +518,15 @@ describe Mongo::Collection::View do
320
518
  end
321
519
 
322
520
  before do
323
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
324
- expect(spec[:selector][:$query]).to eq(selector)
325
- end.and_call_original
521
+ expect(view).to receive(:special_selector).and_call_original
326
522
  end
327
523
 
328
524
  it 'creates a special query selector' do
329
- view.each do |doc|
525
+ expect(query_spec[:selector][:$orderby]).to eq(options[:sort])
526
+ end
527
+
528
+ it 'iterates over all of the documents' do
529
+ returned.each do |doc|
330
530
  expect(doc).to have_key('field')
331
531
  end
332
532
  end
@@ -341,15 +541,11 @@ describe Mongo::Collection::View do
341
541
  end
342
542
 
343
543
  before do
344
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
345
- expect(spec[:selector][:$query]).to eq(selector)
346
- end.and_call_original
544
+ expect(view).to receive(:special_selector).and_call_original
347
545
  end
348
546
 
349
- it'creates a special query selector' do
350
- expect {
351
- view.to_a
352
- }.to raise_error(Mongo::Error::OperationFailure)
547
+ it 'creates a special query selector' do
548
+ expect(query_spec[:selector][:$hint]).to eq(options[:hint])
353
549
  end
354
550
  end
355
551
  end
@@ -361,31 +557,205 @@ describe Mongo::Collection::View do
361
557
  end
362
558
 
363
559
  before do
364
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
365
- expect(spec[:selector][:$query]).to eq(selector)
366
- end.and_call_original
560
+ expect(view).to receive(:special_selector).and_call_original
367
561
  end
368
562
 
369
563
  it 'creates a special query selector' do
564
+ expect(query_spec[:selector][:$comment]).to eq(options[:comment])
565
+ end
566
+
567
+ it 'iterates over all of the documents' do
568
+ returned.each do |doc|
569
+ expect(doc).to have_key('field')
570
+ end
571
+ end
572
+ end
573
+
574
+ context 'when the cluster is sharded', if: sharded? do
575
+
576
+ before do
577
+ expect(view).to receive(:special_selector).and_call_original
578
+ end
579
+
580
+ it 'iterates over all of the documents' do
370
581
  view.each do |doc|
371
582
  expect(doc).to have_key('field')
372
583
  end
373
584
  end
585
+
586
+ context 'when there is a read preference' do
587
+
588
+ let(:collection) do
589
+ authorized_collection.with(read: { mode: :secondary})
590
+ end
591
+
592
+ let(:view) do
593
+ described_class.new(collection, selector, options)
594
+ end
595
+
596
+ let(:formatted_read_pref) do
597
+ BSON::Document.new(Mongo::ServerSelector.get(mode: :secondary).to_mongos)
598
+ end
599
+
600
+ it 'adds the formatted read preference to the selector' do
601
+ expect(view.send(:query_spec)[:selector][:$readPreference]).to eq(formatted_read_pref)
602
+ end
603
+ end
604
+
605
+ context 'when the read preference is primary' do
606
+
607
+ let(:collection) do
608
+ authorized_collection.with(read: { mode: :primary})
609
+ end
610
+
611
+ let(:view) do
612
+ described_class.new(collection, selector, options)
613
+ end
614
+
615
+ it 'does not add the formatted read preference to the selector' do
616
+ expect(view.send(:query_spec)[:selector][:$readPreference]).to be(nil)
617
+ end
618
+ end
374
619
  end
375
620
 
376
- context 'when the cluster is sharded' do
621
+ context 'when a modifier document is provided' do
622
+
623
+ let(:options) do
624
+ { :modifiers => {
625
+ :$orderby => {'x' => Mongo::Index::ASCENDING }
626
+ }
627
+ }
628
+ end
377
629
 
378
630
  before do
379
- expect(Mongo::Operation::Read::Query).to receive(:new) do |spec|
380
- expect(spec[:selector][:$query]).to eq(selector)
381
- end.and_call_original
631
+ expect(view).to receive(:special_selector).and_call_original
382
632
  end
383
633
 
384
634
  it 'creates a special query selector' do
635
+ expect(query_spec[:selector][:$orderby]).to eq(options[:modifiers][:$orderby])
636
+ end
637
+
638
+ it 'iterates over all of the documents' do
385
639
  view.each do |doc|
386
640
  expect(doc).to have_key('field')
387
641
  end
388
642
  end
643
+
644
+ context 'when $explain is specified' do
645
+ let(:options) do
646
+ { :modifiers => {
647
+ :$explain => 1
648
+ }
649
+ }
650
+ end
651
+
652
+ let(:explain) do
653
+ view.to_a.first
654
+ end
655
+
656
+ it 'executes an explain' do
657
+ expect(explain['cursor'] == 'BasicCursor' ||
658
+ explain['queryPlanner']).to be_truthy
659
+ end
660
+
661
+ end
662
+
663
+ context 'when an option is also provided' do
664
+
665
+ context 'when $orderby and sort are specified' do
666
+
667
+ let(:options) do
668
+ { :modifiers => {
669
+ :$orderby => { 'x' => Mongo::Index::ASCENDING }
670
+ },
671
+ :sort => { 'x' => Mongo::Index::DESCENDING }
672
+ }
673
+ end
674
+
675
+ it 'overrides the modifier value with the option value' do
676
+ expect(query_spec[:selector][:$orderby]).to eq(options[:sort])
677
+ end
678
+ end
679
+
680
+ context 'when $comment and comment are specified' do
681
+
682
+ let(:options) do
683
+ { :modifiers => {
684
+ :$comment => 'query1'
685
+ },
686
+ :comment => 'query2'
687
+ }
688
+ end
689
+
690
+ it 'overrides the modifier value with the option value' do
691
+ expect(query_spec[:selector][:$comment]).to eq(options[:comment])
692
+ end
693
+ end
694
+
695
+ context 'when $hint and hint are specified' do
696
+
697
+ let(:options) do
698
+ { :modifiers => {
699
+ :$hint => 'x'
700
+ },
701
+ :hint => 'y'
702
+ }
703
+ end
704
+
705
+ it 'overrides the modifier value with the option value' do
706
+ expect(query_spec[:selector][:$hint]).to eq(options[:hint])
707
+ end
708
+
709
+ end
710
+
711
+ context 'when $maxScan and max_scan are specified' do
712
+
713
+ let(:options) do
714
+ { :modifiers => {
715
+ :$maxScan => 4
716
+ },
717
+ :max_scan => 5
718
+ }
719
+ end
720
+
721
+ it 'overrides the modifier value with the option value' do
722
+ expect(query_spec[:selector][:$maxScan]).to eq(options[:max_scan])
723
+ end
724
+ end
725
+
726
+ context 'when $maxTimeMS and max_time_ms are specified' do
727
+
728
+ let(:options) do
729
+ { :modifiers => {
730
+ :$maxTimeMS => 100
731
+ },
732
+ :max_time_ms => 200
733
+ }
734
+ end
735
+
736
+ it 'overrides the modifier value with the option value' do
737
+ expect(query_spec[:selector][:$maxTimeMS]).to eq(options[:max_time_ms])
738
+ end
739
+ end
740
+
741
+ context 'when $query and a selector are specified' do
742
+
743
+ let(:selector) do
744
+ { 'y' => 1 }
745
+ end
746
+
747
+ let(:options) do
748
+ { :modifiers => {
749
+ :$query => { 'field' => 1 }
750
+ }
751
+ }
752
+ end
753
+
754
+ it 'overrides the modifier value with the option value' do
755
+ expect(query_spec[:selector][:$query]).to eq(options[:modifiers][:$query])
756
+ end
757
+ end
758
+ end
389
759
  end
390
760
  end
391
761
 
@@ -416,6 +786,24 @@ describe Mongo::Collection::View do
416
786
  end
417
787
  end
418
788
  end
789
+
790
+ describe '#close_query' do
791
+
792
+ let(:options) do
793
+ { :batch_size => 1 }
794
+ end
795
+
796
+ before do
797
+ e = view.to_enum
798
+ e.next
799
+ cursor = view.instance_variable_get(:@cursor)
800
+ expect(cursor).to receive(:kill_cursors).and_call_original
801
+ end
802
+
803
+ it 'sends a kill cursors command for the cursor' do
804
+ view.close_query
805
+ end
806
+ end
419
807
  end
420
808
 
421
809
  describe '#hash' do