mongo 2.4.3 → 2.5.0.beta

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 (235) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +3 -2
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo.rb +3 -2
  5. data/lib/mongo/auth/cr.rb +6 -4
  6. data/lib/mongo/auth/cr/conversation.rb +33 -17
  7. data/lib/mongo/auth/ldap.rb +4 -2
  8. data/lib/mongo/auth/ldap/conversation.rb +19 -9
  9. data/lib/mongo/auth/scram.rb +7 -4
  10. data/lib/mongo/auth/scram/conversation.rb +62 -24
  11. data/lib/mongo/auth/user.rb +10 -0
  12. data/lib/mongo/auth/user/view.rb +44 -22
  13. data/lib/mongo/auth/x509.rb +4 -2
  14. data/lib/mongo/auth/x509/conversation.rb +19 -9
  15. data/lib/mongo/bulk_write.rb +33 -27
  16. data/lib/mongo/bulk_write/combineable.rb +5 -0
  17. data/lib/mongo/bulk_write/transformable.rb +2 -0
  18. data/lib/mongo/bulk_write/validatable.rb +4 -0
  19. data/lib/mongo/client.rb +123 -12
  20. data/lib/mongo/cluster.rb +52 -11
  21. data/lib/mongo/cluster/app_metadata.rb +8 -2
  22. data/lib/mongo/cluster/cursor_reaper.rb +0 -1
  23. data/lib/mongo/cluster/topology.rb +1 -1
  24. data/lib/mongo/collection.rb +114 -27
  25. data/lib/mongo/collection/view.rb +8 -2
  26. data/lib/mongo/collection/view/aggregation.rb +11 -7
  27. data/lib/mongo/collection/view/builder/aggregation.rb +5 -1
  28. data/lib/mongo/collection/view/builder/find_command.rb +5 -3
  29. data/lib/mongo/collection/view/builder/map_reduce.rb +11 -3
  30. data/lib/mongo/collection/view/builder/op_query.rb +1 -1
  31. data/lib/mongo/collection/view/change_stream.rb +160 -0
  32. data/lib/mongo/collection/view/change_stream/retryable.rb +57 -0
  33. data/lib/mongo/collection/view/iterable.rb +11 -10
  34. data/lib/mongo/collection/view/map_reduce.rb +22 -18
  35. data/lib/mongo/collection/view/readable.rb +51 -37
  36. data/lib/mongo/collection/view/writable.rb +72 -40
  37. data/lib/mongo/cursor.rb +25 -4
  38. data/lib/mongo/cursor/builder/get_more_command.rb +4 -2
  39. data/lib/mongo/database.rb +22 -11
  40. data/lib/mongo/database/view.rb +16 -12
  41. data/lib/mongo/error.rb +5 -0
  42. data/lib/mongo/error/invalid_session.rb +36 -0
  43. data/lib/mongo/error/missing_resume_token.rb +39 -0
  44. data/lib/mongo/error/operation_failure.rb +17 -0
  45. data/lib/mongo/error/parser.rb +3 -2
  46. data/lib/mongo/error/unknown_payload_type.rb +41 -0
  47. data/lib/mongo/error/unsupported_array_filters.rb +51 -0
  48. data/lib/mongo/error/unsupported_message_type.rb +23 -0
  49. data/lib/mongo/grid/fs_bucket.rb +5 -4
  50. data/lib/mongo/grid/stream/read.rb +3 -2
  51. data/lib/mongo/grid/stream/write.rb +2 -2
  52. data/lib/mongo/index/view.rb +35 -25
  53. data/lib/mongo/monitoring/event/secure.rb +14 -0
  54. data/lib/mongo/operation.rb +16 -0
  55. data/lib/mongo/operation/commands.rb +1 -0
  56. data/lib/mongo/operation/commands/aggregate.rb +9 -5
  57. data/lib/mongo/operation/commands/aggregate/result.rb +1 -1
  58. data/lib/mongo/operation/commands/collections_info.rb +6 -6
  59. data/lib/mongo/operation/commands/command.rb +2 -1
  60. data/lib/mongo/operation/commands/create.rb +6 -2
  61. data/lib/mongo/operation/commands/drop.rb +6 -2
  62. data/lib/mongo/operation/commands/drop_database.rb +6 -2
  63. data/lib/mongo/operation/commands/explain.rb +27 -0
  64. data/lib/mongo/operation/commands/explain/result.rb +52 -0
  65. data/lib/mongo/operation/commands/indexes.rb +1 -1
  66. data/lib/mongo/operation/commands/list_collections.rb +1 -1
  67. data/lib/mongo/operation/commands/list_collections/result.rb +1 -1
  68. data/lib/mongo/operation/commands/list_indexes.rb +1 -1
  69. data/lib/mongo/operation/commands/list_indexes/result.rb +1 -1
  70. data/lib/mongo/operation/commands/map_reduce.rb +8 -4
  71. data/lib/mongo/operation/commands/map_reduce/result.rb +13 -1
  72. data/lib/mongo/operation/commands/user_query.rb +1 -1
  73. data/lib/mongo/operation/commands/users_info.rb +6 -2
  74. data/lib/mongo/operation/executable.rb +4 -1
  75. data/lib/mongo/operation/read_preference.rb +10 -5
  76. data/lib/mongo/operation/result.rb +26 -2
  77. data/lib/mongo/operation/specifiable.rb +13 -1
  78. data/lib/mongo/operation/uses_command_op_msg.rb +47 -0
  79. data/lib/mongo/operation/write/bulk/bulkable.rb +4 -1
  80. data/lib/mongo/operation/write/bulk/insert/result.rb +4 -4
  81. data/lib/mongo/operation/write/command/create_index.rb +6 -1
  82. data/lib/mongo/operation/write/command/delete.rb +28 -4
  83. data/lib/mongo/operation/write/command/drop_index.rb +6 -1
  84. data/lib/mongo/operation/write/command/insert.rb +22 -18
  85. data/lib/mongo/operation/write/command/update.rb +24 -9
  86. data/lib/mongo/operation/write/command/writable.rb +14 -1
  87. data/lib/mongo/operation/write/insert.rb +4 -1
  88. data/lib/mongo/operation/write/insert/result.rb +2 -2
  89. data/lib/mongo/operation/write/update.rb +7 -1
  90. data/lib/mongo/operation/write/write_command_enabled.rb +20 -3
  91. data/lib/mongo/protocol.rb +3 -0
  92. data/lib/mongo/protocol/bit_vector.rb +2 -2
  93. data/lib/mongo/protocol/compressed.rb +135 -0
  94. data/lib/mongo/protocol/delete.rb +8 -6
  95. data/lib/mongo/protocol/get_more.rb +8 -6
  96. data/lib/mongo/protocol/insert.rb +8 -6
  97. data/lib/mongo/protocol/kill_cursors.rb +8 -6
  98. data/lib/mongo/protocol/message.rb +31 -3
  99. data/lib/mongo/protocol/msg.rb +172 -0
  100. data/lib/mongo/protocol/query.rb +26 -6
  101. data/lib/mongo/protocol/registry.rb +76 -0
  102. data/lib/mongo/protocol/reply.rb +10 -5
  103. data/lib/mongo/protocol/serializers.rb +224 -0
  104. data/lib/mongo/protocol/update.rb +8 -6
  105. data/lib/mongo/retryable.rb +4 -2
  106. data/lib/mongo/server.rb +6 -3
  107. data/lib/mongo/server/connectable.rb +1 -1
  108. data/lib/mongo/server/connection.rb +30 -8
  109. data/lib/mongo/server/description.rb +25 -1
  110. data/lib/mongo/server/description/features.rb +4 -1
  111. data/lib/mongo/server/monitor.rb +5 -0
  112. data/lib/mongo/server/monitor/connection.rb +50 -2
  113. data/lib/mongo/server_selector/nearest.rb +10 -4
  114. data/lib/mongo/server_selector/primary.rb +20 -0
  115. data/lib/mongo/server_selector/primary_preferred.rb +10 -4
  116. data/lib/mongo/server_selector/secondary.rb +10 -4
  117. data/lib/mongo/server_selector/secondary_preferred.rb +24 -4
  118. data/lib/mongo/session.rb +180 -0
  119. data/lib/mongo/session/server_session.rb +73 -0
  120. data/lib/mongo/session/session_pool.rb +161 -0
  121. data/lib/mongo/uri.rb +11 -0
  122. data/lib/mongo/version.rb +1 -1
  123. data/mongo.gemspec +2 -1
  124. data/spec/mongo/auth/cr_spec.rb +12 -0
  125. data/spec/mongo/auth/ldap_spec.rb +2 -0
  126. data/spec/mongo/auth/scram/conversation_spec.rb +6 -6
  127. data/spec/mongo/auth/scram_spec.rb +25 -1
  128. data/spec/mongo/auth/user/view_spec.rb +268 -76
  129. data/spec/mongo/auth/x509_spec.rb +2 -0
  130. data/spec/mongo/bulk_write_spec.rb +435 -5
  131. data/spec/mongo/client_spec.rb +356 -39
  132. data/spec/mongo/cluster/app_metadata_spec.rb +2 -2
  133. data/spec/mongo/cluster_spec.rb +176 -0
  134. data/spec/mongo/collection/view/aggregation_spec.rb +33 -12
  135. data/spec/mongo/collection/view/builder/find_command_spec.rb +46 -6
  136. data/spec/mongo/collection/view/change_stream_spec.rb +814 -0
  137. data/spec/mongo/collection/view/map_reduce_spec.rb +94 -17
  138. data/spec/mongo/collection/view/readable_spec.rb +3 -12
  139. data/spec/mongo/collection_spec.rb +1048 -42
  140. data/spec/mongo/cursor/builder/get_more_command_spec.rb +19 -0
  141. data/spec/mongo/cursor_spec.rb +2 -2
  142. data/spec/mongo/database_spec.rb +50 -1
  143. data/spec/mongo/grid/fs_bucket_spec.rb +225 -137
  144. data/spec/mongo/grid/stream/read_spec.rb +2 -2
  145. data/spec/mongo/index/view_spec.rb +146 -8
  146. data/spec/mongo/monitoring/event/secure_spec.rb +42 -0
  147. data/spec/mongo/operation/read/query_spec.rb +2 -1
  148. data/spec/mongo/operation/specifiable_spec.rb +2 -2
  149. data/spec/mongo/operation/write/command/delete_spec.rb +96 -13
  150. data/spec/mongo/operation/write/command/insert_spec.rb +111 -12
  151. data/spec/mongo/operation/write/command/update_spec.rb +93 -10
  152. data/spec/mongo/operation/write/delete_spec.rb +1 -1
  153. data/spec/mongo/operation/write/insert_spec.rb +1 -1
  154. data/spec/mongo/operation/write/update_spec.rb +1 -1
  155. data/spec/mongo/protocol/compressed_spec.rb +66 -0
  156. data/spec/mongo/protocol/delete_spec.rb +14 -0
  157. data/spec/mongo/protocol/get_more_spec.rb +14 -0
  158. data/spec/mongo/protocol/insert_spec.rb +14 -0
  159. data/spec/mongo/protocol/kill_cursors_spec.rb +14 -0
  160. data/spec/mongo/protocol/msg_spec.rb +499 -0
  161. data/spec/mongo/protocol/query_spec.rb +45 -0
  162. data/spec/mongo/protocol/registry_spec.rb +31 -0
  163. data/spec/mongo/protocol/reply_spec.rb +14 -0
  164. data/spec/mongo/protocol/update_spec.rb +14 -0
  165. data/spec/mongo/retryable_spec.rb +6 -2
  166. data/spec/mongo/sdam_spec.rb +4 -0
  167. data/spec/mongo/server/connection_spec.rb +4 -2
  168. data/spec/mongo/server/description_spec.rb +28 -1
  169. data/spec/mongo/session/server_session_spec.rb +16 -0
  170. data/spec/mongo/session/session_pool_spec.rb +194 -0
  171. data/spec/mongo/uri_spec.rb +31 -2
  172. data/spec/spec_helper.rb +104 -0
  173. data/spec/support/authorization.rb +6 -1
  174. data/spec/support/crud.rb +3 -1
  175. data/spec/support/crud/write.rb +6 -1
  176. data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +69 -0
  177. data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +63 -0
  178. data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +109 -0
  179. data/spec/support/sdam/rs/discover_arbiters.yml +1 -1
  180. data/spec/support/sdam/rs/discover_passives.yml +2 -2
  181. data/spec/support/sdam/rs/discover_primary.yml +1 -1
  182. data/spec/support/sdam/rs/discover_secondary.yml +1 -1
  183. data/spec/support/sdam/rs/discovery.yml +4 -4
  184. data/spec/support/sdam/rs/equal_electionids.yml +1 -0
  185. data/spec/support/sdam/rs/ghost_discovered.yml +1 -1
  186. data/spec/support/sdam/rs/hosts_differ_from_seeds.yml +1 -1
  187. data/spec/support/sdam/rs/ls_timeout.yml +88 -0
  188. data/spec/support/sdam/rs/member_reconfig.yml +2 -2
  189. data/spec/support/sdam/rs/member_standalone.yml +2 -2
  190. data/spec/support/sdam/rs/new_primary.yml +2 -2
  191. data/spec/support/sdam/rs/new_primary_new_electionid.yml +3 -0
  192. data/spec/support/sdam/rs/new_primary_new_setversion.yml +3 -0
  193. data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +2 -2
  194. data/spec/support/sdam/rs/non_rs_member.yml +1 -1
  195. data/spec/support/sdam/rs/normalize_case.yml +1 -1
  196. data/spec/support/sdam/rs/null_election_id.yml +4 -0
  197. data/spec/support/sdam/rs/primary_becomes_standalone.yml +2 -2
  198. data/spec/support/sdam/rs/primary_changes_set_name.yml +2 -2
  199. data/spec/support/sdam/rs/primary_disconnect.yml +2 -2
  200. data/spec/support/sdam/rs/primary_disconnect_electionid.yml +5 -0
  201. data/spec/support/sdam/rs/primary_disconnect_setversion.yml +5 -0
  202. data/spec/support/sdam/rs/primary_hint_from_secondary_with_mismatched_me.yml +58 -0
  203. data/spec/support/sdam/rs/primary_reports_new_member.yml +4 -4
  204. data/spec/support/sdam/rs/primary_to_no_primary_mismatched_me.yml +2 -2
  205. data/spec/support/sdam/rs/primary_wrong_set_name.yml +1 -1
  206. data/spec/support/sdam/rs/response_from_removed.yml +2 -2
  207. data/spec/support/sdam/rs/rsother_discovered.yml +1 -1
  208. data/spec/support/sdam/rs/sec_not_auth.yml +1 -1
  209. data/spec/support/sdam/rs/secondary_wrong_set_name.yml +1 -1
  210. data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +2 -2
  211. data/spec/support/sdam/rs/setversion_without_electionid.yml +2 -0
  212. data/spec/support/sdam/rs/stepdown_change_set_name.yml +2 -2
  213. data/spec/support/sdam/rs/unexpected_mongos.yml +1 -1
  214. data/spec/support/sdam/rs/use_setversion_without_electionid.yml +3 -0
  215. data/spec/support/sdam/rs/wrong_set_name.yml +1 -1
  216. data/spec/support/sdam/sharded/ls_timeout_mongos.yml +97 -0
  217. data/spec/support/sdam/sharded/mongos_disconnect.yml +3 -3
  218. data/spec/support/sdam/sharded/multiple_mongoses.yml +1 -1
  219. data/spec/support/sdam/sharded/non_mongos_removed.yml +1 -1
  220. data/spec/support/sdam/sharded/normalize_uri_case.yml +1 -1
  221. data/spec/support/sdam/single/direct_connection_external_ip.yml +1 -1
  222. data/spec/support/sdam/single/direct_connection_mongos.yml +1 -1
  223. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +1 -1
  224. data/spec/support/sdam/single/direct_connection_rsprimary.yml +1 -1
  225. data/spec/support/sdam/single/direct_connection_rssecondary.yml +1 -1
  226. data/spec/support/sdam/single/direct_connection_slave.yml +1 -1
  227. data/spec/support/sdam/single/direct_connection_standalone.yml +1 -1
  228. data/spec/support/sdam/single/ls_timeout_standalone.yml +35 -0
  229. data/spec/support/sdam/single/not_ok_response.yml +1 -1
  230. data/spec/support/sdam/single/standalone_removed.yml +1 -1
  231. data/spec/support/sdam/single/unavailable_seed.yml +1 -1
  232. data/spec/support/server_discovery_and_monitoring.rb +4 -0
  233. data/spec/support/shared/session.rb +236 -0
  234. metadata +53 -15
  235. metadata.gz.sig +0 -0
@@ -27,6 +27,7 @@ module Mongo
27
27
  # :bar => 1 }},
28
28
  # :multi => true,
29
29
  # :upsert => false
30
+ # :array_filters => []
30
31
  # }],
31
32
  # :db_name => 'test',
32
33
  # :coll_name => 'test_coll',
@@ -42,17 +43,31 @@ module Mongo
42
43
 
43
44
  private
44
45
 
45
- # The query selector for this update command operation.
46
- #
47
- # @return [ Hash ] The selector describing this update operation.
46
+ IDENTIFIER = 'updates'.freeze
47
+
48
48
  def selector
49
49
  { update: coll_name,
50
- updates: updates,
51
- ordered: ordered?
52
- }.tap do |cmd|
53
- cmd.merge!(writeConcern: write_concern.options) if write_concern
54
- cmd.merge!(:bypassDocumentValidation => true) if bypass_document_validation
55
- cmd.merge!(:collation => collation) if collation
50
+ updates: updates
51
+ }.merge(command_options)
52
+ end
53
+
54
+ def op_msg(server)
55
+ global_args = { update: coll_name,
56
+ Protocol::Msg::DATABASE_IDENTIFIER => db_name
57
+ }.merge!(command_options)
58
+ add_cluster_time!(global_args, server)
59
+ session.add_id!(global_args) if session
60
+
61
+ section = { type: 1, payload: { identifier: IDENTIFIER, sequence: updates } }
62
+ flags = unacknowledged_write? ? [:more_to_come] : [:none]
63
+ Protocol::Msg.new(flags, {}, global_args, section)
64
+ end
65
+
66
+ def message(server)
67
+ if server.features.op_msg_enabled?
68
+ op_msg(server)
69
+ else
70
+ Protocol::Query.new(db_name, Database::COMMAND, selector, options)
56
71
  end
57
72
  end
58
73
  end
@@ -23,6 +23,7 @@ module Mongo
23
23
  # @since 2.0.0
24
24
  module Writable
25
25
  include Limited
26
+ include UsesCommandOpMsg
26
27
 
27
28
  # Execute the operation.
28
29
  #
@@ -42,13 +43,25 @@ module Mongo
42
43
 
43
44
  private
44
45
 
46
+ def command_options
47
+ opts = { ordered: ordered? }
48
+ opts[:writeConcern] = write_concern.options if write_concern
49
+ opts[:collation] = collation if collation
50
+ opts[:bypassDocumentValidation] = true if bypass_document_validation
51
+ opts
52
+ end
53
+
45
54
  # The wire protocol message for this write operation.
46
55
  #
47
56
  # @return [ Mongo::Protocol::Query ] Wire protocol message.
48
57
  #
49
58
  # @since 2.0.0
50
59
  def message(server)
51
- Protocol::Query.new(db_name, Database::COMMAND, selector, options)
60
+ if server.features.op_msg_enabled?
61
+ command_op_msg(server, selector, options)
62
+ else
63
+ Protocol::Query.new(db_name, Database::COMMAND, selector, options)
64
+ end
52
65
  end
53
66
  end
54
67
  end
@@ -52,7 +52,10 @@ module Mongo
52
52
 
53
53
  def execute_write_command(server)
54
54
  command_spec = spec.merge(:documents => ensure_ids(documents))
55
- Result.new(Command::Insert.new(command_spec).execute(server), @ids).validate!
55
+ result = Result.new(Command::Insert.new(command_spec).execute(server), @ids)
56
+ server.update_cluster_time(result)
57
+ session.process(result) if session
58
+ result.validate!
56
59
  end
57
60
 
58
61
  def execute_message(server)
@@ -35,12 +35,12 @@ module Mongo
35
35
  # @example Instantiate the result.
36
36
  # Result.new(replies, inserted_ids)
37
37
  #
38
- # @param [ Protocol::Reply ] replies The wire protocol replies.
38
+ # @param [ Protocol::Message ] replies The wire protocol replies.
39
39
  # @param [ Array<Object> ] ids The ids of the inserted documents.
40
40
  #
41
41
  # @since 2.0.0
42
42
  def initialize(replies, ids)
43
- @replies = replies.is_a?(Protocol::Reply) ? [ replies ] : replies
43
+ @replies = [ *replies ] if replies
44
44
  @inserted_ids = ids
45
45
  end
46
46
 
@@ -31,12 +31,13 @@ module Mongo
31
31
  # :u => { :$set => { :bar => 1 }},
32
32
  # :multi => true,
33
33
  # :upsert => false
34
+ # :array_filters => []
34
35
  # },
35
36
  # :db_name => 'test',
36
37
  # :coll_name => 'test_coll',
37
38
  # :write_concern => write_concern
38
39
  # })
39
- #
40
+
40
41
  # Initialization:
41
42
  # param [ Hash ] spec The specifications for the update.
42
43
  #
@@ -63,6 +64,10 @@ module Mongo
63
64
  Command::Update.new(s)
64
65
  end
65
66
 
67
+ def has_array_filters?
68
+ update[Operation::ARRAY_FILTERS]
69
+ end
70
+
66
71
  def has_collation?
67
72
  update[:collation] || update[Operation::COLLATION]
68
73
  end
@@ -71,6 +76,7 @@ module Mongo
71
76
  flags = []
72
77
  flags << :multi_update if update[Operation::MULTI]
73
78
  flags << :upsert if update[Operation::UPSERT]
79
+
74
80
  Protocol::Update.new(
75
81
  db_name,
76
82
  coll_name,
@@ -34,16 +34,30 @@ module Mongo
34
34
  #
35
35
  # @since 2.1.0
36
36
  def execute(server)
37
- if !server.features.write_command_enabled? || unacknowledged_write?
37
+ if unacknowledged_write?
38
38
  raise Error::UnsupportedCollation.new(Error::UnsupportedCollation::UNACKNOWLEDGED_WRITES_MESSAGE) if has_collation?
39
+ raise Error::UnsupportedArrayFilters.new(Error::UnsupportedArrayFilters::UNACKNOWLEDGED_WRITES_MESSAGE) if has_array_filters?
40
+ end
41
+
42
+ if !server.features.write_command_enabled? # version < 2.4
39
43
  execute_message(server)
40
- else
44
+ elsif server.features.op_msg_enabled? # version 3.6
41
45
  execute_write_command(server)
46
+ else # server version is 2.6 through 3.4
47
+ if unacknowledged_write?
48
+ execute_message(server)
49
+ else
50
+ execute_write_command(server)
51
+ end
42
52
  end
43
53
  end
44
54
 
45
55
  private
46
56
 
57
+ def has_array_filters?
58
+ false
59
+ end
60
+
47
61
  def has_collation?
48
62
  false
49
63
  end
@@ -54,7 +68,10 @@ module Mongo
54
68
 
55
69
  def execute_write_command(server)
56
70
  result_class = self.class.const_defined?(:Result, false) ? self.class::Result : Result
57
- result_class.new(write_command_op.execute(server)).validate!
71
+ result = result_class.new(write_command_op.execute(server))
72
+ server.update_cluster_time(result)
73
+ session.process(result) if session
74
+ result.validate!
58
75
  end
59
76
  end
60
77
  end
@@ -1,15 +1,18 @@
1
1
  # Wire Protocol Base
2
2
  require 'mongo/protocol/serializers'
3
+ require 'mongo/protocol/registry'
3
4
  require 'mongo/protocol/bit_vector'
4
5
  require 'mongo/protocol/message'
5
6
 
6
7
  # Client Requests
8
+ require 'mongo/protocol/compressed'
7
9
  require 'mongo/protocol/delete'
8
10
  require 'mongo/protocol/get_more'
9
11
  require 'mongo/protocol/insert'
10
12
  require 'mongo/protocol/kill_cursors'
11
13
  require 'mongo/protocol/query'
12
14
  require 'mongo/protocol/update'
15
+ require 'mongo/protocol/msg'
13
16
 
14
17
  # Server Responses
15
18
  require 'mongo/protocol/reply'
@@ -28,7 +28,7 @@ module Mongo
28
28
  def initialize(layout)
29
29
  @masks = {}
30
30
  layout.each_with_index do |field, index|
31
- @masks[field] = 2**index
31
+ @masks[field] = 2**index if field
32
32
  end
33
33
  end
34
34
 
@@ -40,7 +40,7 @@ module Mongo
40
40
  # @return [ String ] Buffer that received the serialized vector
41
41
  def serialize(buffer, value, validating_keys = BSON::Config.validating_keys?)
42
42
  bits = 0
43
- value.each { |flag| bits |= @masks[flag] }
43
+ value.each { |flag| bits |= (@masks[flag] || 0) }
44
44
  buffer.put_int32(bits)
45
45
  end
46
46
 
@@ -0,0 +1,135 @@
1
+ # Copyright (C) 2017 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'zlib'
16
+
17
+ module Mongo
18
+ module Protocol
19
+
20
+ # MongoDB Wire protocol Compressed message.
21
+ #
22
+ # This is a bi-directional message that compresses another opcode.
23
+ #
24
+ # @api semipublic
25
+ #
26
+ # @since 2.5.0
27
+ class Compressed < Message
28
+
29
+ # The byte signaling that the message has been compressed with Zlib.
30
+ #
31
+ # @since 2.5.0
32
+ ZLIB_BYTE = 2.chr.force_encoding(BSON::BINARY).freeze
33
+
34
+ # The Zlib compressor identifier.
35
+ #
36
+ # @since 2.5.0
37
+ ZLIB = 'zlib'.freeze
38
+
39
+ # The compressor identifier to byte map.
40
+ #
41
+ # @since 2.5.0
42
+ COMPRESSOR_ID_MAP = { ZLIB => ZLIB_BYTE }.freeze
43
+
44
+ # Creates a new OP_COMPRESSED message.
45
+ #
46
+ # @example Create an OP_COMPRESSED message.
47
+ # Compressed.new(original_message, 'zlib')
48
+ #
49
+ # @param [ Mongo::Protocol::Message ] message The original message.
50
+ # @param [ String, Symbol ] compressor The compression algorithm to use.
51
+ # @param [ Integer ] level The zlib compression level to use. -1 and nil imply default.
52
+ #
53
+ # @since 2.5.0
54
+ def initialize(message, compressor, zlib_compression_level = nil)
55
+ @original_message = message
56
+ @original_op_code = message.op_code
57
+ @uncompressed_size = 0
58
+ @compressor_id = COMPRESSOR_ID_MAP[compressor]
59
+ @compressed_message = ''
60
+ @zlib_compression_level = zlib_compression_level if zlib_compression_level && zlib_compression_level != -1
61
+ @request_id = message.set_request_id
62
+ end
63
+
64
+ # Inflate an OP_COMRESSED message and return the original message.
65
+ #
66
+ # @example Inflate a compressed message.
67
+ # message.inflate!
68
+ #
69
+ # @return [ Protocol::Message ] The inflated message.
70
+ #
71
+ # @since 2.5.0
72
+ def inflate!
73
+ message = Registry.get(@original_op_code).allocate
74
+ uncompressed_message = Zlib::Inflate.inflate(@compressed_message)
75
+
76
+ buf = BSON::ByteBuffer.new(uncompressed_message)
77
+
78
+ message.send(:fields).each do |field|
79
+ if field[:multi]
80
+ Message.deserialize_array(message, buf, field)
81
+ else
82
+ Message.deserialize_field(message, buf, field)
83
+ end
84
+ end
85
+ message
86
+ end
87
+
88
+ # Whether the message expects a reply from the database.
89
+ #
90
+ # @example Does the message require a reply?
91
+ # message.replyable?
92
+ #
93
+ # @return [ true, false ] If the message expects a reply.
94
+ #
95
+ # @since 2.5.0
96
+ def replyable?
97
+ @original_message.replyable?
98
+ end
99
+
100
+ private
101
+
102
+ # The operation code for a +Compressed+ message.
103
+ # @return [ Fixnum ] the operation code.
104
+ #
105
+ # @since 2.5.0
106
+ OP_CODE = 2012
107
+
108
+ # @!attribute
109
+ # Field representing the original message's op code as an Int32.
110
+ field :original_op_code, Int32
111
+
112
+ # @!attribute
113
+ # @return [ Fixnum ] The size of the original message, excluding header as an Int32.
114
+ field :uncompressed_size, Int32
115
+
116
+ # @!attribute
117
+ # @return [ String ] The id of the compressor as a single byte.
118
+ field :compressor_id, Byte
119
+
120
+ # @!attribute
121
+ # @return [ String ] The actual compressed message bytes.
122
+ field :compressed_message, Bytes
123
+
124
+ def serialize_fields(buffer, max_bson_size)
125
+ buf = BSON::ByteBuffer.new
126
+ @original_message.send(:serialize_fields, buf, max_bson_size)
127
+ @uncompressed_size = buf.length
128
+ @compressed_message = Zlib::Deflate.deflate(buf.to_s, @zlib_compression_level).force_encoding(BSON::BINARY)
129
+ super
130
+ end
131
+
132
+ Registry.register(OP_CODE, self)
133
+ end
134
+ end
135
+ end
@@ -54,16 +54,16 @@ module Mongo
54
54
  # @example Return the event payload.
55
55
  # message.payload
56
56
  #
57
- # @return [ Hash ] The event payload.
57
+ # @return [ BSON::Document ] The event payload.
58
58
  #
59
59
  # @since 2.1.0
60
60
  def payload
61
- {
61
+ BSON::Document.new(
62
62
  command_name: 'delete',
63
63
  database_name: @database,
64
64
  command: upconverter.command,
65
65
  request_id: request_id
66
- }
66
+ )
67
67
  end
68
68
 
69
69
  protected
@@ -74,9 +74,9 @@ module Mongo
74
74
 
75
75
  # The operation code required to specify a Delete message.
76
76
  # @return [Fixnum] the operation code.
77
- def op_code
78
- 2006
79
- end
77
+ #
78
+ # @since 2.5.0
79
+ OP_CODE = 2006
80
80
 
81
81
  # Available flags for a Delete message.
82
82
  FLAGS = [:single_remove]
@@ -162,6 +162,8 @@ module Mongo
162
162
  end
163
163
  end
164
164
  end
165
+
166
+ Registry.register(OP_CODE, self)
165
167
  end
166
168
  end
167
169
  end
@@ -50,16 +50,16 @@ module Mongo
50
50
  # @example Return the event payload.
51
51
  # message.payload
52
52
  #
53
- # @return [ Hash ] The event payload.
53
+ # @return [ BSON::Document ] The event payload.
54
54
  #
55
55
  # @since 2.1.0
56
56
  def payload
57
- {
57
+ BSON::Document.new(
58
58
  command_name: 'getMore',
59
59
  database_name: @database,
60
60
  command: upconverter.command,
61
61
  request_id: request_id
62
- }
62
+ )
63
63
  end
64
64
 
65
65
  # Get more messages require replies from the database.
@@ -82,9 +82,9 @@ module Mongo
82
82
 
83
83
  # The operation code required to specify a GetMore message.
84
84
  # @return [Fixnum] the operation code.
85
- def op_code
86
- 2005
87
- end
85
+ #
86
+ # @since 2.5.0
87
+ OP_CODE = 2005
88
88
 
89
89
  # Field representing Zero encoded as an Int32
90
90
  field :zero, Zero
@@ -154,6 +154,8 @@ module Mongo
154
154
  document
155
155
  end
156
156
  end
157
+
158
+ Registry.register(OP_CODE, self)
157
159
  end
158
160
  end
159
161
  end