mongo 2.6.0 → 2.6.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8c5dc91c26dc7d6d0a6c9f50e39c6d7b53130d08e75611d9f2a81162ed5a53e2
4
- data.tar.gz: ceb6c12c3e4a7e5b9552fa8501b8faa6835ce110a6f32e6df8e8c65f53599b76
3
+ metadata.gz: d8e500892649b1d8d1817ec229c1d56d97837e252452654af04e995d1416082a
4
+ data.tar.gz: 5fa8c7ca6caa84c0c81ed9f8ab3cd6566f579fc10ac28f510628f2de790040c7
5
5
  SHA512:
6
- metadata.gz: 94c8eeb0c0afa60bd77ad0fc8139bfa818e9b3d1ac1d7e1656d92cf91e50d0481d3e9bb275bd3f5143b540036e5acc314e573e79c5891ad85003b05eadfc695e
7
- data.tar.gz: 94e7a7f089b67ec901c8182f96d9a020ba67143b5e0823d3c39f0fa7dfa8cc7e0132a40df65a64c2c308b2d255316dbac4e20180b70bbeaa5680b3ef55e6f70e
6
+ metadata.gz: 725de14593b44d0bf8b370f53a5e18a8f5d033efddd2e05096ec561b69f51b01b70394d3c8ebab1e89dbb7ecbb7784dbb161376d1194130ae6d016afd39344ae
7
+ data.tar.gz: 989ee85302acac376637d777e1c83cff4e7fa5d932fc62d489b3192d0b7336875fe831a0742d9953892108d2cb86c5b825f84d73a1779c0149fef2ffbb04aa05
Binary file
data.tar.gz.sig CHANGED
@@ -1 +1,3 @@
1
- ���.,�1��[+��>4��v�1��8�9+ *�7{R�'���E�R �@�ج�����t$����52eh��?��jG!��E��:�x��47Dr]��&�=Ϗl›�-�m:e�� ��Y��+����$���S l%@|L���BB�/��1�3^Ε��a'�N'azn ۝�@����Oy[��ԫ c�,��&<��2'����3] цY=�����ӌa6 �e��H`����Np4�����q� ו��Y9��
1
+ ���6Ș�����>in{��M�(����Jʐ4���E�tm}WBA8�������y��z���W�S��^<~6���&%q�`��M��(����<�7��Kݰxj�����d�\����f���f�f��EML�|3tKDЂ9�J<3-�,���<�Q��!Eg>L>��8Yf95��֙<i�lgu������mx[=�f
2
+ ��;�|klr�؁�n
3
+ v�a����gn���0�O�I�S���r�PowVo`�
@@ -42,3 +42,4 @@ require 'mongo/socket'
42
42
  require 'mongo/uri'
43
43
  require 'mongo/version'
44
44
  require 'mongo/write_concern'
45
+ require 'mongo/lint'
@@ -142,7 +142,7 @@ module Mongo
142
142
  # @param [ Float ] socket_timeout The socket timeout.
143
143
  # @param [ Hash ] ssl_options SSL options.
144
144
  #
145
- # @return [ Pool::Socket::SSL, Pool::Socket::TCP, Pool::Socket::Unix ] The socket.
145
+ # @return [ Mongo::Socket::SSL, Mongo::Socket::TCP, Mongo::Socket::Unix ] The socket.
146
146
  #
147
147
  # @since 2.0.0
148
148
  def socket(socket_timeout, ssl_options = {})
@@ -80,7 +80,7 @@ module Mongo
80
80
  # @param [ Float ] socket_timeout The socket timeout.
81
81
  # @param [ Hash ] ssl_options SSL options.
82
82
  #
83
- # @return [ Pool::Socket::SSL, Pool::Socket::TCP ] The socket.
83
+ # @return [ Mongo::Socket::SSL, Mongo::Socket::TCP ] The socket.
84
84
  #
85
85
  # @since 2.0.0
86
86
  def socket(socket_timeout, ssl_options = {})
@@ -96,7 +96,7 @@ module Mongo
96
96
  # @param [ Float ] socket_timeout The socket timeout.
97
97
  # @param [ Hash ] ssl_options SSL options.
98
98
  #
99
- # @return [ Pool::Socket::SSL, Pool::Socket::TCP ] The socket.
99
+ # @return [ Mongo::Socket::SSL, Mongo::Socket::TCP ] The socket.
100
100
  #
101
101
  # @since 2.0.0
102
102
  def socket(socket_timeout, ssl_options = {})
@@ -65,7 +65,7 @@ module Mongo
65
65
  # @param [ Float ] socket_timeout The socket timeout.
66
66
  # @param [ Hash ] ssl_options SSL options - ignored.
67
67
  #
68
- # @return [ Pool::Socket::Unix ] The socket.
68
+ # @return [ Mongo::Socket::Unix ] The socket.
69
69
  #
70
70
  # @since 2.0.0
71
71
  def socket(socket_timeout, ssl_options = {})
@@ -193,7 +193,7 @@ module Mongo
193
193
  # supports 'zlib'.
194
194
  # @option options [ Hash ] :read The read preference options. The hash
195
195
  # may have the following items:
196
- # - *:read* -- read preference specified as a symbol; valid values are
196
+ # - *:mode* -- read preference specified as a symbol; valid values are
197
197
  # *:primary*, *:primary_preferred*, *:secondary*, *:secondary_preferred*
198
198
  # and *:nearest*.
199
199
  # - *:tag_sets* -- an array of hashes.
@@ -219,18 +219,18 @@ module Mongo
219
219
  # @option options [ OpenSSL::PKey ] :ssl_key_object The private key used to identify the
220
220
  # connection against MongoDB
221
221
  # @option options [ String ] :ssl_key_pass_phrase A passphrase for the private key.
222
- # @option options [ true, false ] :ssl_verify Whether or not to do peer certification
222
+ # @option options [ true, false ] :ssl_verify Whether to do peer certificate
223
223
  # validation.
224
- # @option options [ String ] :ssl_ca_cert The file containing a set of concatenated
225
- # certification authority certifications used to validate certs passed from the
224
+ # @option options [ String ] :ssl_ca_cert The file containing concatenated
225
+ # certificate authority certificates used to validate certs passed from the
226
226
  # other end of the connection. One of :ssl_ca_cert, :ssl_ca_cert_string or
227
227
  # :ssl_ca_cert_object (in order of priority) is required for :ssl_verify.
228
- # @option options [ String ] :ssl_ca_cert_string A string containing a set of concatenated
229
- # certification authority certifications used to validate certs passed from the
228
+ # @option options [ String ] :ssl_ca_cert_string A string containing concatenated
229
+ # certificate authority certificates used to validate certs passed from the
230
230
  # other end of the connection. One of :ssl_ca_cert, :ssl_ca_cert_string or
231
231
  # :ssl_ca_cert_object (in order of priority) is required for :ssl_verify.
232
232
  # @option options [ Array<OpenSSL::X509::Certificate> ] :ssl_ca_cert_object An array of
233
- # OpenSSL::X509::Certificate representing the certification authority certifications used
233
+ # OpenSSL::X509::Certificate representing the certificate authority certificates used
234
234
  # to validate certs passed from the other end of the connection. One of :ssl_ca_cert,
235
235
  # :ssl_ca_cert_string or :ssl_ca_cert_object (in order of priority) is required for :ssl_verify.
236
236
  # @option options [ Float ] :socket_timeout The timeout, in seconds, to
@@ -261,6 +261,7 @@ module Mongo
261
261
  #
262
262
  # @since 2.0.0
263
263
  def initialize(addresses_or_uri, options = Options::Redacted.new)
264
+ Mongo::Lint.validate_underscore_read_preference(options[:read])
264
265
  if addresses_or_uri.is_a?(::String)
265
266
  create_from_uri(addresses_or_uri, validate_options!(options))
266
267
  else
@@ -301,6 +302,12 @@ module Mongo
301
302
  # client.read_preference
302
303
  #
303
304
  # @return [ BSON::Document ] The user-defined read preference.
305
+ # The document may have the following fields:
306
+ # - *:read* -- read preference specified as a symbol; valid values are
307
+ # *:primary*, *:primary_preferred*, *:secondary*, *:secondary_preferred*
308
+ # and *:nearest*.
309
+ # - *:tag_sets* -- an array of hashes.
310
+ # - *:local_threshold*.
304
311
  #
305
312
  # @since 2.0.0
306
313
  def read_preference
@@ -68,7 +68,15 @@ module Mongo
68
68
  end
69
69
 
70
70
  def read_pref_formatted
71
- @read_formatted ||= ServerSelector.get(read).to_mongos if read
71
+ @read_formatted ||= begin
72
+ if read
73
+ read_pref = ServerSelector.get(read).to_mongos
74
+ Mongo::Lint.validate_camel_case_read_preference(read_pref)
75
+ read_pref
76
+ else
77
+ nil
78
+ end
79
+ end
72
80
  end
73
81
 
74
82
  def special_filter
@@ -139,6 +139,7 @@ module Mongo
139
139
  cmd[:limit] = opts[:limit] if opts[:limit]
140
140
  cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
141
141
  cmd[:readConcern] = collection.read_concern if collection.read_concern
142
+ Mongo::Lint.validate_underscore_read_preference(opts[:read])
142
143
  read_pref = opts[:read] || read_preference
143
144
  selector = ServerSelector.get(read_pref || server_selector)
144
145
  with_session(opts) do |session|
@@ -203,6 +204,7 @@ module Mongo
203
204
  cmd = { count: collection.name }
204
205
  cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
205
206
  cmd[:readConcern] = collection.read_concern if collection.read_concern
207
+ Mongo::Lint.validate_underscore_read_preference(opts[:read])
206
208
  read_pref = opts[:read] || read_preference
207
209
  selector = ServerSelector.get(read_pref || server_selector)
208
210
  with_session(opts) do |session|
@@ -240,6 +242,7 @@ module Mongo
240
242
  :query => filter }
241
243
  cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
242
244
  cmd[:readConcern] = collection.read_concern if collection.read_concern
245
+ Mongo::Lint.validate_underscore_read_preference(opts[:read])
243
246
  read_pref = opts[:read] || read_preference
244
247
  selector = ServerSelector.get(read_pref || server_selector)
245
248
  with_session(opts) do |session|
@@ -537,11 +540,13 @@ module Mongo
537
540
  end
538
541
 
539
542
  def read_preference
540
- if options[:session] && options[:session].in_transaction?
541
- options[:session].send(:txn_read_pref) || collection.client.read_preference
543
+ rp = if options[:session] && options[:session].in_transaction?
544
+ options[:session].txn_read_preference || collection.client.read_preference
542
545
  else
543
546
  @read_preference ||= (options[:read] || collection.read_preference)
544
547
  end
548
+ Mongo::Lint.validate_underscore_read_preference(rp)
549
+ rp
545
550
  end
546
551
 
547
552
  def server_selector
@@ -153,7 +153,8 @@ module Mongo
153
153
  #
154
154
  # @return [ Hash ] The result of the command execution.
155
155
  def command(operation, opts = {})
156
- txn_read_pref = opts[:session] && opts[:session].in_transaction? && opts[:session].txn_read_pref
156
+ txn_read_pref = opts[:session] && opts[:session].in_transaction? && opts[:session].txn_read_preference
157
+ Mongo::Lint.validate_underscore_read_preference(txn_read_pref)
157
158
  preference = ServerSelector.get(txn_read_pref || opts[:read] || ServerSelector::PRIMARY)
158
159
  server = preference.select_server(cluster)
159
160
 
@@ -151,6 +151,7 @@ require 'mongo/error/invalid_update_document'
151
151
  require 'mongo/error/invalid_uri'
152
152
  require 'mongo/error/invalid_write_concern'
153
153
  require 'mongo/error/insufficient_iteration_count'
154
+ require 'mongo/error/lint_error'
154
155
  require 'mongo/error/max_bson_size'
155
156
  require 'mongo/error/max_message_size'
156
157
  require 'mongo/error/mismatched_domain'
@@ -0,0 +1,35 @@
1
+ # Copyright (C) 2018 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
+ class Error
17
+
18
+ # Raised when the driver is used incorrectly.
19
+ #
20
+ # Normally the driver passes certain data to the server and lets the
21
+ # server return an error if the data is invalid. This makes it possible
22
+ # for the server to add functionality in the future and for older
23
+ # driver versions to support such functionality transparently, but
24
+ # also complicates debugging.
25
+ #
26
+ # Setting the environment variable MONGO_RUBY_DRIVER_LINT to 1, true
27
+ # or yes will make the driver perform additional checks on data it passes
28
+ # to the server, to flag failures sooner. This exception is raised on
29
+ # such failures.
30
+ #
31
+ # @since 2.7.0
32
+ class LintError < Error
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,45 @@
1
+ module Mongo
2
+ # @api private
3
+ module Lint
4
+ def validate_underscore_read_preference(read_pref)
5
+ return unless enabled?
6
+ if read_pref
7
+ validate_underscore_read_preference_mode(read_pref[:mode] || read_pref['mode'])
8
+ end
9
+ end
10
+ module_function :validate_underscore_read_preference
11
+
12
+ def validate_underscore_read_preference_mode(mode)
13
+ return unless enabled?
14
+ if mode
15
+ unless %w(primary primary_preferred secondary secondary_preferred nearest).include?(mode.to_s)
16
+ raise Error::LintError, "Invalid read preference mode: #{mode}"
17
+ end
18
+ end
19
+ end
20
+ module_function :validate_underscore_read_preference_mode
21
+
22
+ def validate_camel_case_read_preference(read_pref)
23
+ return unless enabled?
24
+ if read_pref
25
+ validate_camel_case_read_preference_mode(read_pref[:mode] || read_pref['mode'])
26
+ end
27
+ end
28
+ module_function :validate_camel_case_read_preference
29
+
30
+ def validate_camel_case_read_preference_mode(mode)
31
+ return unless enabled?
32
+ if mode
33
+ unless %w(primary primaryPreferred secondary secondaryPreferred nearest).include?(mode.to_s)
34
+ raise Error::LintError, "Invalid read preference mode: #{mode}"
35
+ end
36
+ end
37
+ end
38
+ module_function :validate_camel_case_read_preference_mode
39
+
40
+ def enabled?
41
+ ENV['MONGO_RUBY_DRIVER_LINT'] && %w(1 yes true).include?(ENV['MONGO_RUBY_DRIVER_LINT'].downcase)
42
+ end
43
+ module_function :enabled?
44
+ end
45
+ end
@@ -30,8 +30,9 @@ module Mongo
30
30
 
31
31
  def update_selector_for_read_pref(sel, server)
32
32
  if read && server.mongos? && read_pref = read.to_mongos
33
+ Mongo::Lint.validate_camel_case_read_preference(read_pref)
33
34
  sel = sel[:$query] ? sel : {:$query => sel}
34
- sel.merge(:$readPreference => read_pref)
35
+ sel = sel.merge(:$readPreference => read_pref)
35
36
  else
36
37
  sel
37
38
  end
@@ -24,8 +24,6 @@ module Mongo
24
24
 
25
25
  ZERO_TIMESTAMP = BSON::Timestamp.new(0, 0)
26
26
 
27
- READ_PREFERENCE = '$readPreference'.freeze
28
-
29
27
  READ_COMMANDS = [
30
28
  :aggregate,
31
29
  :collStats,
@@ -101,8 +99,8 @@ module Mongo
101
99
  session.suppress_read_write_concern!(selector)
102
100
  end
103
101
 
104
- def validate_read_pref!(selector)
105
- session.validate_read_pref!(selector) if read_command?(selector)
102
+ def validate_read_preference!(selector)
103
+ session.validate_read_preference!(selector) if read_command?(selector)
106
104
  end
107
105
 
108
106
  def update_session_state!
@@ -113,7 +111,7 @@ module Mongo
113
111
  sel = selector(server)
114
112
  add_write_concern!(sel)
115
113
  sel[Protocol::Msg::DATABASE_IDENTIFIER] = db_name
116
- sel[READ_PREFERENCE] = read.to_doc if read
114
+ sel['$readPreference'] = read.to_doc if read
117
115
 
118
116
  if server.features.sessions_enabled?
119
117
  apply_cluster_time!(sel, server)
@@ -125,7 +123,7 @@ module Mongo
125
123
  apply_autocommit!(sel)
126
124
  apply_txn_opts!(sel)
127
125
  suppress_read_write_concern!(sel)
128
- validate_read_pref!(sel)
126
+ validate_read_preference!(sel)
129
127
  update_session_state!
130
128
  apply_txn_num!(sel)
131
129
  end
@@ -138,7 +136,7 @@ module Mongo
138
136
  apply_autocommit!(sel)
139
137
  apply_txn_opts!(sel)
140
138
  suppress_read_write_concern!(sel)
141
- validate_read_pref!(sel)
139
+ validate_read_preference!(sel)
142
140
  update_session_state!
143
141
  apply_txn_num!(sel)
144
142
  end
@@ -301,6 +301,7 @@ module Mongo
301
301
  OPTION_MAPPINGS.each do |legacy, option|
302
302
  document.store(option, options[legacy]) unless options[legacy].nil?
303
303
  end
304
+ Mongo::Lint.validate_camel_case_read_preference(filter['readPreference'])
304
305
  SPECIAL_FIELD_MAPPINGS.each do |special, normal|
305
306
  document.store(normal, filter[special]) unless filter[special].nil?
306
307
  end
@@ -201,7 +201,7 @@ module Mongo
201
201
  # @example Get the connection pool for the server.
202
202
  # server.pool
203
203
  #
204
- # @return [ Mongo::Pool ] The connection pool.
204
+ # @return [ Mongo::Server::ConnectionPool ] The connection pool.
205
205
  #
206
206
  # @since 2.0.0
207
207
  def pool
@@ -47,7 +47,7 @@ module Mongo
47
47
  # @example Check a connection out from the pool.
48
48
  # pool.checkout
49
49
  #
50
- # @return [ Mongo::Pool::Connection ] The checked out connection.
50
+ # @return [ Mongo::Server::Connection ] The checked out connection.
51
51
  #
52
52
  # @since 2.0.0
53
53
  def checkout
@@ -120,14 +120,14 @@ module Mongo
120
120
 
121
121
  class << self
122
122
 
123
- # Get a connection pool for the provided server.
123
+ # Creates a new connection pool for the provided server.
124
124
  #
125
- # @example Get a connection pool.
126
- # Mongo::Pool.get(server)
125
+ # @example Create a new connection pool.
126
+ # Mongo::Server::ConnectionPool.get(server)
127
127
  #
128
128
  # @param [ Mongo::Server ] server The server.
129
129
  #
130
- # @return [ Mongo::Pool ] The connection pool.
130
+ # @return [ Mongo::Server::ConnectionPool ] The connection pool.
131
131
  #
132
132
  # @since 2.0.0
133
133
  def get(server)
@@ -53,7 +53,7 @@ module Mongo
53
53
  # @example Dequeue a connection.
54
54
  # queue.dequeue
55
55
  #
56
- # @return [ Mongo::Pool::Connection ] The next connection.
56
+ # @return [ Mongo::Server::Connection ] The next connection.
57
57
  #
58
58
  # @since 2.0.0
59
59
  def dequeue
@@ -82,7 +82,7 @@ module Mongo
82
82
  # @example Enqueue a connection.
83
83
  # queue.enqueue(connection)
84
84
  #
85
- # @param [ Mongo::Pool::Connection ] connection The connection.
85
+ # @param [ Mongo::Server::Connection ] connection The connection.
86
86
  #
87
87
  # @since 2.0.0
88
88
  def enqueue(connection)
@@ -96,7 +96,7 @@ module Mongo
96
96
  # the initial size of the queue.
97
97
  #
98
98
  # @example Create the queue.
99
- # Mongo::Pool::Queue.new(max_pool_size: 5) { Connection.new }
99
+ # Mongo::Server::ConnectionPool::Queue.new(max_pool_size: 5) { Connection.new }
100
100
  #
101
101
  # @param [ Hash ] options The options.
102
102
  #
@@ -124,7 +124,7 @@ module Mongo
124
124
  #
125
125
  # @since 2.0.0
126
126
  def inspect
127
- "#<Mongo::Pool::Queue:0x#{object_id} min_size=#{min_size} max_size=#{max_size} " +
127
+ "#<Mongo::Server::ConnectionPool::Queue:0x#{object_id} min_size=#{min_size} max_size=#{max_size} " +
128
128
  "wait_timeout=#{wait_timeout} current_size=#{queue.size}>"
129
129
  end
130
130
 
@@ -71,6 +71,7 @@ module Mongo
71
71
  # @since 2.0.0
72
72
  def get(preference = {})
73
73
  return preference if PREFERENCES.values.include?(preference.class)
74
+ Mongo::Lint.validate_underscore_read_preference(preference)
74
75
  PREFERENCES.fetch((preference[:mode] || :primary).to_sym).new(preference)
75
76
  end
76
77
  end
@@ -110,9 +110,16 @@ module Mongo
110
110
  # @param [ Client ] client The client through which this session is created.
111
111
  # @param [ Hash ] options The options for this session.
112
112
  #
113
+ # @option options [ Hash ] :read_preference The read preference options hash,
114
+ # with the following optional keys:
115
+ # - *:mode* -- the read preference as a string or symbol; valid values are
116
+ # *:primary*, *:primary_preferred*, *:secondary*, *:secondary_preferred*
117
+ # and *:nearest*.
118
+ #
113
119
  # @since 2.5.0
114
120
  def initialize(server_session, client, options = {})
115
121
  @server_session = server_session
122
+ options = options.dup
116
123
 
117
124
  # Because the read preference will need to be inserted into a command as a string, we convert
118
125
  # it from a symbol immediately upon receiving it.
@@ -121,7 +128,7 @@ module Mongo
121
128
  end
122
129
 
123
130
  @client = client.use(:admin)
124
- @options = options.dup.freeze
131
+ @options = options.freeze
125
132
  @cluster_time = nil
126
133
  @state = NO_TRANSACTION_STATE
127
134
  end
@@ -232,7 +239,13 @@ module Mongo
232
239
  def add_txn_opts!(command, read)
233
240
  command.tap do |c|
234
241
  # The read preference should be added for all read operations.
235
- c['$readPreference'] = txn_read_pref if read && txn_read_pref
242
+ if read && txn_read_pref = txn_read_preference
243
+ Mongo::Lint.validate_underscore_read_preference(txn_read_pref)
244
+ txn_read_pref = txn_read_pref.dup
245
+ txn_read_pref[:mode] = txn_read_pref[:mode].to_s.gsub(/(_\w)/) { |match| match[1].upcase }
246
+ Mongo::Lint.validate_camel_case_read_preference(txn_read_pref)
247
+ c['$readPreference'] = txn_read_pref
248
+ end
236
249
 
237
250
  # The read concern should be added to any command that starts a transaction.
238
251
  if starting_transaction? && txn_read_concern
@@ -277,14 +290,14 @@ module Mongo
277
290
  # Ensure that the read preference of a command primary.
278
291
  #
279
292
  # @example
280
- # session.validate_read_pref!(command)
293
+ # session.validate_read_preference!(command)
281
294
  #
282
295
  # @raise [ Mongo::Error::InvalidTransactionOperation ] If the read preference of the command is
283
296
  # not primary.
284
297
  #
285
298
  # @since 2.6.0
286
- def validate_read_pref!(command)
287
- return unless in_transaction? && non_primary_readpref?(command)
299
+ def validate_read_preference!(command)
300
+ return unless in_transaction? && non_primary_read_preference_mode?(command)
288
301
 
289
302
  raise Mongo::Error::InvalidTransactionOperation.new(
290
303
  Mongo::Error::InvalidTransactionOperation::INVALID_READ_PREFERENCE)
@@ -452,14 +465,29 @@ module Mongo
452
465
 
453
466
  # Start a new transaction.
454
467
  #
455
- # Note that the transaction will not be started on the server until an operation is performed
456
- # after start_transaction is called.
468
+ # Note that the transaction will not be started on the server until an
469
+ # operation is performed after start_transaction is called.
457
470
  #
458
471
  # @example Start a new transaction
459
472
  # session.start_transaction(options)
460
473
  #
461
- # @raise [ InvalidTransactionOperation ] If a transaction is already in progress or if the
462
- # write concern is unacknowledged.
474
+ # @param [ Hash ] options The options for the transaction being started.
475
+ #
476
+ # @option options [ Hash ] read_concern The read concern options hash, with the following
477
+ # optional keys:
478
+ # - *:level* -- the read preference level as a symbol; valid values are *:local*, *:majority*,
479
+ # and *:snapshot*
480
+ # - *:after_cluster_time* -- the cluster time BSON::Document or hash specifying which cluster
481
+ # time reads should occur after
482
+ # @option options [ Hash ] :write_concern The write concern options. Can be :w =>
483
+ # Integer|String, :fsync => Boolean, :j => Boolean.
484
+ # @option options [ Hash ] :read The read preference options. The hash may have the following
485
+ # items:
486
+ # - *:mode* -- read preference specified as a symbol; the only valid value is
487
+ # *:primary*.
488
+ #
489
+ # @raise [ InvalidTransactionOperation ] If a transaction is already in
490
+ # progress or if the write concern is unacknowledged.
463
491
  #
464
492
  # @since 2.6.0
465
493
  def start_transaction(options = nil)
@@ -594,18 +622,21 @@ module Mongo
594
622
  within_states?(STARTING_TRANSACTION_STATE, TRANSACTION_IN_PROGRESS_STATE)
595
623
  end
596
624
 
597
- # Get the read preference document the session will use in the currently active transaction.
625
+ # Get the read preference the session will use in the currently
626
+ # active transaction.
627
+ #
628
+ # This is a driver style hash with underscore keys.
598
629
  #
599
630
  # @example Get the transaction's read preference
600
- # session.txn_read_pref
631
+ # session.txn_read_preference
601
632
  #
602
- # @return [ Hash ] The read preference document of the transaction.
633
+ # @return [ Hash ] The read preference of the transaction.
603
634
  #
604
635
  # @since 2.6.0
605
- def txn_read_pref
606
- rp = (txn_options && txn_options[:read_preference] && txn_options[:read_preference].dup) ||
607
- (@client.read_preference && @client.read_preference.dup)
608
- rp[:mode] = rp[:mode].to_s if rp
636
+ def txn_read_preference
637
+ rp = txn_options && txn_options[:read_preference] ||
638
+ @client.read_preference
639
+ Mongo::Lint.validate_underscore_read_preference(rp)
609
640
  rp
610
641
  end
611
642
 
@@ -639,7 +670,7 @@ module Mongo
639
670
  (@client.write_concern && @client.write_concern.options)
640
671
  end
641
672
 
642
- def non_primary_readpref?(command)
673
+ def non_primary_read_preference_mode?(command)
643
674
  return false unless command['$readPreference']
644
675
 
645
676
  mode = command['$readPreference']['mode'] || command['$readPreference'][:mode]