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
data/lib/mongo/db.rb DELETED
@@ -1,808 +0,0 @@
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
- module Mongo
16
-
17
- # A MongoDB database.
18
- class DB
19
- include Mongo::WriteConcern
20
-
21
- SYSTEM_NAMESPACE_COLLECTION = 'system.namespaces'
22
- SYSTEM_INDEX_COLLECTION = 'system.indexes'
23
- SYSTEM_PROFILE_COLLECTION = 'system.profile'
24
- SYSTEM_USER_COLLECTION = 'system.users'
25
- SYSTEM_JS_COLLECTION = 'system.js'
26
- SYSTEM_COMMAND_COLLECTION = '$cmd'
27
- MAX_TIME_MS_CODE = 50
28
-
29
- PROFILE_LEVEL = {
30
- :off => 0,
31
- :slow_only => 1,
32
- :all => 2
33
- }
34
-
35
- # Counter for generating unique request ids.
36
- @@current_request_id = 0
37
-
38
- # Strict mode enforces collection existence checks. When +true+,
39
- # asking for a collection that does not exist, or trying to create a
40
- # collection that already exists, raises an error.
41
- #
42
- # Strict mode is disabled by default, but enabled (+true+) at any time.
43
- #
44
- # @deprecated Support for strict will be removed in version 2.0 of the driver.
45
- def strict=(value)
46
- unless ENV['TEST_MODE']
47
- warn "Support for strict mode has been deprecated and will be " +
48
- "removed in version 2.0 of the driver."
49
- end
50
- @strict = value
51
- end
52
-
53
- # Returns the value of the +strict+ flag.
54
- #
55
- # @deprecated Support for strict will be removed in version 2.0 of the driver.
56
- def strict?
57
- @strict
58
- end
59
-
60
- # The name of the database and the local write concern options.
61
- attr_reader :name, :write_concern
62
-
63
- # The Mongo::MongoClient instance connecting to the MongoDB server.
64
- attr_reader :client
65
-
66
- # for backward compatibility
67
- alias_method :connection, :client
68
-
69
- # The length of time that Collection.ensure_index should cache index calls
70
- attr_accessor :cache_time
71
-
72
- # Read Preference
73
- attr_accessor :read, :tag_sets, :acceptable_latency
74
-
75
- # Instances of DB are normally obtained by calling Mongo#db.
76
- #
77
- # @param [String] name the database name.
78
- # @param [Mongo::MongoClient] client a connection object pointing to MongoDB. Note
79
- # that databases are usually instantiated via the MongoClient class. See the examples below.
80
- #
81
- # @option opts [Boolean] :strict (False) [DEPRECATED] If true, collections existence checks are
82
- # performed during a number of relevant operations. See DB#collection, DB#create_collection and
83
- # DB#drop_collection.
84
- #
85
- # @option opts [Object, #create_pk(doc)] :pk (BSON::ObjectId) A primary key factory object,
86
- # which should take a hash and return a hash which merges the original hash with any primary key
87
- # fields the factory wishes to inject. (NOTE: if the object already has a primary key,
88
- # the factory should not inject a new key).
89
- #
90
- # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
91
- # should be acknowledged.
92
- # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
93
- # @option opts [Boolean] :j (false) If true, block until write operations have been committed
94
- # to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
95
- # ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
96
- # fail with an exception if this option is used when the server is running without journaling.
97
- # @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
98
- # the server has synced all data files to disk. If the server is running with journaling, this acts the same as
99
- # the 'j' option, blocking until write operations have been committed to the journal.
100
- # Cannot be used in combination with 'j'.
101
- #
102
- # Notes on write concern:
103
- # These write concern options are propagated to Collection objects instantiated off of this DB. If no
104
- # options are provided, the default write concern set on this instance's MongoClient object will be used. This
105
- # default can be overridden upon instantiation of any collection by explicitly setting write concern options
106
- # on initialization or at the time of an operation.
107
- #
108
- # @option opts [Integer] :cache_time (300) Set the time that all ensure_index calls should cache the command.
109
-
110
- def initialize(name, client, opts={})
111
- # A database name of '$external' is permitted for some auth types
112
- Support.validate_db_name(name) unless name == '$external'
113
-
114
- @name = name
115
- @client = client
116
- @strict = opts[:strict]
117
- @pk_factory = opts[:pk]
118
-
119
- @write_concern = get_write_concern(opts, client)
120
-
121
- @read = opts[:read] || @client.read
122
- ReadPreference::validate(@read)
123
-
124
- @tag_sets = opts.fetch(:tag_sets, @client.tag_sets)
125
- @acceptable_latency = opts.fetch(:acceptable_latency,
126
- @client.acceptable_latency)
127
-
128
- @cache_time = opts[:cache_time] || 300 #5 minutes.
129
- end
130
-
131
- # Authenticate with the given username and password.
132
- #
133
- # @param username [String] The username.
134
- # @param password [String] The user's password. This is not required for
135
- # some authentication mechanisms.
136
- # @param save_auth [Boolean]
137
- # Save this authentication to the client object using
138
- # MongoClient#add_auth. This will ensure that the authentication will
139
- # be applied to all sockets and upon database reconnect.
140
- # @param source [String] Database with user credentials. This should be
141
- # used to authenticate against a database when the credentials exist
142
- # elsewhere.
143
- # @param mechanism [String] The authentication mechanism to be used.
144
- # @param extra [Hash] A optional hash of extra options to be stored with
145
- # the credential set.
146
- #
147
- # @note The ability to disable the save_auth option has been deprecated.
148
- # With save_auth=false specified, driver authentication behavior during
149
- # failovers and reconnections becomes unreliable. This option still
150
- # exists for API compatibility, but it no longer has any effect if
151
- # disabled and now always uses the default behavior (safe_auth=true).
152
- #
153
- # @raise [AuthenticationError] Raised if authentication fails.
154
- # @return [Boolean] The result of the authentication operation.
155
- def authenticate(username, password=nil, save_auth=nil, source=nil, mechanism=nil, extra=nil)
156
- warn "[DEPRECATED] Disabling the 'save_auth' option no longer has " +
157
- "any effect. Please see the API documentation for more details " +
158
- "on this change." unless save_auth.nil?
159
- @client.add_auth(self.name, username, password, source, mechanism, extra)
160
- true
161
- end
162
-
163
- # Deauthorizes use for this database for this client connection. Also removes
164
- # the saved authentication in the MongoClient class associated with this
165
- # database.
166
- #
167
- # @return [Boolean]
168
- def logout(opts={})
169
- @client.remove_auth(self.name)
170
- true
171
- end
172
-
173
- # Adds a stored Javascript function to the database which can executed
174
- # server-side in map_reduce, db.eval and $where clauses.
175
- #
176
- # @param [String] function_name
177
- # @param [String] code
178
- #
179
- # @return [String] the function name saved to the database
180
- def add_stored_function(function_name, code)
181
- self[SYSTEM_JS_COLLECTION].save(
182
- {
183
- "_id" => function_name,
184
- :value => BSON::Code.new(code)
185
- }
186
- )
187
- end
188
-
189
- # Removes stored Javascript function from the database. Returns
190
- # false if the function does not exist
191
- #
192
- # @param [String] function_name
193
- #
194
- # @return [Boolean]
195
- def remove_stored_function(function_name)
196
- return false unless self[SYSTEM_JS_COLLECTION].find_one({"_id" => function_name})
197
- self[SYSTEM_JS_COLLECTION].remove({"_id" => function_name}, :w => 1)
198
- end
199
-
200
- # Adds a user to this database for use with authentication. If the user already
201
- # exists in the system, the password and any additional fields provided in opts
202
- # will be updated.
203
- #
204
- # @param [String] username
205
- # @param [String] password
206
- # @param [Boolean] read_only
207
- # Create a read-only user.
208
- #
209
- # @param [Hash] opts
210
- # Optional fields for the user document (e.g. +userSource+, or +roles+)
211
- #
212
- # See {http://docs.mongodb.org/manual/reference/privilege-documents}
213
- # for more information.
214
- #
215
- # @note The use of the opts argument to provide or update additional fields
216
- # on the user document requires MongoDB >= 2.4.0
217
- #
218
- # @return [Hash] an object representing the user.
219
- def add_user(username, password=nil, read_only=false, opts={})
220
- user_info = command(:usersInfo => username)
221
- if user_info.key?('users') && !user_info['users'].empty?
222
- create_or_update_user(:updateUser, username, password, read_only, opts)
223
- else
224
- create_or_update_user(:createUser, username, password, read_only, opts)
225
- end
226
- # MongoDB >= 2.5.3 requires the use of commands to manage users.
227
- # "Command not found" error didn't return an error code (59) before
228
- # MongoDB 2.4.7 so we assume that a nil error code means the usersInfo
229
- # command doesn't exist and we should fall back to the legacy add user code.
230
- rescue OperationFailure => ex
231
- if Mongo::ErrorCode::COMMAND_NOT_FOUND_CODES.include?(ex.error_code)
232
- legacy_add_user(username, password, read_only, opts)
233
- elsif ex.error_code == Mongo::ErrorCode::UNAUTHORIZED
234
- # In MongoDB > 2.7 the localhost exception was narrowed, and the usersInfo
235
- # command is no longer allowed. In this case, add the first user.
236
- create_or_update_user(:createUser, username, password, read_only, opts)
237
- else
238
- raise ex
239
- end
240
- end
241
-
242
- # Remove the given user from this database. Returns false if the user
243
- # doesn't exist in the system.
244
- #
245
- # @param [String] username
246
- #
247
- # @return [Boolean]
248
- def remove_user(username)
249
- begin
250
- command(:dropUser => username)
251
- rescue OperationFailure => ex
252
- raise ex unless Mongo::ErrorCode::COMMAND_NOT_FOUND_CODES.include?(ex.error_code)
253
- response = self[SYSTEM_USER_COLLECTION].remove({:user => username}, :w => 1)
254
- response.key?('n') && response['n'] > 0 ? response : false
255
- end
256
- end
257
-
258
- # Get an array of collection names in this database.
259
- #
260
- # @return [Array]
261
- def collection_names
262
- if @client.wire_version_feature?(Mongo::MongoClient::MONGODB_3_0)
263
- names = collections_info.collect { |doc| doc['name'] || '' }
264
- names.delete_if do |name|
265
- name.index('$')
266
- end
267
- else
268
- legacy_collection_names
269
- end
270
- end
271
-
272
- # Get an array of Collection instances, one for each collection in this database.
273
- #
274
- # @return [Array<Mongo::Collection>]
275
- def collections
276
- collection_names.map do |name|
277
- Collection.new(name, self)
278
- end
279
- end
280
-
281
- # Get info on system namespaces (collections). This method returns
282
- # a cursor which can be iterated over. For each collection, a hash
283
- # will be yielded containing a 'name' string and, optionally, an 'options' hash.
284
- #
285
- # @param [String] coll_name return info for the specified collection only.
286
- #
287
- # @return [Array] List of collection info.
288
- def collections_info(coll_name=nil)
289
- if @client.wire_version_feature?(Mongo::MongoClient::MONGODB_3_0)
290
- cmd = BSON::OrderedHash[:listCollections, 1]
291
- cmd.merge!(:filter => { :name => coll_name }) if coll_name
292
- result = self.command(cmd, :cursor => {})
293
- if result.key?('cursor')
294
- cursor_info = result['cursor']
295
- pinned_pool = @client.pinned_pool
296
- pinned_pool = pinned_pool[:pool] if pinned_pool.respond_to?(:keys)
297
-
298
- seed = {
299
- :cursor_id => cursor_info['id'],
300
- :first_batch => cursor_info['firstBatch'],
301
- :pool => pinned_pool,
302
- :ns => cursor_info['ns']
303
- }
304
-
305
- Cursor.new(Collection.new('$cmd', self), seed).to_a
306
- else
307
- result['collections']
308
- end
309
- else
310
- legacy_collections_info(coll_name).to_a
311
- end
312
- end
313
-
314
- # Create a collection.
315
- #
316
- # new collection. If +strict+ is true, will raise an error if
317
- # collection +name+ already exists.
318
- #
319
- # @param [String, Symbol] name the name of the new collection.
320
- #
321
- # @option opts [Boolean] :capped (False) created a capped collection.
322
- #
323
- # @option opts [Integer] :size (Nil) If +capped+ is +true+,
324
- # specifies the maximum number of bytes for the capped collection.
325
- # If +false+, specifies the number of bytes allocated
326
- # for the initial extent of the collection.
327
- #
328
- # @option opts [Integer] :max (Nil) If +capped+ is +true+, indicates
329
- # the maximum number of records in a capped collection.
330
- #
331
- # @raise [MongoDBError] raised under two conditions:
332
- # either we're in +strict+ mode and the collection
333
- # already exists or collection creation fails on the server.
334
- #
335
- # @note Note that the options listed may be subset of those available.
336
- # Please see the MongoDB documentation for a full list of supported options by server version.
337
- #
338
- # @return [Mongo::Collection]
339
- def create_collection(name, opts={})
340
- name = name.to_s
341
- if strict? && collection_names.include?(name)
342
- raise MongoDBError, "Collection '#{name}' already exists. (strict=true)"
343
- end
344
-
345
- begin
346
- cmd = BSON::OrderedHash.new
347
- cmd[:create] = name
348
- doc = command(cmd.merge(opts || {}))
349
- return Collection.new(name, self, :pk => @pk_factory) if ok?(doc)
350
- rescue OperationFailure => e
351
- return Collection.new(name, self, :pk => @pk_factory) if e.message =~ /exists/
352
- raise e
353
- end
354
- raise MongoDBError, "Error creating collection: #{doc.inspect}"
355
- end
356
-
357
- # Get a collection by name.
358
- #
359
- # @param [String, Symbol] name the collection name.
360
- # @param [Hash] opts any valid options that can be passed to Collection#new.
361
- #
362
- # @raise [MongoDBError] if collection does not already exist and we're in
363
- # +strict+ mode.
364
- #
365
- # @return [Mongo::Collection]
366
- def collection(name, opts={})
367
- if strict? && !collection_names.include?(name.to_s)
368
- raise MongoDBError, "Collection '#{name}' doesn't exist. (strict=true)"
369
- else
370
- opts = opts.dup
371
- opts.merge!(:pk => @pk_factory) unless opts[:pk]
372
- Collection.new(name, self, opts)
373
- end
374
- end
375
- alias_method :[], :collection
376
-
377
- # Drop a collection by +name+.
378
- #
379
- # @param [String, Symbol] name
380
- #
381
- # @return [Boolean] +true+ on success or +false+ if the collection name doesn't exist.
382
- def drop_collection(name)
383
- return false if strict? && !collection_names.include?(name.to_s)
384
- begin
385
- ok?(command(:drop => name))
386
- rescue OperationFailure
387
- false
388
- end
389
- end
390
-
391
- # Run the getlasterror command with the specified replication options.
392
- #
393
- # @option opts [Boolean] :fsync (false)
394
- # @option opts [Integer] :w (nil)
395
- # @option opts [Integer] :wtimeout (nil)
396
- # @option opts [Boolean] :j (false)
397
- #
398
- # @return [Hash] the entire response to getlasterror.
399
- #
400
- # @raise [MongoDBError] if the operation fails.
401
- def get_last_error(opts={})
402
- cmd = BSON::OrderedHash.new
403
- cmd[:getlasterror] = 1
404
- cmd.merge!(opts)
405
- doc = command(cmd, :check_response => false)
406
- raise MongoDBError, "Error retrieving last error: #{doc.inspect}" unless ok?(doc)
407
- doc
408
- end
409
-
410
- # Return +true+ if an error was caused by the most recently executed
411
- # database operation.
412
- #
413
- # @return [Boolean]
414
- def error?
415
- get_last_error['err'] != nil
416
- end
417
-
418
- # Get the most recent error to have occurred on this database.
419
- #
420
- # This command only returns errors that have occurred since the last call to
421
- # DB#reset_error_history - returns +nil+ if there is no such error.
422
- #
423
- # @return [String, Nil] the text of the error or +nil+ if no error has occurred.
424
- def previous_error
425
- error = command(:getpreverror => 1)
426
- error["err"] ? error : nil
427
- end
428
-
429
- # Reset the error history of this database
430
- #
431
- # Calls to DB#previous_error will only return errors that have occurred
432
- # since the most recent call to this method.
433
- #
434
- # @return [Hash]
435
- def reset_error_history
436
- command(:reseterror => 1)
437
- end
438
-
439
- # Dereference a DBRef, returning the document it points to.
440
- #
441
- # @param [Mongo::DBRef] dbref
442
- #
443
- # @return [Hash] the document indicated by the db reference.
444
- #
445
- # @see http://www.mongodb.org/display/DOCS/DB+Ref MongoDB DBRef spec.
446
- def dereference(dbref)
447
- collection(dbref.namespace).find_one("_id" => dbref.object_id)
448
- end
449
-
450
- # Evaluate a JavaScript expression in MongoDB.
451
- #
452
- # @param [String, Code] code a JavaScript expression to evaluate server-side.
453
- # @param [Integer, Hash] args any additional argument to be passed to the +code+ expression when
454
- # it's run on the server.
455
- #
456
- # @note the eval command is deprecated in MongoDB 3.0 and will be removed in a future server version.
457
- #
458
- # @return [String] the return value of the function.
459
- def eval(code, *args)
460
- unless code.is_a?(BSON::Code)
461
- code = BSON::Code.new(code)
462
- end
463
-
464
- cmd = BSON::OrderedHash.new
465
- cmd[:$eval] = code
466
- cmd.merge!(args.pop) if args.last.respond_to?(:keys) && args.last.key?(:nolock)
467
- cmd[:args] = args
468
- doc = command(cmd)
469
- doc['retval']
470
- end
471
-
472
- # Rename a collection.
473
- #
474
- # @param [String] from original collection name.
475
- # @param [String] to new collection name.
476
- #
477
- # @return [True] returns +true+ on success.
478
- #
479
- # @raise MongoDBError if there's an error renaming the collection.
480
- def rename_collection(from, to)
481
- cmd = BSON::OrderedHash.new
482
- cmd[:renameCollection] = "#{@name}.#{from}"
483
- cmd[:to] = "#{@name}.#{to}"
484
- doc = DB.new('admin', @client).command(cmd, :check_response => false)
485
- ok?(doc) || raise(MongoDBError, "Error renaming collection: #{doc.inspect}")
486
- end
487
-
488
- # Drop an index from a given collection. Normally called from
489
- # Collection#drop_index or Collection#drop_indexes.
490
- #
491
- # @param [String] collection_name
492
- # @param [String] index_name
493
- #
494
- # @return [True] returns +true+ on success.
495
- #
496
- # @raise MongoDBError if there's an error dropping the index.
497
- def drop_index(collection_name, index_name)
498
- cmd = BSON::OrderedHash.new
499
- cmd[:deleteIndexes] = collection_name
500
- cmd[:index] = index_name.to_s
501
- doc = command(cmd, :check_response => false)
502
- ok?(doc) || raise(MongoDBError, "Error with drop_index command: #{doc.inspect}")
503
- end
504
-
505
- # Get information on the indexes for the given collection.
506
- # Normally called by Collection#index_information.
507
- #
508
- # @param [String] collection_name
509
- #
510
- # @return [Hash] keys are index names and the values are lists of [key, type] pairs
511
- # defining the index.
512
- def index_information(collection_name)
513
- if @client.wire_version_feature?(Mongo::MongoClient::MONGODB_3_0)
514
- result = self.command({ :listIndexes => collection_name }, :cursor => {})
515
- if result.key?('cursor')
516
- cursor_info = result['cursor']
517
- pinned_pool = @client.pinned_pool
518
- pinned_pool = pinned_pool[:pool] if pinned_pool.respond_to?(:keys)
519
-
520
- seed = {
521
- :cursor_id => cursor_info['id'],
522
- :first_batch => cursor_info['firstBatch'],
523
- :pool => pinned_pool,
524
- :ns => cursor_info['ns']
525
- }
526
-
527
- indexes = Cursor.new(Collection.new('$cmd', self), seed).to_a
528
- else
529
- indexes = result['indexes']
530
- end
531
- else
532
- indexes = legacy_list_indexes(collection_name)
533
- end
534
- indexes.reduce({}) do |info, index|
535
- info.merge!(index['name'] => index)
536
- end
537
- end
538
-
539
- # Return stats on this database. Uses MongoDB's dbstats command.
540
- #
541
- # @return [Hash]
542
- def stats
543
- self.command(:dbstats => 1)
544
- end
545
-
546
- # Return +true+ if the supplied +doc+ contains an 'ok' field with the value 1.
547
- #
548
- # @param [Hash] doc
549
- #
550
- # @return [Boolean]
551
- def ok?(doc)
552
- Mongo::Support.ok?(doc)
553
- end
554
-
555
- # Send a command to the database.
556
- #
557
- # Note: DB commands must start with the "command" key. For this reason,
558
- # any selector containing more than one key must be an OrderedHash.
559
- #
560
- # Note also that a command in MongoDB is just a kind of query
561
- # that occurs on the system command collection ($cmd). Examine this method's implementation
562
- # to see how it works.
563
- #
564
- # @param [OrderedHash, Hash] selector an OrderedHash, or a standard Hash with just one
565
- # key, specifying the command to be performed. In Ruby 1.9 and above, OrderedHash isn't necessary
566
- # because hashes are ordered by default.
567
- #
568
- # @option opts [Boolean] :check_response (true) If +true+, raises an exception if the
569
- # command fails.
570
- # @option opts [Socket] :socket a socket to use for sending the command. This is mainly for internal use.
571
- # @option opts [:primary, :secondary] :read Read preference for this command. See Collection#find for
572
- # more details.
573
- # @option opts [String] :comment (nil) a comment to include in profiling logs
574
- # @option opts [Boolean] :compile_regex (true) whether BSON regex objects should be compiled into Ruby regexes.
575
- # If false, a BSON::Regex object will be returned instead.
576
- #
577
- # @return [Hash]
578
- def command(selector, opts={})
579
- raise MongoArgumentError, "Command must be given a selector" unless selector.respond_to?(:keys) && !selector.empty?
580
-
581
- opts = opts.dup
582
- # deletes :check_response and returns the value, if nil defaults to the block result
583
- check_response = opts.delete(:check_response) { true }
584
-
585
- # build up the command hash
586
- command = opts.key?(:socket) ? { :socket => opts.delete(:socket) } : {}
587
- command.merge!(:comment => opts.delete(:comment)) if opts.key?(:comment)
588
- command.merge!(:compile_regex => opts.delete(:compile_regex)) if opts.key?(:compile_regex)
589
- command[:limit] = -1
590
- command[:read] = Mongo::ReadPreference::cmd_read_pref(opts.delete(:read), selector) if opts.key?(:read)
591
-
592
- if RUBY_VERSION < '1.9' && selector.class != BSON::OrderedHash
593
- if selector.keys.length > 1
594
- raise MongoArgumentError, "DB#command requires an OrderedHash when hash contains multiple keys"
595
- end
596
- if opts.keys.size > 0
597
- # extra opts will be merged into the selector, so make sure it's an OH in versions < 1.9
598
- selector = selector.dup
599
- selector = BSON::OrderedHash.new.merge!(selector)
600
- end
601
- end
602
-
603
- # arbitrary opts are merged into the selector
604
- command[:selector] = selector.merge!(opts)
605
-
606
- begin
607
- result = Cursor.new(system_command_collection, command).next_document
608
- rescue OperationFailure => ex
609
- if check_response
610
- raise ex.class.new("Database command '#{selector.keys.first}' failed: #{ex.message}", ex.error_code, ex.result)
611
- else
612
- result = ex.result
613
- end
614
- end
615
-
616
- raise OperationFailure,
617
- "Database command '#{selector.keys.first}' failed: returned null." unless result
618
-
619
- if check_response && (!ok?(result) || result['writeErrors'] || result['writeConcernError'])
620
- message = "Database command '#{selector.keys.first}' failed: ("
621
- message << result.map do |key, value|
622
- "#{key}: '#{value}'"
623
- end.join('; ')
624
- message << ').'
625
- code = result['code'] || result['assertionCode']
626
- if result['writeErrors']
627
- code = result['writeErrors'].first['code']
628
- end
629
- raise ExecutionTimeout.new(message, code, result) if code == MAX_TIME_MS_CODE
630
- raise OperationFailure.new(message, code, result)
631
- end
632
-
633
- result
634
- end
635
-
636
- # A shortcut returning db plus dot plus collection name.
637
- #
638
- # @param [String] collection_name
639
- #
640
- # @return [String]
641
- def full_collection_name(collection_name)
642
- "#{@name}.#{collection_name}"
643
- end
644
-
645
- # The primary key factory object (or +nil+).
646
- #
647
- # @return [Object, Nil]
648
- def pk_factory
649
- @pk_factory
650
- end
651
-
652
- # Specify a primary key factory if not already set.
653
- #
654
- # @raise [MongoArgumentError] if the primary key factory has already been set.
655
- def pk_factory=(pk_factory)
656
- raise MongoArgumentError,
657
- "Cannot change primary key factory once it's been set" if @pk_factory
658
-
659
- @pk_factory = pk_factory
660
- end
661
-
662
- # Return the current database profiling level. If profiling is enabled, you can
663
- # get the results using DB#profiling_info.
664
- #
665
- # @return [Symbol] :off, :slow_only, or :all
666
- def profiling_level
667
- cmd = BSON::OrderedHash.new
668
- cmd[:profile] = -1
669
- doc = command(cmd, :check_response => false)
670
-
671
- raise "Error with profile command: #{doc.inspect}" unless ok?(doc)
672
-
673
- level_sym = PROFILE_LEVEL.invert[doc['was'].to_i]
674
- raise "Error: illegal profiling level value #{doc['was']}" unless level_sym
675
- level_sym
676
- end
677
-
678
- # Set this database's profiling level. If profiling is enabled, you can
679
- # get the results using DB#profiling_info.
680
- #
681
- # @param [Symbol] level acceptable options are +:off+, +:slow_only+, or +:all+.
682
- def profiling_level=(level)
683
- cmd = BSON::OrderedHash.new
684
- cmd[:profile] = PROFILE_LEVEL[level]
685
- doc = command(cmd, :check_response => false)
686
- ok?(doc) || raise(MongoDBError, "Error with profile command: #{doc.inspect}")
687
- end
688
-
689
- # Get the current profiling information.
690
- #
691
- # @return [Array] a list of documents containing profiling information.
692
- def profiling_info
693
- Cursor.new(Collection.new(SYSTEM_PROFILE_COLLECTION, self), :selector => {}).to_a
694
- end
695
-
696
- # Validate a named collection.
697
- #
698
- # @param [String] name the collection name.
699
- #
700
- # @return [Hash] validation information.
701
- #
702
- # @raise [MongoDBError] if the command fails or there's a problem with the validation
703
- # data, or if the collection is invalid.
704
- def validate_collection(name)
705
- cmd = BSON::OrderedHash.new
706
- cmd[:validate] = name
707
- cmd[:full] = true
708
- doc = command(cmd, :check_response => false)
709
-
710
- raise MongoDBError, "Error with validate command: #{doc.inspect}" unless ok?(doc)
711
-
712
- if (doc.has_key?('valid') && !doc['valid']) || (doc['result'] =~ /\b(exception|corrupt)\b/i)
713
- raise MongoDBError, "Error: invalid collection #{name}: #{doc.inspect}"
714
- end
715
- doc
716
- end
717
-
718
- private
719
-
720
- def system_command_collection
721
- Collection.new(SYSTEM_COMMAND_COLLECTION, self)
722
- end
723
-
724
- # Create a new user.
725
- #
726
- # @param username [String] The username.
727
- # @param password [String] The user's password.
728
- # @param read_only [Boolean] Create a read-only user (deprecated in MongoDB >= 2.6)
729
- # @param opts [Hash]
730
- #
731
- # @private
732
- def create_or_update_user(command, username, password, read_only, opts)
733
- if read_only || !opts.key?(:roles)
734
- warn "Creating a user with the read_only option or without roles is " +
735
- "deprecated in MongoDB >= 2.6"
736
- end
737
-
738
- # The password is always salted and hashed by the driver.
739
- if opts.key?(:digestPassword)
740
- raise MongoArgumentError,
741
- "The digestPassword option is not available via DB#add_user. " +
742
- "Use DB#command(:createUser => ...) instead for this option."
743
- end
744
-
745
- opts = opts.dup
746
- pwd = Mongo::Authentication.hash_password(username, password) if password
747
- cmd_opts = pwd ? { :pwd => pwd } : {}
748
- # specify that the server shouldn't digest the password because the driver does
749
- cmd_opts[:digestPassword] = false
750
- unless opts.key?(:roles)
751
- if name == 'admin'
752
- roles = read_only ? ['readAnyDatabase'] : ['root']
753
- else
754
- roles = read_only ? ['read'] : ["dbOwner"]
755
- end
756
- cmd_opts[:roles] = roles
757
- end
758
- cmd_opts[:writeConcern] =
759
- opts.key?(:writeConcern) ? opts.delete(:writeConcern) : { :w => 1 }
760
- cmd_opts.merge!(opts)
761
- command({ command => username }, cmd_opts)
762
- end
763
-
764
- # Create a user in MongoDB versions < 2.5.3.
765
- # Called by #add_user if the 'usersInfo' command fails.
766
- #
767
- # @param username [String] The username.
768
- # @param password [String] (nil) The user's password.
769
- # @param read_only [Boolean] (false) Create a read-only user.
770
- # @param opts [Hash]
771
- #
772
- # @private
773
- def legacy_add_user(username, password=nil, read_only=false, opts={})
774
- users = self[SYSTEM_USER_COLLECTION]
775
- user = users.find_one(:user => username) || {:user => username}
776
- user['pwd'] =
777
- Mongo::Authentication.hash_password(username, password) if password
778
- user['readOnly'] = true if read_only
779
- user.merge!(opts)
780
- begin
781
- users.save(user)
782
- rescue OperationFailure => ex
783
- # adding first admin user fails GLE in MongoDB 2.2
784
- raise ex unless ex.message =~ /login/
785
- end
786
- user
787
- end
788
-
789
- def legacy_list_indexes(collection_name)
790
- sel = {:ns => full_collection_name(collection_name)}
791
- Cursor.new(Collection.new(SYSTEM_INDEX_COLLECTION, self), :selector => sel)
792
- end
793
-
794
- def legacy_collections_info(coll_name=nil)
795
- selector = {}
796
- selector[:name] = full_collection_name(coll_name) if coll_name
797
- Cursor.new(Collection.new(SYSTEM_NAMESPACE_COLLECTION, self), :selector => selector)
798
- end
799
-
800
- def legacy_collection_names
801
- names = legacy_collections_info.collect { |doc| doc['name'] || '' }
802
- names = names.delete_if do |name|
803
- name.index(@name).nil? || name.index('$')
804
- end
805
- names.map {|name| name.sub(@name + '.', '')}
806
- end
807
- end
808
- end