mongo 1.12.5 → 2.0.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 (475) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CONTRIBUTING.md +64 -0
  4. data/LICENSE +1 -1
  5. data/README.md +21 -126
  6. data/Rakefile +39 -21
  7. data/bin/mongo_console +6 -38
  8. data/lib/mongo/address/ipv4.rb +85 -0
  9. data/lib/mongo/address/ipv6.rb +85 -0
  10. data/lib/mongo/address/unix.rb +76 -0
  11. data/lib/mongo/address.rb +111 -0
  12. data/lib/mongo/auth/cr/conversation.rb +119 -0
  13. data/lib/mongo/auth/cr.rb +44 -0
  14. data/lib/mongo/auth/executable.rb +52 -0
  15. data/lib/mongo/auth/ldap/conversation.rb +92 -0
  16. data/lib/mongo/auth/ldap.rb +48 -0
  17. data/lib/mongo/auth/roles.rb +104 -0
  18. data/lib/mongo/auth/scram/conversation.rb +450 -0
  19. data/lib/mongo/auth/scram.rb +53 -0
  20. data/lib/mongo/auth/user/view.rb +102 -0
  21. data/lib/mongo/auth/user.rb +159 -0
  22. data/lib/mongo/auth/x509/conversation.rb +92 -0
  23. data/lib/mongo/auth/x509.rb +48 -0
  24. data/lib/mongo/auth.rb +108 -0
  25. data/lib/mongo/bulk_write/bulk_writable.rb +191 -0
  26. data/lib/mongo/bulk_write/deletable.rb +60 -0
  27. data/lib/mongo/bulk_write/insertable.rb +52 -0
  28. data/lib/mongo/bulk_write/ordered_bulk_write.rb +48 -0
  29. data/lib/mongo/bulk_write/replacable.rb +57 -0
  30. data/lib/mongo/bulk_write/unordered_bulk_write.rb +46 -0
  31. data/lib/mongo/bulk_write/updatable.rb +68 -0
  32. data/lib/mongo/bulk_write.rb +52 -0
  33. data/lib/mongo/client.rb +246 -0
  34. data/lib/mongo/cluster/topology/replica_set.rb +160 -0
  35. data/lib/mongo/cluster/topology/sharded.rb +132 -0
  36. data/lib/mongo/cluster/topology/standalone.rb +132 -0
  37. data/lib/mongo/cluster/topology/unknown.rb +155 -0
  38. data/lib/mongo/cluster/topology.rb +60 -0
  39. data/lib/mongo/cluster.rb +203 -0
  40. data/lib/mongo/collection/view/aggregation.rb +108 -0
  41. data/lib/mongo/collection/view/explainable.rb +49 -0
  42. data/lib/mongo/collection/view/immutable.rb +43 -0
  43. data/lib/mongo/collection/view/iterable.rb +48 -0
  44. data/lib/mongo/collection/view/map_reduce.rb +191 -0
  45. data/lib/mongo/collection/view/readable.rb +363 -0
  46. data/lib/mongo/collection/view/writable.rb +185 -0
  47. data/lib/mongo/collection/view.rb +169 -0
  48. data/lib/mongo/collection.rb +130 -1101
  49. data/lib/mongo/cursor.rb +78 -681
  50. data/lib/mongo/database/view.rb +101 -0
  51. data/lib/mongo/database.rb +224 -0
  52. data/lib/mongo/error/bulk_write_error.rb +41 -0
  53. data/lib/mongo/error/invalid_bulk_operation.rb +36 -0
  54. data/lib/mongo/error/invalid_bulk_operation_type.rb +36 -0
  55. data/lib/mongo/error/invalid_collection_name.rb +39 -0
  56. data/lib/mongo/error/invalid_database_name.rb +39 -0
  57. data/{test/replica_set/ssl_test.rb → lib/mongo/error/invalid_document.rb} +21 -14
  58. data/lib/mongo/error/invalid_file.rb +38 -0
  59. data/lib/mongo/error/invalid_nonce.rb +46 -0
  60. data/lib/mongo/error/invalid_replacement_document.rb +39 -0
  61. data/lib/mongo/error/invalid_signature.rb +47 -0
  62. data/{test/functional/ssl_test.rb → lib/mongo/error/invalid_update_document.rb} +22 -12
  63. data/lib/mongo/error/max_bson_size.rb +40 -0
  64. data/lib/mongo/error/max_message_size.rb +42 -0
  65. data/{test/functional/db_connection_test.rb → lib/mongo/error/multi_index_drop.rb} +17 -8
  66. data/lib/mongo/{utils.rb → error/need_primary_server.rb} +10 -6
  67. data/lib/mongo/{connection.rb → error/operation_failure.rb} +10 -6
  68. data/lib/mongo/error/parser.rb +77 -0
  69. data/lib/mongo/{connection/socket.rb → error/socket_error.rb} +10 -5
  70. data/lib/mongo/error/socket_timeout_error.rb +23 -0
  71. data/lib/mongo/error/unsupported_features.rb +43 -0
  72. data/lib/mongo/error.rb +82 -0
  73. data/lib/mongo/event/listeners.rb +63 -0
  74. data/lib/mongo/event/primary_elected.rb +53 -0
  75. data/lib/mongo/event/publisher.rb +42 -0
  76. data/lib/mongo/event/server_added.rb +53 -0
  77. data/lib/mongo/event/server_removed.rb +53 -0
  78. data/lib/mongo/event/subscriber.rb +41 -0
  79. data/lib/mongo/event.rb +40 -0
  80. data/lib/mongo/grid/file/chunk.rb +184 -0
  81. data/lib/mongo/grid/file/metadata.rb +229 -0
  82. data/lib/mongo/grid/file.rb +106 -0
  83. data/lib/mongo/grid/fs.rb +149 -0
  84. data/lib/mongo/{gridfs.rb → grid.rb} +3 -5
  85. data/lib/mongo/index/view.rb +261 -0
  86. data/lib/mongo/index.rb +64 -0
  87. data/lib/mongo/loggable.rb +126 -0
  88. data/lib/mongo/logger.rb +132 -0
  89. data/lib/mongo/operation/aggregate/result.rb +88 -0
  90. data/lib/mongo/operation/aggregate.rb +100 -0
  91. data/lib/mongo/operation/command.rb +62 -0
  92. data/lib/mongo/operation/executable.rb +105 -0
  93. data/lib/mongo/operation/kill_cursors.rb +39 -0
  94. data/lib/mongo/operation/limited.rb +37 -0
  95. data/lib/mongo/operation/list_collections/result.rb +114 -0
  96. data/lib/mongo/operation/list_indexes/result.rb +118 -0
  97. data/lib/mongo/operation/map_reduce/result.rb +122 -0
  98. data/lib/mongo/operation/map_reduce.rb +96 -0
  99. data/lib/mongo/operation/read/collections_info.rb +67 -0
  100. data/lib/mongo/operation/read/get_more.rb +71 -0
  101. data/lib/mongo/operation/read/indexes.rb +68 -0
  102. data/lib/mongo/operation/read/list_collections.rb +75 -0
  103. data/lib/mongo/operation/read/list_indexes.rb +77 -0
  104. data/lib/mongo/operation/read/query.rb +71 -0
  105. data/lib/mongo/{functional.rb → operation/read.rb} +7 -7
  106. data/lib/mongo/operation/read_preferrable.rb +34 -0
  107. data/lib/mongo/operation/result.rb +259 -0
  108. data/lib/mongo/operation/specifiable.rb +397 -0
  109. data/lib/mongo/operation/write/bulk/bulk_delete/result.rb +75 -0
  110. data/lib/mongo/operation/write/bulk/bulk_delete.rb +144 -0
  111. data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +68 -0
  112. data/lib/mongo/operation/write/bulk/bulk_insert.rb +129 -0
  113. data/lib/mongo/operation/write/bulk/bulk_mergable.rb +67 -0
  114. data/lib/mongo/operation/write/bulk/bulk_update/result.rb +162 -0
  115. data/lib/mongo/operation/write/bulk/bulk_update.rb +153 -0
  116. data/lib/mongo/operation/write/bulk/legacy_bulk_mergable.rb +83 -0
  117. data/lib/mongo/operation/write/bulk.rb +17 -0
  118. data/lib/mongo/operation/write/command/create_index.rb +50 -0
  119. data/lib/mongo/operation/write/command/create_user.rb +43 -0
  120. data/lib/mongo/operation/write/command/delete.rb +56 -0
  121. data/lib/mongo/operation/write/command/drop_index.rb +51 -0
  122. data/lib/mongo/operation/write/command/insert.rb +55 -0
  123. data/lib/mongo/operation/write/command/remove_user.rb +42 -0
  124. data/lib/mongo/operation/write/command/update.rb +60 -0
  125. data/lib/mongo/operation/write/command/writable.rb +61 -0
  126. data/lib/mongo/operation/write/command.rb +22 -0
  127. data/lib/mongo/operation/write/create_index.rb +89 -0
  128. data/lib/mongo/operation/write/create_user.rb +75 -0
  129. data/lib/mongo/operation/write/delete/result.rb +40 -0
  130. data/lib/mongo/operation/write/delete.rb +93 -0
  131. data/lib/mongo/operation/write/drop_index.rb +62 -0
  132. data/lib/mongo/{utils/thread_local_variable_manager.rb → operation/write/insert/result.rb} +15 -8
  133. data/lib/mongo/operation/write/insert.rb +90 -0
  134. data/lib/mongo/operation/write/remove_user.rb +70 -0
  135. data/lib/mongo/operation/write/update/result.rb +160 -0
  136. data/lib/mongo/operation/write/update.rb +103 -0
  137. data/lib/mongo/{connection/socket/socket_util.rb → operation/write.rb} +10 -24
  138. data/lib/mongo/operation.rb +25 -0
  139. data/lib/mongo/options/mapper.rb +78 -0
  140. data/lib/mongo/options.rb +15 -0
  141. data/lib/mongo/protocol/bit_vector.rb +61 -0
  142. data/lib/mongo/protocol/delete.rb +94 -0
  143. data/lib/mongo/protocol/get_more.rb +99 -0
  144. data/lib/mongo/protocol/insert.rb +99 -0
  145. data/lib/mongo/protocol/kill_cursors.rb +74 -0
  146. data/lib/mongo/protocol/message.rb +252 -0
  147. data/lib/mongo/protocol/query.rb +147 -0
  148. data/lib/mongo/protocol/reply.rb +72 -0
  149. data/lib/mongo/protocol/serializers.rb +180 -0
  150. data/lib/mongo/protocol/update.rb +111 -0
  151. data/lib/mongo/protocol.rb +15 -0
  152. data/lib/mongo/server/connectable.rb +110 -0
  153. data/lib/mongo/server/connection.rb +134 -0
  154. data/lib/mongo/server/connection_pool/queue.rb +182 -0
  155. data/lib/mongo/server/connection_pool.rb +141 -0
  156. data/lib/mongo/server/context.rb +66 -0
  157. data/lib/mongo/server/description/features.rb +85 -0
  158. data/lib/mongo/server/description/inspector/primary_elected.rb +58 -0
  159. data/lib/mongo/server/description/inspector/server_added.rb +59 -0
  160. data/lib/mongo/server/description/inspector/server_removed.rb +59 -0
  161. data/lib/mongo/server/description/inspector.rb +79 -0
  162. data/lib/mongo/server/description.rb +450 -0
  163. data/lib/mongo/server/monitor/connection.rb +89 -0
  164. data/lib/mongo/server/monitor.rb +176 -0
  165. data/lib/mongo/server.rb +163 -0
  166. data/lib/mongo/server_selector/nearest.rb +94 -0
  167. data/lib/mongo/server_selector/primary.rb +88 -0
  168. data/lib/mongo/server_selector/primary_preferred.rb +94 -0
  169. data/lib/mongo/server_selector/secondary.rb +91 -0
  170. data/lib/mongo/server_selector/secondary_preferred.rb +96 -0
  171. data/lib/mongo/server_selector/selectable.rb +209 -0
  172. data/lib/mongo/server_selector.rb +81 -0
  173. data/lib/mongo/socket/ssl.rb +130 -0
  174. data/lib/mongo/socket/tcp.rb +69 -0
  175. data/lib/mongo/socket/unix.rb +64 -0
  176. data/lib/mongo/socket.rb +179 -0
  177. data/lib/mongo/uri.rb +504 -0
  178. data/lib/mongo/version.rb +21 -0
  179. data/lib/mongo/write_concern/acknowledged.rb +52 -0
  180. data/lib/mongo/write_concern/normalizable.rb +51 -0
  181. data/lib/mongo/write_concern/unacknowledged.rb +55 -0
  182. data/lib/mongo/write_concern.rb +99 -0
  183. data/lib/mongo.rb +24 -82
  184. data/mongo.gemspec +17 -14
  185. data/spec/certificates/ca.pem +17 -0
  186. data/spec/certificates/client.pem +101 -0
  187. data/spec/certificates/crl.pem +10 -0
  188. data/spec/certificates/crl_client_revoked.pem +12 -0
  189. data/spec/certificates/password_protected.pem +51 -0
  190. data/spec/certificates/server.pem +34 -0
  191. data/spec/mongo/address/ipv4_spec.rb +74 -0
  192. data/spec/mongo/address/ipv6_spec.rb +74 -0
  193. data/spec/mongo/address/unix_spec.rb +30 -0
  194. data/spec/mongo/address_spec.rb +206 -0
  195. data/spec/mongo/auth/cr_spec.rb +59 -0
  196. data/spec/mongo/auth/ldap_spec.rb +40 -0
  197. data/spec/mongo/auth/scram/conversation_spec.rb +197 -0
  198. data/spec/mongo/auth/scram_spec.rb +55 -0
  199. data/spec/mongo/auth/user/view_spec.rb +76 -0
  200. data/spec/mongo/auth/user_spec.rb +190 -0
  201. data/spec/mongo/auth/x509_spec.rb +40 -0
  202. data/spec/mongo/auth_spec.rb +65 -0
  203. data/spec/mongo/bulk/bulk_write_spec.rb +262 -0
  204. data/spec/mongo/client_spec.rb +564 -0
  205. data/spec/mongo/cluster/topology/replica_set_spec.rb +101 -0
  206. data/spec/mongo/cluster/topology/sharded_spec.rb +74 -0
  207. data/spec/mongo/cluster/topology/standalone_spec.rb +79 -0
  208. data/spec/mongo/cluster/topology_spec.rb +65 -0
  209. data/spec/mongo/cluster_spec.rb +129 -0
  210. data/spec/mongo/collection/view/aggregation_spec.rb +148 -0
  211. data/spec/mongo/collection/view/explainable_spec.rb +32 -0
  212. data/spec/mongo/collection/view/map_reduce_spec.rb +242 -0
  213. data/spec/mongo/collection/view/readable_spec.rb +603 -0
  214. data/spec/mongo/collection/view/writable_spec.rb +679 -0
  215. data/spec/mongo/collection/view_spec.rb +530 -0
  216. data/spec/mongo/collection_spec.rb +362 -0
  217. data/spec/mongo/crud_spec.rb +42 -0
  218. data/spec/mongo/cursor_spec.rb +295 -0
  219. data/spec/mongo/database_spec.rb +302 -0
  220. data/spec/mongo/error/parser_spec.rb +119 -0
  221. data/spec/mongo/event/publisher_spec.rb +50 -0
  222. data/spec/mongo/event/subscriber_spec.rb +34 -0
  223. data/spec/mongo/grid/file/chunk_spec.rb +226 -0
  224. data/spec/mongo/grid/file/metadata_spec.rb +92 -0
  225. data/spec/mongo/grid/file_spec.rb +172 -0
  226. data/spec/mongo/grid/fs_spec.rb +129 -0
  227. data/spec/mongo/index/view_spec.rb +330 -0
  228. data/spec/mongo/loggable_spec.rb +62 -0
  229. data/spec/mongo/logger_spec.rb +97 -0
  230. data/spec/mongo/operation/aggregate/result_spec.rb +80 -0
  231. data/spec/mongo/operation/aggregate_spec.rb +127 -0
  232. data/spec/mongo/operation/command_spec.rb +98 -0
  233. data/spec/mongo/operation/kill_cursors_spec.rb +66 -0
  234. data/spec/mongo/operation/limited_spec.rb +50 -0
  235. data/spec/mongo/operation/map_reduce_spec.rb +143 -0
  236. data/spec/mongo/operation/read/collections_info_spec.rb +40 -0
  237. data/spec/mongo/operation/read/get_more_spec.rb +81 -0
  238. data/spec/mongo/operation/read/indexes_spec.rb +31 -0
  239. data/spec/mongo/operation/read/query_spec.rb +84 -0
  240. data/spec/mongo/operation/result_spec.rb +275 -0
  241. data/spec/mongo/operation/specifiable_spec.rb +53 -0
  242. data/spec/mongo/operation/write/bulk_delete_spec.rb +235 -0
  243. data/spec/mongo/operation/write/bulk_insert_spec.rb +235 -0
  244. data/spec/mongo/operation/write/bulk_update_spec.rb +236 -0
  245. data/spec/mongo/operation/write/command/delete_spec.rb +103 -0
  246. data/spec/mongo/operation/write/command/insert_spec.rb +103 -0
  247. data/spec/mongo/operation/write/command/update_spec.rb +109 -0
  248. data/spec/mongo/operation/write/create_index_spec.rb +63 -0
  249. data/spec/mongo/operation/write/create_user_spec.rb +44 -0
  250. data/spec/mongo/operation/write/delete_spec.rb +186 -0
  251. data/spec/mongo/operation/write/drop_index_spec.rb +51 -0
  252. data/spec/mongo/operation/write/insert_spec.rb +244 -0
  253. data/spec/mongo/operation/write/remove_user_spec.rb +46 -0
  254. data/spec/mongo/operation/write/response_spec.rb +85 -0
  255. data/spec/mongo/operation/write/update_spec.rb +228 -0
  256. data/spec/mongo/protocol/delete_spec.rb +167 -0
  257. data/spec/mongo/protocol/get_more_spec.rb +146 -0
  258. data/spec/mongo/protocol/insert_spec.rb +161 -0
  259. data/spec/mongo/protocol/kill_cursors_spec.rb +101 -0
  260. data/spec/mongo/protocol/query_spec.rb +285 -0
  261. data/spec/mongo/protocol/reply_spec.rb +157 -0
  262. data/spec/mongo/protocol/update_spec.rb +186 -0
  263. data/spec/mongo/server/connection_pool/queue_spec.rb +170 -0
  264. data/spec/mongo/server/connection_pool_spec.rb +120 -0
  265. data/spec/mongo/server/connection_spec.rb +312 -0
  266. data/spec/mongo/server/description/features_spec.rb +138 -0
  267. data/spec/mongo/server/description/inspector/primary_elected_spec.rb +94 -0
  268. data/spec/mongo/server/description/inspector/server_added_spec.rb +92 -0
  269. data/spec/mongo/server/description/inspector/server_removed_spec.rb +95 -0
  270. data/spec/mongo/server/description_spec.rb +510 -0
  271. data/spec/mongo/server/monitor_spec.rb +144 -0
  272. data/spec/mongo/server_discovery_and_monitoring_spec.rb +103 -0
  273. data/spec/mongo/server_selection_rtt_spec.rb +104 -0
  274. data/spec/mongo/server_selection_spec.rb +89 -0
  275. data/spec/mongo/server_selector/nearest_spec.rb +250 -0
  276. data/spec/mongo/server_selector/primary_preferred_spec.rb +290 -0
  277. data/spec/mongo/server_selector/primary_spec.rb +114 -0
  278. data/spec/mongo/server_selector/secondary_preferred_spec.rb +252 -0
  279. data/spec/mongo/server_selector/secondary_spec.rb +196 -0
  280. data/spec/mongo/server_selector_spec.rb +101 -0
  281. data/spec/mongo/server_spec.rb +131 -0
  282. data/spec/mongo/uri_spec.rb +517 -0
  283. data/spec/mongo/write_concern/acknowledged_spec.rb +44 -0
  284. data/spec/mongo/write_concern/unacknowledged_spec.rb +15 -0
  285. data/spec/spec_helper.rb +133 -0
  286. data/spec/support/authorization.rb +247 -0
  287. data/spec/support/crud/read.rb +144 -0
  288. data/spec/support/crud/write.rb +214 -0
  289. data/spec/support/crud.rb +203 -0
  290. data/spec/support/crud_tests/read/aggregate.yml +43 -0
  291. data/spec/support/crud_tests/read/count.yml +37 -0
  292. data/spec/support/crud_tests/read/distinct.yml +33 -0
  293. data/spec/support/crud_tests/read/find.yml +50 -0
  294. data/spec/support/crud_tests/write/deleteMany.yml +36 -0
  295. data/spec/support/crud_tests/write/deleteOne.yml +49 -0
  296. data/spec/support/crud_tests/write/findOneAndDelete.yml +54 -0
  297. data/spec/support/crud_tests/write/findOneAndReplace.yml +153 -0
  298. data/spec/support/crud_tests/write/findOneAndUpdate.yml +161 -0
  299. data/spec/support/crud_tests/write/insertMany.yml +24 -0
  300. data/spec/support/crud_tests/write/insertOne.yml +19 -0
  301. data/spec/support/crud_tests/write/replaceOne.yml +96 -0
  302. data/spec/support/crud_tests/write/updateMany.yml +83 -0
  303. data/spec/support/crud_tests/write/updateOne.yml +80 -0
  304. data/spec/support/helpers.rb +140 -0
  305. data/spec/support/matchers.rb +37 -0
  306. data/spec/support/sdam/rs/discover_arbiters.yml +41 -0
  307. data/spec/support/sdam/rs/discover_passives.yml +41 -0
  308. data/spec/support/sdam/rs/discover_primary.yml +40 -0
  309. data/spec/support/sdam/rs/discover_secondary.yml +41 -0
  310. data/spec/support/sdam/rs/discovery.yml +195 -0
  311. data/spec/support/sdam/rs/ghost_discovered.yml +39 -0
  312. data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +34 -0
  313. data/spec/support/sdam/rs/member_reconfig.yml +68 -0
  314. data/spec/support/sdam/rs/member_standalone.yml +60 -0
  315. data/spec/support/sdam/rs/new_primary.yml +74 -0
  316. data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +71 -0
  317. data/spec/support/sdam/rs/non_rs_member.yml +31 -0
  318. data/spec/support/sdam/rs/normalize_case.yml +49 -0
  319. data/spec/support/sdam/rs/primary_becomes_standalone.yml +52 -0
  320. data/spec/support/sdam/rs/primary_changes_set_name.yml +57 -0
  321. data/spec/support/sdam/rs/primary_disconnect.yml +56 -0
  322. data/spec/support/sdam/rs/primary_wrong_set_name.yml +27 -0
  323. data/spec/support/sdam/rs/response_from_removed.yml +63 -0
  324. data/spec/support/sdam/rs/rsother_discovered.yml +41 -0
  325. data/spec/support/sdam/rs/sec_not_auth.yml +49 -0
  326. data/spec/support/sdam/rs/secondary_wrong_set_name.yml +28 -0
  327. data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +69 -0
  328. data/spec/support/sdam/rs/unexpected_mongos.yml +26 -0
  329. data/spec/support/sdam/rs/wrong_set_name.yml +35 -0
  330. data/spec/support/sdam/sharded/multiple_mongoses.yml +46 -0
  331. data/spec/support/sdam/sharded/non_mongos_removed.yml +41 -0
  332. data/spec/support/sdam/sharded/normalize_uri_case.yml +32 -0
  333. data/spec/support/sdam/single/direct_connection_external_ip.yml +34 -0
  334. data/spec/support/sdam/single/direct_connection_mongos.yml +33 -0
  335. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +35 -0
  336. data/spec/support/sdam/single/direct_connection_rsprimary.yml +34 -0
  337. data/spec/support/sdam/single/direct_connection_rssecondary.yml +35 -0
  338. data/spec/support/sdam/single/direct_connection_slave.yml +32 -0
  339. data/spec/support/sdam/single/direct_connection_standalone.yml +32 -0
  340. data/spec/support/sdam/single/not_ok_response.yml +39 -0
  341. data/spec/support/sdam/single/standalone_removed.yml +32 -0
  342. data/spec/support/sdam/single/unavailable_seed.yml +28 -0
  343. data/spec/support/server_discovery_and_monitoring.rb +167 -0
  344. data/spec/support/server_selection/rtt/first_value.yml +4 -0
  345. data/spec/support/server_selection/rtt/first_value_zero.yml +4 -0
  346. data/spec/support/server_selection/rtt/value_test_1.yml +4 -0
  347. data/spec/support/server_selection/rtt/value_test_2.yml +4 -0
  348. data/spec/support/server_selection/rtt/value_test_3.yml +4 -0
  349. data/spec/support/server_selection/rtt/value_test_4.yml +4 -0
  350. data/spec/support/server_selection/rtt/value_test_5.yml +4 -0
  351. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest.yml +26 -0
  352. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_non_matching.yml +21 -0
  353. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Primary.yml +21 -0
  354. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred.yml +26 -0
  355. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/PrimaryPreferred_non_matching.yml +21 -0
  356. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary.yml +26 -0
  357. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred.yml +26 -0
  358. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/SecondaryPreferred_non_matching.yml +21 -0
  359. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_non_matching.yml +21 -0
  360. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest.yml +33 -0
  361. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_non_matching.yml +26 -0
  362. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Primary.yml +29 -0
  363. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred.yml +29 -0
  364. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/PrimaryPreferred_non_matching.yml +29 -0
  365. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary.yml +31 -0
  366. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred.yml +31 -0
  367. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred_non_matching.yml +29 -0
  368. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Secondary_non_matching.yml +26 -0
  369. data/spec/support/server_selection/selection/Sharded/read/SecondaryPreferred.yml +26 -0
  370. data/spec/support/server_selection/selection/Single/read/SecondaryPreferred.yml +19 -0
  371. data/spec/support/server_selection/selection/Unknown/read/SecondaryPreferred.yml +11 -0
  372. data/spec/support/server_selection.rb +157 -0
  373. data/spec/support/server_selection_rtt.rb +41 -0
  374. data/spec/support/shared/bulk_write.rb +535 -0
  375. data/spec/support/shared/cursor.rb +38 -0
  376. data/spec/support/shared/operation.rb +77 -0
  377. data/spec/support/shared/protocol.rb +31 -0
  378. data/spec/support/shared/server_selector.rb +111 -0
  379. data/spec/support/shared/socket.rb +82 -0
  380. data/spec/support/travis.rb +14 -0
  381. data.tar.gz.sig +2 -3
  382. metadata +583 -186
  383. metadata.gz.sig +0 -0
  384. data/VERSION +0 -1
  385. data/lib/mongo/bulk_write_collection_view.rb +0 -387
  386. data/lib/mongo/collection_writer.rb +0 -364
  387. data/lib/mongo/connection/node.rb +0 -249
  388. data/lib/mongo/connection/pool.rb +0 -340
  389. data/lib/mongo/connection/pool_manager.rb +0 -320
  390. data/lib/mongo/connection/sharding_pool_manager.rb +0 -67
  391. data/lib/mongo/connection/socket/ssl_socket.rb +0 -95
  392. data/lib/mongo/connection/socket/tcp_socket.rb +0 -87
  393. data/lib/mongo/connection/socket/unix_socket.rb +0 -39
  394. data/lib/mongo/db.rb +0 -808
  395. data/lib/mongo/exception.rb +0 -145
  396. data/lib/mongo/functional/authentication.rb +0 -455
  397. data/lib/mongo/functional/logging.rb +0 -85
  398. data/lib/mongo/functional/read_preference.rb +0 -183
  399. data/lib/mongo/functional/scram.rb +0 -556
  400. data/lib/mongo/functional/uri_parser.rb +0 -409
  401. data/lib/mongo/functional/write_concern.rb +0 -66
  402. data/lib/mongo/gridfs/grid.rb +0 -112
  403. data/lib/mongo/gridfs/grid_ext.rb +0 -53
  404. data/lib/mongo/gridfs/grid_file_system.rb +0 -163
  405. data/lib/mongo/gridfs/grid_io.rb +0 -484
  406. data/lib/mongo/legacy.rb +0 -140
  407. data/lib/mongo/mongo_client.rb +0 -697
  408. data/lib/mongo/mongo_replica_set_client.rb +0 -535
  409. data/lib/mongo/mongo_sharded_client.rb +0 -159
  410. data/lib/mongo/networking.rb +0 -372
  411. data/lib/mongo/utils/conversions.rb +0 -110
  412. data/lib/mongo/utils/core_ext.rb +0 -70
  413. data/lib/mongo/utils/server_version.rb +0 -69
  414. data/lib/mongo/utils/support.rb +0 -80
  415. data/test/functional/authentication_test.rb +0 -39
  416. data/test/functional/bulk_api_stress_test.rb +0 -133
  417. data/test/functional/bulk_write_collection_view_test.rb +0 -1198
  418. data/test/functional/client_test.rb +0 -627
  419. data/test/functional/collection_test.rb +0 -2175
  420. data/test/functional/collection_writer_test.rb +0 -83
  421. data/test/functional/conversions_test.rb +0 -163
  422. data/test/functional/cursor_fail_test.rb +0 -57
  423. data/test/functional/cursor_message_test.rb +0 -56
  424. data/test/functional/cursor_test.rb +0 -683
  425. data/test/functional/db_api_test.rb +0 -835
  426. data/test/functional/db_test.rb +0 -348
  427. data/test/functional/grid_file_system_test.rb +0 -285
  428. data/test/functional/grid_io_test.rb +0 -252
  429. data/test/functional/grid_test.rb +0 -273
  430. data/test/functional/pool_test.rb +0 -136
  431. data/test/functional/safe_test.rb +0 -98
  432. data/test/functional/support_test.rb +0 -62
  433. data/test/functional/timeout_test.rb +0 -60
  434. data/test/functional/uri_test.rb +0 -446
  435. data/test/functional/write_concern_test.rb +0 -118
  436. data/test/helpers/general.rb +0 -50
  437. data/test/helpers/test_unit.rb +0 -476
  438. data/test/replica_set/authentication_test.rb +0 -37
  439. data/test/replica_set/basic_test.rb +0 -189
  440. data/test/replica_set/client_test.rb +0 -393
  441. data/test/replica_set/connection_test.rb +0 -138
  442. data/test/replica_set/count_test.rb +0 -66
  443. data/test/replica_set/cursor_test.rb +0 -220
  444. data/test/replica_set/insert_test.rb +0 -157
  445. data/test/replica_set/max_values_test.rb +0 -151
  446. data/test/replica_set/pinning_test.rb +0 -105
  447. data/test/replica_set/query_test.rb +0 -73
  448. data/test/replica_set/read_preference_test.rb +0 -219
  449. data/test/replica_set/refresh_test.rb +0 -211
  450. data/test/replica_set/replication_ack_test.rb +0 -95
  451. data/test/sharded_cluster/basic_test.rb +0 -203
  452. data/test/shared/authentication/basic_auth_shared.rb +0 -260
  453. data/test/shared/authentication/bulk_api_auth_shared.rb +0 -249
  454. data/test/shared/authentication/gssapi_shared.rb +0 -176
  455. data/test/shared/authentication/sasl_plain_shared.rb +0 -96
  456. data/test/shared/authentication/scram_shared.rb +0 -92
  457. data/test/shared/ssl_shared.rb +0 -235
  458. data/test/test_helper.rb +0 -61
  459. data/test/threading/basic_test.rb +0 -120
  460. data/test/tools/mongo_config.rb +0 -708
  461. data/test/tools/mongo_config_test.rb +0 -160
  462. data/test/unit/client_test.rb +0 -381
  463. data/test/unit/collection_test.rb +0 -166
  464. data/test/unit/connection_test.rb +0 -335
  465. data/test/unit/cursor_test.rb +0 -307
  466. data/test/unit/db_test.rb +0 -136
  467. data/test/unit/grid_test.rb +0 -76
  468. data/test/unit/mongo_sharded_client_test.rb +0 -48
  469. data/test/unit/node_test.rb +0 -93
  470. data/test/unit/pool_manager_test.rb +0 -111
  471. data/test/unit/read_pref_test.rb +0 -406
  472. data/test/unit/read_test.rb +0 -159
  473. data/test/unit/safe_test.rb +0 -158
  474. data/test/unit/sharding_pool_manager_test.rb +0 -84
  475. data/test/unit/write_concern_test.rb +0 -175
@@ -0,0 +1,247 @@
1
+ # Copyright (C) 2009-2014 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
+ # The default test database for all specs.
16
+ #
17
+ # @since 2.0.0
18
+ TEST_DB = 'ruby-driver'.freeze
19
+
20
+ # The default test collection.
21
+ #
22
+ # @since 2.0.0
23
+ TEST_COLL = 'test'.freeze
24
+
25
+ # The seed addresses to be used when creating a client.
26
+ #
27
+ # @since 2.0.0
28
+ ADDRESSES = ENV['MONGODB_ADDRESSES'] ? ENV['MONGODB_ADDRESSES'].split(',').freeze :
29
+ [ '127.0.0.1:27017' ].freeze
30
+
31
+ # A default address to use in tests.
32
+ #
33
+ # @since 2.0.0
34
+ DEFAULT_ADDRESS = ADDRESSES.first
35
+
36
+ # The topology type.
37
+ #
38
+ # @since 2.0.0
39
+ CONNECT = ENV['RS_ENABLED'] == 'true' ? :replica_set.freeze :
40
+ ENV['SHARDED_ENABLED'] == 'true' ? :sharded.freeze :
41
+ :direct.freeze
42
+
43
+ # The root user name.
44
+ #
45
+ # @since 2.0.0
46
+ ROOT_USER_NAME = ENV['ROOT_USER_NAME'] || 'root-user'
47
+
48
+ # The root user password.
49
+ #
50
+ # @since 2.0.0
51
+ ROOT_USER_PWD = ENV['ROOT_USER_PWD'] || 'password'
52
+
53
+ # Gets the root system administrator user.
54
+ #
55
+ # @since 2.0.0
56
+ ROOT_USER = Mongo::Auth::User.new(
57
+ database: Mongo::Database::ADMIN,
58
+ user: ROOT_USER_NAME,
59
+ password: ROOT_USER_PWD,
60
+ roles: [
61
+ Mongo::Auth::Roles::USER_ADMIN_ANY_DATABASE,
62
+ Mongo::Auth::Roles::DATABASE_ADMIN_ANY_DATABASE,
63
+ Mongo::Auth::Roles::READ_WRITE_ANY_DATABASE,
64
+ Mongo::Auth::Roles::HOST_MANAGER
65
+ ]
66
+ )
67
+
68
+ # Get the default test user for the suite on versions 2.6 and higher.
69
+ #
70
+ # @since 2.0.0
71
+ TEST_USER = Mongo::Auth::User.new(
72
+ database: Mongo::Database::ADMIN,
73
+ user: 'test-user',
74
+ password: 'password',
75
+ roles: [
76
+ { role: Mongo::Auth::Roles::READ_WRITE, db: TEST_DB },
77
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: TEST_DB },
78
+ { role: Mongo::Auth::Roles::READ_WRITE, db: 'invalid_database' },
79
+ { role: Mongo::Auth::Roles::DATABASE_ADMIN, db: 'invalid_database' }
80
+ ]
81
+ )
82
+
83
+ # MongoDB 2.4 and lower does not allow hashes as roles, so we need to create a
84
+ # user on those versions for each database permission in order to ensure the
85
+ # legacy roles work with users. The following users are those.
86
+
87
+ # Gets the default test user for the suite on 2.4 and lower.
88
+ #
89
+ # @since 2.0.
90
+ TEST_READ_WRITE_USER = Mongo::Auth::User.new(
91
+ database: TEST_DB,
92
+ user: 'test-user',
93
+ password: 'password',
94
+ roles: [ Mongo::Auth::Roles::READ_WRITE, Mongo::Auth::Roles::DATABASE_ADMIN ]
95
+ )
96
+
97
+ # The write concern to use in the tests.
98
+ #
99
+ # @since 2.0.0
100
+ WRITE_CONCERN = (CONNECT == :replica_set) ? { w: ADDRESSES.size } : { w: 1 }
101
+
102
+ # Provides an authorized mongo client on the default test database for the
103
+ # default test user.
104
+ #
105
+ # @since 2.0.0
106
+ AUTHORIZED_CLIENT = Mongo::Client.new(
107
+ ADDRESSES,
108
+ database: TEST_DB,
109
+ user: TEST_USER.name,
110
+ password: TEST_USER.password,
111
+ max_pool_size: 1,
112
+ write: WRITE_CONCERN,
113
+ connect: CONNECT
114
+ )
115
+
116
+ # Provides an authorized mongo client on the default test database for the
117
+ # default root system administrator.
118
+ #
119
+ # @since 2.0.0
120
+ ROOT_AUTHORIZED_CLIENT = Mongo::Client.new(
121
+ ADDRESSES,
122
+ auth_source: Mongo::Database::ADMIN,
123
+ database: TEST_DB,
124
+ user: ROOT_USER.name,
125
+ password: ROOT_USER.password,
126
+ max_pool_size: 1,
127
+ write: WRITE_CONCERN,
128
+ connect: CONNECT
129
+ )
130
+
131
+ # Provides an unauthorized mongo client on the default test database.
132
+ #
133
+ # @since 2.0.0
134
+ UNAUTHORIZED_CLIENT = Mongo::Client.new(
135
+ ADDRESSES,
136
+ database: TEST_DB,
137
+ max_pool_size: 1,
138
+ write: WRITE_CONCERN,
139
+ connect: CONNECT
140
+ )
141
+
142
+ # Provides an unauthorized mongo client on the admin database, for use in
143
+ # setting up the first admin root user.
144
+ #
145
+ # @since 2.0.0
146
+ ADMIN_UNAUTHORIZED_CLIENT = Mongo::Client.new(
147
+ ADDRESSES,
148
+ database: Mongo::Database::ADMIN,
149
+ max_pool_size: 1,
150
+ write: WRITE_CONCERN,
151
+ connect: CONNECT
152
+ )
153
+
154
+ # Get an authorized client on the admin database logged in as the admin
155
+ # root user.
156
+ #
157
+ # @since 2.0.0
158
+ ADMIN_AUTHORIZED_CLIENT = ADMIN_UNAUTHORIZED_CLIENT.with(
159
+ user: ROOT_USER.name,
160
+ password: ROOT_USER.password
161
+ )
162
+
163
+ module Authorization
164
+
165
+ # On inclusion provides helpers for use with testing with and without
166
+ # authorization.
167
+ #
168
+ #
169
+ # @since 2.0.0
170
+ def self.included(context)
171
+
172
+ # Gets the root system administrator user.
173
+ #
174
+ # @since 2.0.0
175
+ context.let(:root_user) { ROOT_USER }
176
+
177
+ # Get the default test user for the suite.
178
+ #
179
+ # @since 2.0.0
180
+ context.let(:test_user) { TEST_USER }
181
+
182
+ # Provides an authorized mongo client on the default test database for the
183
+ # default test user.
184
+ #
185
+ # @since 2.0.0
186
+ context.let(:authorized_client) { AUTHORIZED_CLIENT }
187
+
188
+ # Provides an authorized mongo client on the default test database for the
189
+ # default root system administrator.
190
+ #
191
+ # @since 2.0.0
192
+ context.let(:root_authorized_client) { ROOT_AUTHORIZED_CLIENT }
193
+
194
+ # Provides an unauthorized mongo client on the default test database.
195
+ #
196
+ # @since 2.0.0
197
+ context.let!(:unauthorized_client) { UNAUTHORIZED_CLIENT }
198
+
199
+ # Provides an unauthorized mongo client on the admin database, for use in
200
+ # setting up the first admin root user.
201
+ #
202
+ # @since 2.0.0
203
+ context.let!(:admin_unauthorized_client) { ADMIN_UNAUTHORIZED_CLIENT }
204
+
205
+ # Get an authorized client on the admin database logged in as the admin
206
+ # root user.
207
+ #
208
+ # @since 2.0.0
209
+ context.let!(:admin_authorized_client) { ADMIN_AUTHORIZED_CLIENT }
210
+
211
+ # Gets the default test collection from the authorized client.
212
+ #
213
+ # @since 2.0.0
214
+ context.let(:authorized_collection) do
215
+ authorized_client[TEST_COLL]
216
+ end
217
+
218
+ # Gets the default test collection from the unauthorized client.
219
+ #
220
+ # @since 2.0.0
221
+ context.let(:unauthorized_collection) do
222
+ unauthorized_client[TEST_COLL]
223
+ end
224
+
225
+ # Gets a primary server for the default authorized client.
226
+ #
227
+ # @since 2.0.0
228
+ context.let(:authorized_primary) do
229
+ authorized_client.cluster.next_primary
230
+ end
231
+
232
+ # Get a primary server for the client authorized as the root system
233
+ # administrator.
234
+ #
235
+ # @since 2.0.0
236
+ context.let(:root_authorized_primary) do
237
+ root_authorized_client.cluster.next_primary
238
+ end
239
+
240
+ # Get a primary server from the unauthorized client.
241
+ #
242
+ # @since 2.0.0
243
+ context.let(:unauthorized_primary) do
244
+ authorized_client.cluster.next_primary
245
+ end
246
+ end
247
+ end
@@ -0,0 +1,144 @@
1
+ # Copyright (C) 2014-2015 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
+ module Mongo
16
+ module CRUD
17
+ module Operation
18
+
19
+ # Defines common behaviour for running CRUD read operation tests
20
+ # on a collection.
21
+ #
22
+ # @since 2.0.0
23
+ class Read
24
+
25
+ # Map of method names to test operation argument names.
26
+ #
27
+ # @since 2.0.0
28
+ ARGUMENT_MAP = { :sort => 'sort',
29
+ :skip => 'skip',
30
+ :batch_size => 'batch_size',
31
+ :limit => 'limit'
32
+ }
33
+
34
+ # The operation name.
35
+ #
36
+ # @return [ String ] name The operation name.
37
+ #
38
+ # @since 2.0.0
39
+ attr_reader :name
40
+
41
+ # Instantiate the operation.
42
+ #
43
+ # @return [ Hash ] spec The operation spec.
44
+ #
45
+ # @since 2.0.0
46
+ def initialize(spec)
47
+ @spec = spec
48
+ @name = spec['name']
49
+ end
50
+
51
+ # Execute the operation.
52
+ #
53
+ # @example Execute the operation.
54
+ # operation.execute
55
+ #
56
+ # @param [ Collection ] collection The collection to execute the operation on.
57
+ #
58
+ # @return [ Result, Array<Hash> ] The result of executing the operation.
59
+ #
60
+ # @since 2.0.0
61
+ def execute(collection)
62
+ send(name.to_sym, collection)
63
+ end
64
+
65
+ # Whether the operation is expected to have restuls.
66
+ #
67
+ # @example Whether the operation is expected to have results.
68
+ # operation.has_results?
69
+ #
70
+ # @return [ true, false ] If the operation is expected to have results.
71
+ #
72
+ # @since 2.0.0
73
+ def has_results?
74
+ !(name == 'aggregate' &&
75
+ pipeline.find {|op| op.keys.include?('$out') })
76
+ end
77
+
78
+ # Whether the operation requires server version >= 2.6 for its results to
79
+ # match expected results.
80
+ #
81
+ # @example Whether the operation requires >= 2.6 for its results to match.
82
+ # operation.requires_2_6?(collection)
83
+ #
84
+ # @param [ Collection ] collection The collection the operation is executed on.
85
+ #
86
+ # @return [ true, false ] If the operation requires 2.6 for its results to match.
87
+ #
88
+ # @since 2.0.0
89
+ def requires_2_6?(collection)
90
+ name == 'aggregate' && pipeline.find {|op| op.keys.include?('$out') }
91
+ end
92
+
93
+ private
94
+
95
+ def count(collection)
96
+ view = collection.find(filter)
97
+ options = ARGUMENT_MAP.reduce({}) do |opts, (key, value)|
98
+ opts.merge!(key => arguments[value]) if arguments[value]
99
+ opts
100
+ end
101
+ view.count(options)
102
+ end
103
+
104
+ def aggregate(collection)
105
+ collection.find.tap do |view|
106
+ view = view.batch_size(batch_size) if batch_size
107
+ end.aggregate(pipeline).to_a
108
+ end
109
+
110
+ def distinct(collection)
111
+ collection.find(filter).distinct(field_name)
112
+ end
113
+
114
+ def find(collection)
115
+ view = collection.find(filter)
116
+ ARGUMENT_MAP.each do |key, value|
117
+ view = view.send(key, arguments[value]) if arguments[value]
118
+ end
119
+ view.to_a
120
+ end
121
+
122
+ def batch_size
123
+ arguments['batchSize']
124
+ end
125
+
126
+ def filter
127
+ arguments['filter']
128
+ end
129
+
130
+ def pipeline
131
+ arguments['pipeline']
132
+ end
133
+
134
+ def field_name
135
+ arguments['fieldName']
136
+ end
137
+
138
+ def arguments
139
+ @spec['arguments']
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,214 @@
1
+ # Copyright (C) 2014-2015 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
+ module Mongo
16
+ module CRUD
17
+ module Operation
18
+
19
+ # Defines common behaviour for running CRUD write operation tests on a
20
+ # collection.
21
+ #
22
+ # @since 2.0.0
23
+ class Write
24
+
25
+ # Map of CRUD operation names to method names.
26
+ #
27
+ # @since 2.0.0
28
+ OPERATIONS = { 'deleteMany' => :delete_many,
29
+ 'deleteOne' => :delete_one,
30
+ 'insertMany' => :insert_many,
31
+ 'insertOne' => :insert_one,
32
+ 'replaceOne' => :replace_one,
33
+ 'updateMany' => :update_many,
34
+ 'updateOne' => :update_one,
35
+ 'findOneAndDelete' => :find_one_and_delete,
36
+ 'findOneAndReplace' => :find_one_and_replace,
37
+ 'findOneAndUpdate' => :find_one_and_update
38
+ }
39
+
40
+ # Map of operation options to method names.
41
+ #
42
+ # @since 2.0.0
43
+ ARGUMENT_MAP = {
44
+ :sort => 'sort',
45
+ :projection => 'projection'
46
+ }
47
+
48
+ # Operations that need a check if results on < 2.6 will match.
49
+ #
50
+ # @since 2.0.0
51
+ REQUIRES_2_6 = ['findOneAndReplace',
52
+ 'updateMany',
53
+ 'updateOne',
54
+ 'replaceOne']
55
+
56
+ # The operation name.
57
+ #
58
+ # @return [ String ] name The operation name.
59
+ #
60
+ # @since 2.0.0
61
+ attr_reader :name
62
+
63
+ def initialize(spec)
64
+ @spec = spec
65
+ @name = spec['name']
66
+ end
67
+
68
+ # Whether the operation is expected to have restuls.
69
+ #
70
+ # @example Whether the operation is expected to have results.
71
+ # operation.has_results?
72
+ #
73
+ # @return [ true ] If the operation is expected to have results.
74
+ #
75
+ # @since 2.0.0
76
+ def has_results?
77
+ true
78
+ end
79
+
80
+ # Execute the operation.
81
+ #
82
+ # @example Execute the operation.
83
+ # operation.execute
84
+ #
85
+ # @param [ Collection ] collection The collection to execute
86
+ # the operation on.
87
+ #
88
+ # @return [ Result, Array<Hash> ] The result of executing the operation.
89
+ #
90
+ # @since 2.0.0
91
+ def execute(collection)
92
+ send(OPERATIONS[name], collection)
93
+ end
94
+
95
+ # Whether this operation requires >= 2.6 to be tested.
96
+ #
97
+ # @example Determine whether this operation requires >= 2.6.
98
+ # operation.requires_2_6?(collection)
99
+ #
100
+ # @param [ Collection ] collection The collection the operation
101
+ # should be executed on.
102
+ #
103
+ # @return [ true, false ] Whether this operation requires 2.6
104
+ # to be tested.
105
+ #
106
+ # @since 2.0.0
107
+ def requires_2_6?(collection)
108
+ REQUIRES_2_6.include?(name) && upsert
109
+ end
110
+
111
+ private
112
+
113
+ def delete_many(collection)
114
+ result = collection.find(filter).delete_many
115
+ { 'deletedCount' => result.deleted_count }
116
+ end
117
+
118
+ def delete_one(collection)
119
+ result = collection.find(filter).delete_one
120
+ { 'deletedCount' => result.deleted_count }
121
+ end
122
+
123
+ def insert_many(collection)
124
+ collection.insert_many(documents)
125
+ # returning inserted_ids is optional
126
+ { 'insertedIds' => documents.collect { |d| d['_id'] } }
127
+ end
128
+
129
+ def insert_one(collection)
130
+ result = collection.insert_one(document)
131
+ # returning inserted_id is optional
132
+ { 'insertedId' => document['_id'] }
133
+ end
134
+
135
+ def update_return_doc(result)
136
+ return_doc = { 'upsertedId' => result.upserted_id } if upsert
137
+ (return_doc || {}).merge!({ 'matchedCount' => result.matched_count,
138
+ 'modifiedCount' => result.modified_count })
139
+ end
140
+
141
+ def replace_one(collection)
142
+ result = collection.find(filter).replace_one(replacement, upsert: upsert)
143
+ update_return_doc(result)
144
+ end
145
+
146
+ def update_many(collection)
147
+ result = collection.find(filter).update_many(update, upsert: upsert)
148
+ update_return_doc(result)
149
+ end
150
+
151
+ def update_one(collection)
152
+ result = collection.find(filter).update_one(update, upsert: upsert)
153
+ update_return_doc(result)
154
+ end
155
+
156
+ def find_one_and_delete(collection)
157
+ view = collection.find(filter)
158
+ ARGUMENT_MAP.each do |key, value|
159
+ view = view.send(key, arguments[value]) if arguments[value]
160
+ end
161
+ view.find_one_and_delete
162
+ end
163
+
164
+ def find_one_and_replace(collection)
165
+ view = collection.find(filter)
166
+ ARGUMENT_MAP.each do |key, value|
167
+ view = view.send(key, arguments[value]) if arguments[value]
168
+ end
169
+ view.find_one_and_replace(replacement, upsert: upsert, return_document: return_document)
170
+ end
171
+
172
+ def find_one_and_update(collection)
173
+ view = collection.find(filter)
174
+ ARGUMENT_MAP.each do |key, value|
175
+ view = view.send(key, arguments[value]) if arguments[value]
176
+ end
177
+ view.find_one_and_update(update, upsert: upsert, return_document: return_document)
178
+ end
179
+
180
+ def replacement
181
+ arguments['replacement']
182
+ end
183
+
184
+ def documents
185
+ arguments['documents']
186
+ end
187
+
188
+ def document
189
+ arguments['document']
190
+ end
191
+
192
+ def filter
193
+ arguments['filter']
194
+ end
195
+
196
+ def upsert
197
+ arguments['upsert']
198
+ end
199
+
200
+ def return_document
201
+ :after if arguments['returnDocument']
202
+ end
203
+
204
+ def update
205
+ arguments['update']
206
+ end
207
+
208
+ def arguments
209
+ @spec['arguments']
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end