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,61 @@
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 Protocol
17
+ module Serializers
18
+ # Class used to define a bitvector for a MongoDB wire protocol message.
19
+ #
20
+ # Defines serialization strategy upon initialization.
21
+ #
22
+ # @api private
23
+ class BitVector
24
+
25
+ # Initializes a BitVector with a layout
26
+ #
27
+ # @param layout [Array<Symbol>] the array of fields in the bit vector
28
+ def initialize(layout)
29
+ @masks = {}
30
+ layout.each_with_index do |field, index|
31
+ @masks[field] = 2**index
32
+ end
33
+ end
34
+
35
+ # Serializes vector by encoding each symbol according to its mask
36
+ #
37
+ # @param buffer [IO] Buffer to receive the serialized vector
38
+ # @param value [Array<Symbol>] Array of flags to encode
39
+ # @return [IO] Buffer that received the serialized vector
40
+ def serialize(buffer, value)
41
+ bits = 0
42
+ value.each { |flag| bits |= @masks[flag] }
43
+ buffer << [bits].pack(INT32_PACK)
44
+ end
45
+
46
+ # Deserializes vector by decoding the symbol according to its mask
47
+ #
48
+ # @param io [IO] Stream containing the vector to be deserialized
49
+ # @return [Array<Symbol>] Flags contained in the vector
50
+ def deserialize(io)
51
+ vector = io.read(4).unpack(INT32_PACK).first
52
+ flags = []
53
+ @masks.each do |flag, mask|
54
+ flags << flag if mask & vector != 0
55
+ end
56
+ flags
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,94 @@
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 Protocol
17
+
18
+ # MongoDB Wire protocol Delete message.
19
+ #
20
+ # This is a client request message that is sent to the server in order
21
+ # to delete selected documents in the specified namespace.
22
+ #
23
+ # The operation, by default, operates on many documents. Setting
24
+ # the +:single_remove+ flag allows for a single matching document
25
+ # to be removed.
26
+ #
27
+ # @api semipublic
28
+ class Delete < Message
29
+
30
+ # Creates a new Delete message
31
+ #
32
+ # @example Remove all users named Tyler.
33
+ # Query.new('xgen', 'users', {:name => 'Tyler'})
34
+ #
35
+ # @param database [String, Symbol] The database to remove from.
36
+ # @param collection [String, Symbol] The collection to remove from.
37
+ # @param selector [Hash] The query used to select doc(s) to remove.
38
+ # @param options [Hash] The additional delete options.
39
+ #
40
+ # @option options :flags [Array] The flags for the delete message.
41
+ #
42
+ # Supported flags: +:single_remove+
43
+ def initialize(database, collection, selector, options = {})
44
+ @namespace = "#{database}.#{collection}"
45
+ @selector = selector
46
+ @flags = options[:flags] || []
47
+ end
48
+
49
+ # The log message for a delete operation.
50
+ #
51
+ # @example Get the log message.
52
+ # delete.log_message
53
+ #
54
+ # @return [ String ] The log message
55
+ #
56
+ # @since 2.0.0
57
+ def log_message
58
+ fields = []
59
+ fields << ["%s |", "DELETE"]
60
+ fields << ["namespace=%s", namespace]
61
+ fields << ["selector=%s", selector.inspect]
62
+ fields << ["flags=%s", flags.inspect]
63
+ f, v = fields.transpose
64
+ f.join(" ") % v
65
+ end
66
+
67
+ private
68
+
69
+ # The operation code required to specify a Delete message.
70
+ # @return [Fixnum] the operation code.
71
+ def op_code
72
+ 2006
73
+ end
74
+
75
+ # Available flags for a Delete message.
76
+ FLAGS = [:single_remove]
77
+
78
+ # Field representing Zero encoded as an Int32.
79
+ field :zero, Zero
80
+
81
+ # @!attribute
82
+ # @return [String] The namespace for this Delete message.
83
+ field :namespace, CString
84
+
85
+ # @!attribute
86
+ # @return [Array<Symbol>] The flags for this Delete message.
87
+ field :flags, BitVector.new(FLAGS)
88
+
89
+ # @!attribute
90
+ # @return [Hash] The selector for this Delete message.
91
+ field :selector, Document
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,99 @@
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 Protocol
17
+
18
+ # MongoDB Wire protocol GetMore message.
19
+ #
20
+ # This is a client request message that is sent to the server in order
21
+ # to retrieve additional documents from a cursor that has already been
22
+ # instantiated.
23
+ #
24
+ # The operation requires that you specify the database and collection
25
+ # name as well as the cursor id because cursors are scoped to a namespace.
26
+ #
27
+ # @api semipublic
28
+ class GetMore < Message
29
+
30
+ # Creates a new GetMore message
31
+ #
32
+ # @example Get 15 additional documents from cursor 123 in 'xgen.users'.
33
+ # GetMore.new('xgen', 'users', 15, 123)
34
+ #
35
+ # @param database [String, Symbol] The database to query.
36
+ # @param collection [String, Symbol] The collection to query.
37
+ # @param number_to_return [Integer] The number of documents to return.
38
+ # @param cursor_id [Integer] The cursor id returned in a reply.
39
+ def initialize(database, collection, number_to_return, cursor_id)
40
+ @namespace = "#{database}.#{collection}"
41
+ @number_to_return = number_to_return
42
+ @cursor_id = cursor_id
43
+ end
44
+
45
+ # The log message for a get more operation.
46
+ #
47
+ # @example Get the log message.
48
+ # get_more.log_message
49
+ #
50
+ # @return [ String ] The log message
51
+ #
52
+ # @since 2.0.0
53
+ def log_message
54
+ fields = []
55
+ fields << ["%s |", "GETMORE"]
56
+ fields << ["namespace=%s", namespace]
57
+ fields << ["number_to_return=%s", number_to_return]
58
+ fields << ["cursor_id=%s", cursor_id]
59
+ f, v = fields.transpose
60
+ f.join(" ") % v
61
+ end
62
+
63
+ # Get more messages require replies from the database.
64
+ #
65
+ # @example Does the message require a reply?
66
+ # message.replyable?
67
+ #
68
+ # @return [ true ] Always true for get more.
69
+ #
70
+ # @since 2.0.0
71
+ def replyable?
72
+ true
73
+ end
74
+
75
+ private
76
+
77
+ # The operation code required to specify a GetMore message.
78
+ # @return [Fixnum] the operation code.
79
+ def op_code
80
+ 2005
81
+ end
82
+
83
+ # Field representing Zero encoded as an Int32
84
+ field :zero, Zero
85
+
86
+ # @!attribute
87
+ # @return [String] The namespace for this GetMore message.
88
+ field :namespace, CString
89
+
90
+ # @!attribute
91
+ # @return [Fixnum] The number to return for this GetMore message.
92
+ field :number_to_return, Int32
93
+
94
+ # @!attribute
95
+ # @return [Fixnum] The cursor id to get more documents from.
96
+ field :cursor_id, Int64
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,99 @@
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 Protocol
17
+
18
+ # MongoDB Wire protocol Insert message.
19
+ #
20
+ # This is a client request message that is sent to the server in order
21
+ # to insert documents within a namespace.
22
+ #
23
+ # The operation only has one flag +:continue_on_error+ which the user
24
+ # can use to instruct the database server to continue processing a bulk
25
+ # insertion if one happens to fail (e.g. due to duplicate IDs). This makes
26
+ # builk insert behave similarly to a seires of single inserts, except
27
+ # lastError will be set if any insert fails, not just the last one.
28
+ #
29
+ # If multiple errors occur, only the most recent will be reported by the
30
+ # getLastError mechanism.
31
+ #
32
+ # @api semipublic
33
+ class Insert < Message
34
+
35
+ # Creates a new Insert message
36
+ #
37
+ # @example Insert a user document
38
+ # Insert.new('xgen', 'users', [{:name => 'Tyler'}])
39
+ #
40
+ # @example Insert serveral user documents and continue on errors
41
+ # Insert.new('xgen', 'users', users, :flags => [:continue_on_error])
42
+ #
43
+ # @param database [String, Symbol] The database to insert into.
44
+ # @param collection [String, Symbol] The collection to insert into.
45
+ # @param documents [Array<Hash>] The documents to insert.
46
+ # @param options [Hash] Additional options for the insertion.
47
+ #
48
+ # @option options :flags [Array] The flags for the insertion message.
49
+ #
50
+ # Supported flags: +:continue_on_error+
51
+ def initialize(database, collection, documents, options = {})
52
+ @namespace = "#{database}.#{collection}"
53
+ @documents = documents
54
+ @flags = options[:flags] || []
55
+ end
56
+
57
+ # The log message for a insert operation.
58
+ #
59
+ # @example Get the log message.
60
+ # insert.log_message
61
+ #
62
+ # @return [ String ] The log message
63
+ #
64
+ # @since 2.0.0
65
+ def log_message
66
+ fields = []
67
+ fields << ["%s |", "INSERT"]
68
+ fields << ["namespace=%s", namespace]
69
+ fields << ["documents=%s", documents.inspect]
70
+ fields << ["flags=%s", flags.inspect]
71
+ f, v = fields.transpose
72
+ f.join(" ") % v
73
+ end
74
+
75
+ private
76
+
77
+ # The operation code required to specify an Insert message.
78
+ # @return [Fixnum] the operation code.
79
+ def op_code
80
+ 2002
81
+ end
82
+
83
+ # Available flags for an Insert message.
84
+ FLAGS = [:continue_on_error]
85
+
86
+ # @!attribute
87
+ # @return [Array<Symbol>] The flags for this Insert message.
88
+ field :flags, BitVector.new(FLAGS)
89
+
90
+ # @!attribute
91
+ # @return [String] The namespace for this Insert message.
92
+ field :namespace, CString
93
+
94
+ # @!attribute
95
+ # @return [Array<Hash>] The documents to insert.
96
+ field :documents, Document, true
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,74 @@
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 Protocol
17
+
18
+ # MongoDB Wire protocol KillCursors message.
19
+ #
20
+ # This is a client request message that is sent to the server in order
21
+ # to kill a number of cursors.
22
+ #
23
+ # @api semipublic
24
+ class KillCursors < Message
25
+
26
+ # Creates a new KillCursors message
27
+ #
28
+ # @example Kill the cursor on the server with id 1.
29
+ # KillCursors.new([1])
30
+ #
31
+ # @param cursor_ids [Array<Fixnum>] The cursor ids to kill.
32
+ # @param options [Hash] The additional kill cursors options.
33
+ def initialize(cursor_ids, options = {})
34
+ @cursor_ids = cursor_ids
35
+ @id_count = @cursor_ids.size
36
+ end
37
+
38
+ # The log message for a kill cursors operation.
39
+ #
40
+ # @example Get the log message.
41
+ # kill_cursors.log_message
42
+ #
43
+ # @return [ String ] The log message
44
+ #
45
+ # @since 2.0.0
46
+ def log_message
47
+ fields = []
48
+ fields << ["%s |", "KILLCURSORS"]
49
+ fields << ["cursor_ids=%s", cursor_ids.inspect]
50
+ f, v = fields.transpose
51
+ f.join(" ") % v
52
+ end
53
+
54
+ private
55
+
56
+ # The operation code required to specify +KillCursors+ message.
57
+ # @return [Fixnum] the operation code.
58
+ def op_code
59
+ 2007
60
+ end
61
+
62
+ # Field representing Zero encoded as an Int32.
63
+ field :zero, Zero
64
+
65
+ # @!attribute
66
+ # @return [Fixnum] Count of the number of cursor ids.
67
+ field :id_count, Int32
68
+
69
+ # @!attribute
70
+ # @return [Array<Fixnum>] Cursors to kill.
71
+ field :cursor_ids, Int64, true
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,252 @@
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 Protocol
17
+
18
+ # A base class providing functionality required by all messages in
19
+ # the MongoDB wire protocol. It provides a minimal DSL for defining typed
20
+ # fields to enable serialization and deserialization over the wire.
21
+ #
22
+ # @example
23
+ # class WireProtocolMessage < Message
24
+ #
25
+ # private
26
+ #
27
+ # def op_code
28
+ # 1234
29
+ # end
30
+ #
31
+ # FLAGS = [:first_bit, :bit_two]
32
+ #
33
+ # # payload
34
+ # field :flags, BitVector.new(FLAGS)
35
+ # field :namespace, CString
36
+ # field :document, Document
37
+ # field :documents, Document, true
38
+ # end
39
+ #
40
+ # @abstract
41
+ # @api semiprivate
42
+ class Message
43
+ include Serializers
44
+
45
+ # Returns the request id for the message
46
+ #
47
+ # @return [Fixnum] The request id for this message
48
+ attr_reader :request_id
49
+
50
+ # The default for messages is not to require a reply after sending a
51
+ # message to the server.
52
+ #
53
+ # @example Does the message require a reply?
54
+ # message.replyable?
55
+ #
56
+ # @return [ false ] The default is to not require a reply.
57
+ #
58
+ # @since 2.0.0
59
+ def replyable?
60
+ false
61
+ end
62
+
63
+ # Serializes message into bytes that can be sent on the wire
64
+ #
65
+ # @param buffer [String] buffer where the message should be inserted
66
+ # @return [String] buffer containing the serialized message
67
+ def serialize(buffer = ''.force_encoding('BINARY'), max_bson_size = nil)
68
+ start = buffer.bytesize
69
+ serialize_header(buffer)
70
+ serialize_fields(buffer, max_bson_size)
71
+ length = buffer.bytesize - start
72
+ buffer[start, 4] = Int32.serialize('', length)
73
+ buffer
74
+ end
75
+
76
+ alias_method :to_s, :serialize
77
+
78
+ # Deserializes messages from an IO stream
79
+ #
80
+ # @param io [IO] Stream containing a message
81
+ # @return [Message] Instance of a Message class
82
+ def self.deserialize(io)
83
+ deserialize_header(io)
84
+ message = allocate
85
+ fields.each do |field|
86
+ if field[:multi]
87
+ deserialize_array(message, io, field)
88
+ else
89
+ deserialize_field(message, io, field)
90
+ end
91
+ end
92
+ message
93
+ end
94
+
95
+ # Tests for equality between two wire protocol messages
96
+ # by comparing class and field values.
97
+ #
98
+ # @param other [Mongo::Protocol::Message] The wire protocol message.
99
+ # @return [true, false] The equality of the messages.
100
+ def ==(other)
101
+ return false if self.class != other.class
102
+ fields.all? do |field|
103
+ name = field[:name]
104
+ instance_variable_get(name) ==
105
+ other.instance_variable_get(name)
106
+ end
107
+ end
108
+ alias_method :eql?, :==
109
+
110
+ # Creates a hash from the values of the fields of a message.
111
+ #
112
+ # @return [ Fixnum ] The hash code for the message.
113
+ def hash
114
+ fields.map { |field| instance_variable_get(field[:name]) }.hash
115
+ end
116
+
117
+ private
118
+
119
+ @@request_id = 0
120
+ @@id_lock = Mutex.new
121
+
122
+ # A method for getting the fields for a message class
123
+ #
124
+ # @return [Integer] the fields for the message class
125
+ def fields
126
+ self.class.fields
127
+ end
128
+
129
+ # A class method for getting the fields for a message class
130
+ #
131
+ # @return [Integer] the fields for the message class
132
+ def self.fields
133
+ @fields ||= []
134
+ end
135
+
136
+ # Serializes message fields into a buffer
137
+ #
138
+ # @param buffer [String] buffer to receive the field
139
+ # @return [String] buffer with serialized field
140
+ def serialize_fields(buffer, max_bson_size = nil)
141
+ fields.each do |field|
142
+ value = instance_variable_get(field[:name])
143
+ if field[:multi]
144
+ value.each do |item|
145
+ if field[:type].respond_to?(:size_limited?)
146
+ field[:type].serialize(buffer, item, max_bson_size)
147
+ else
148
+ field[:type].serialize(buffer, item)
149
+ end
150
+ end
151
+ else
152
+ if field[:type].respond_to?(:size_limited?)
153
+ field[:type].serialize(buffer, value, max_bson_size)
154
+ else
155
+ field[:type].serialize(buffer, value)
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ # Generates a request id for a message
162
+ #
163
+ # @return [Fixnum] a request id used for sending a message to the
164
+ # server. The server will put this id in the response_to field of
165
+ # a reply.
166
+ def set_request_id
167
+ @@id_lock.synchronize do
168
+ @request_id = @@request_id += 1
169
+ end
170
+ end
171
+
172
+ # Serializes the header of the message consisting of 4 32bit integers
173
+ #
174
+ # The integers represent a message length placeholder (calculation of
175
+ # the actual length is deferred) the request id, the response to id,
176
+ # and the op code for the message
177
+ #
178
+ # Currently uses hardcoded 0 for request id and response to as their
179
+ # values are irrelevent to the server
180
+ #
181
+ # @param buffer [String] Buffer to receive the header
182
+ # @return [String] Serialized header
183
+ def serialize_header(buffer)
184
+ set_request_id
185
+ Header.serialize(buffer, [0, request_id, 0, op_code])
186
+ end
187
+
188
+ # Deserializes the header of the message
189
+ #
190
+ # @param io [IO] Stream containing the header.
191
+ # @return [Array<Fixnum>] Deserialized header.
192
+ def self.deserialize_header(io)
193
+ @length, @request_id, @response_to, @op_code = Header.deserialize(io)
194
+ end
195
+
196
+ # A method for declaring a message field
197
+ #
198
+ # @param name [String] Name of the field
199
+ # @param type [Module] Type specific serialization strategies
200
+ # @param multi [true, false, Symbol] Specify as +true+ to
201
+ # serialize the field's value as an array of type +:type+ or as a
202
+ # symbol describing the field having the number of items in the
203
+ # array (used upon deserialization)
204
+ #
205
+ # Note: In fields where multi is a symbol representing the field
206
+ # containing number items in the repetition, the field containing
207
+ # that information *must* be deserialized prior to deserializing
208
+ # fields that use the number.
209
+ #
210
+ # @return [NilClass]
211
+ def self.field(name, type, multi = false)
212
+ fields << {
213
+ :name => "@#{name}".intern,
214
+ :type => type,
215
+ :multi => multi
216
+ }
217
+
218
+ attr_reader name
219
+ end
220
+
221
+ # Deserializes an array of fields in a message
222
+ #
223
+ # The number of items in the array must be described by a previously
224
+ # deserialized field specified in the class by the field dsl under
225
+ # the key +:multi+
226
+ #
227
+ # @param message [Message] Message to contain the deserialized array.
228
+ # @param io [IO] Stream containing the array to deserialize.
229
+ # @param field [Hash] Hash representing a field.
230
+ # @return [Message] Message with deserialized array.
231
+ def self.deserialize_array(message, io, field)
232
+ elements = []
233
+ count = message.instance_variable_get(field[:multi])
234
+ count.times { elements << field[:type].deserialize(io) }
235
+ message.instance_variable_set(field[:name], elements)
236
+ end
237
+
238
+ # Deserializes a single field in a message
239
+ #
240
+ # @param message [Message] Message to contain the deserialized field.
241
+ # @param io [IO] Stream containing the field to deserialize.
242
+ # @param field [Hash] Hash representing a field.
243
+ # @return [Message] Message with deserialized field.
244
+ def self.deserialize_field(message, io, field)
245
+ message.instance_variable_set(
246
+ field[:name],
247
+ field[:type].deserialize(io)
248
+ )
249
+ end
250
+ end
251
+ end
252
+ end