mongo 2.3.1 → 2.4.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +2 -3
  4. data/lib/mongo/bulk_write.rb +8 -7
  5. data/lib/mongo/bulk_write/combineable.rb +4 -0
  6. data/lib/mongo/bulk_write/transformable.rb +17 -5
  7. data/lib/mongo/bulk_write/validatable.rb +1 -0
  8. data/lib/mongo/client.rb +3 -0
  9. data/lib/mongo/cluster.rb +8 -0
  10. data/lib/mongo/cluster/app_metadata.rb +135 -0
  11. data/lib/mongo/collection.rb +42 -10
  12. data/lib/mongo/collection/view.rb +15 -1
  13. data/lib/mongo/collection/view/aggregation.rb +5 -0
  14. data/lib/mongo/collection/view/builder/aggregation.rb +13 -3
  15. data/lib/mongo/collection/view/builder/find_command.rb +7 -21
  16. data/lib/mongo/collection/view/builder/map_reduce.rb +22 -5
  17. data/lib/mongo/collection/view/iterable.rb +1 -0
  18. data/lib/mongo/collection/view/map_reduce.rb +5 -0
  19. data/lib/mongo/collection/view/readable.rb +35 -14
  20. data/lib/mongo/collection/view/writable.rb +54 -23
  21. data/lib/mongo/cursor/builder/get_more_command.rb +2 -3
  22. data/lib/mongo/database.rb +10 -2
  23. data/lib/mongo/error.rb +2 -0
  24. data/lib/mongo/error/invalid_application_name.rb +38 -0
  25. data/lib/mongo/error/invalid_server_preference.rb +24 -3
  26. data/lib/mongo/error/unsupported_collation.rb +51 -0
  27. data/lib/mongo/index/view.rb +28 -15
  28. data/lib/mongo/operation.rb +6 -0
  29. data/lib/mongo/operation/commands.rb +3 -0
  30. data/lib/mongo/operation/commands/aggregate.rb +10 -10
  31. data/lib/mongo/operation/commands/create.rb +45 -0
  32. data/lib/mongo/operation/commands/drop.rb +45 -0
  33. data/lib/mongo/operation/commands/drop_database.rb +45 -0
  34. data/lib/mongo/operation/commands/map_reduce.rb +12 -1
  35. data/lib/mongo/operation/commands/parallel_scan.rb +1 -0
  36. data/lib/mongo/operation/read_preference.rb +9 -9
  37. data/lib/mongo/operation/specifiable.rb +34 -0
  38. data/lib/mongo/operation/takes_write_concern.rb +35 -0
  39. data/lib/mongo/operation/write/bulk/bulkable.rb +1 -1
  40. data/lib/mongo/operation/write/command/create_index.rb +6 -0
  41. data/lib/mongo/operation/write/command/drop_index.rb +6 -0
  42. data/lib/mongo/operation/write/command/insert.rb +1 -1
  43. data/lib/mongo/operation/write/command/update.rb +1 -0
  44. data/lib/mongo/operation/write/command/writable.rb +2 -2
  45. data/lib/mongo/operation/write/create_index.rb +2 -2
  46. data/lib/mongo/operation/write/create_user.rb +1 -1
  47. data/lib/mongo/operation/write/delete.rb +5 -1
  48. data/lib/mongo/operation/write/gle.rb +1 -1
  49. data/lib/mongo/operation/write/insert.rb +2 -2
  50. data/lib/mongo/operation/write/remove_user.rb +1 -1
  51. data/lib/mongo/operation/write/update.rb +5 -1
  52. data/lib/mongo/operation/write/update_user.rb +1 -1
  53. data/lib/mongo/operation/write/write_command_enabled.rb +10 -2
  54. data/lib/mongo/protocol/insert.rb +1 -2
  55. data/lib/mongo/protocol/query.rb +3 -7
  56. data/lib/mongo/server.rb +8 -3
  57. data/lib/mongo/server/connection.rb +17 -11
  58. data/lib/mongo/server/description.rb +22 -0
  59. data/lib/mongo/server/description/features.rb +2 -0
  60. data/lib/mongo/server/monitor.rb +5 -0
  61. data/lib/mongo/server/monitor/connection.rb +11 -0
  62. data/lib/mongo/server_selector/nearest.rb +9 -6
  63. data/lib/mongo/server_selector/primary.rb +4 -0
  64. data/lib/mongo/server_selector/primary_preferred.rb +7 -1
  65. data/lib/mongo/server_selector/secondary.rb +5 -0
  66. data/lib/mongo/server_selector/secondary_preferred.rb +7 -2
  67. data/lib/mongo/server_selector/selectable.rb +57 -10
  68. data/lib/mongo/socket/ssl.rb +1 -0
  69. data/lib/mongo/uri.rb +4 -0
  70. data/lib/mongo/version.rb +1 -1
  71. data/lib/mongo/write_concern.rb +1 -0
  72. data/mongo.gemspec +1 -1
  73. data/spec/mongo/auth/cr_spec.rb +7 -1
  74. data/spec/mongo/auth/ldap_spec.rb +7 -1
  75. data/spec/mongo/auth/scram_spec.rb +7 -1
  76. data/spec/mongo/auth/x509_spec.rb +7 -1
  77. data/spec/mongo/bulk_write_spec.rb +598 -5
  78. data/spec/mongo/client_spec.rb +47 -1
  79. data/spec/mongo/cluster/app_metadata_spec.rb +104 -0
  80. data/spec/mongo/cluster/topology/replica_set_spec.rb +14 -8
  81. data/spec/mongo/cluster/topology/sharded_spec.rb +9 -3
  82. data/spec/mongo/cluster/topology/single_spec.rb +10 -4
  83. data/spec/mongo/cluster_spec.rb +29 -0
  84. data/spec/mongo/collection/view/aggregation_spec.rb +139 -0
  85. data/spec/mongo/collection/view/builder/find_command_spec.rb +6 -243
  86. data/spec/mongo/collection/view/map_reduce_spec.rb +104 -0
  87. data/spec/mongo/collection/view/readable_spec.rb +83 -0
  88. data/spec/mongo/collection/view/writable_spec.rb +447 -1
  89. data/spec/mongo/collection/view_spec.rb +57 -0
  90. data/spec/mongo/collection_spec.rb +926 -101
  91. data/spec/mongo/crud_spec.rb +4 -5
  92. data/spec/mongo/database_spec.rb +99 -1
  93. data/spec/mongo/index/view_spec.rb +360 -31
  94. data/spec/mongo/max_staleness_spec.rb +108 -0
  95. data/spec/mongo/operation/read_preference_spec.rb +8 -8
  96. data/spec/mongo/operation/write/command/delete_spec.rb +1 -1
  97. data/spec/mongo/operation/write/command/insert_spec.rb +1 -1
  98. data/spec/mongo/operation/write/command/update_spec.rb +1 -1
  99. data/spec/mongo/server/connection_pool_spec.rb +3 -1
  100. data/spec/mongo/server/connection_spec.rb +17 -7
  101. data/spec/mongo/server/description/features_spec.rb +50 -0
  102. data/spec/mongo/server/description_spec.rb +9 -3
  103. data/spec/mongo/server_selection_spec.rb +5 -3
  104. data/spec/mongo/server_selector/nearest_spec.rb +73 -0
  105. data/spec/mongo/server_selector/primary_preferred_spec.rb +73 -0
  106. data/spec/mongo/server_selector/primary_spec.rb +36 -0
  107. data/spec/mongo/server_selector/secondary_preferred_spec.rb +73 -0
  108. data/spec/mongo/server_selector/secondary_spec.rb +73 -0
  109. data/spec/mongo/server_selector_spec.rb +53 -0
  110. data/spec/mongo/server_spec.rb +3 -1
  111. data/spec/mongo/uri_spec.rb +54 -0
  112. data/spec/mongo/write_concern_spec.rb +18 -0
  113. data/spec/spec_helper.rb +10 -0
  114. data/spec/support/authorization.rb +8 -1
  115. data/spec/support/crud.rb +15 -0
  116. data/spec/support/crud/read.rb +27 -19
  117. data/spec/support/crud/write.rb +28 -3
  118. data/spec/support/crud_tests/read/aggregate.yml +15 -3
  119. data/spec/support/crud_tests/read/count.yml +14 -3
  120. data/spec/support/crud_tests/read/distinct.yml +13 -1
  121. data/spec/support/crud_tests/read/find.yml +12 -2
  122. data/spec/support/crud_tests/write/deleteMany.yml +22 -1
  123. data/spec/support/crud_tests/write/deleteOne.yml +20 -1
  124. data/spec/support/crud_tests/write/findOneAndDelete.yml +27 -2
  125. data/spec/support/crud_tests/write/findOneAndReplace.yml +43 -14
  126. data/spec/support/crud_tests/write/findOneAndUpdate.yml +50 -8
  127. data/spec/support/crud_tests/write/replaceOne.yml +34 -10
  128. data/spec/support/crud_tests/write/updateMany.yml +42 -11
  129. data/spec/support/crud_tests/write/updateOne.yml +32 -7
  130. data/spec/support/max_staleness/ReplicaSetNoPrimary/DefaultNoMaxStaleness.yml +26 -0
  131. data/spec/support/max_staleness/ReplicaSetNoPrimary/Incompatible.yml +25 -0
  132. data/spec/support/max_staleness/ReplicaSetNoPrimary/LastUpdateTime.yml +33 -0
  133. data/spec/support/max_staleness/ReplicaSetNoPrimary/Nearest.yml +33 -0
  134. data/spec/support/max_staleness/ReplicaSetNoPrimary/Nearest2.yml +33 -0
  135. data/spec/support/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred.yml +27 -0
  136. data/spec/support/max_staleness/ReplicaSetNoPrimary/PrimaryPreferred_tags.yml +36 -0
  137. data/spec/support/max_staleness/ReplicaSetNoPrimary/Secondary.yml +51 -0
  138. data/spec/support/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred.yml +26 -0
  139. data/spec/support/max_staleness/ReplicaSetNoPrimary/SecondaryPreferred_tags.yml +51 -0
  140. data/spec/support/max_staleness/ReplicaSetWithPrimary/DefaultNoMaxStaleness.yml +26 -0
  141. data/spec/support/max_staleness/ReplicaSetWithPrimary/Incompatible.yml +25 -0
  142. data/spec/support/max_staleness/ReplicaSetWithPrimary/LastUpdateTime.yml +35 -0
  143. data/spec/support/max_staleness/ReplicaSetWithPrimary/MaxStalenessTooSmall.yml +25 -0
  144. data/spec/support/max_staleness/ReplicaSetWithPrimary/MaxStalenessWithModePrimary.yml +23 -0
  145. data/spec/support/max_staleness/ReplicaSetWithPrimary/Nearest.yml +33 -0
  146. data/spec/support/max_staleness/ReplicaSetWithPrimary/Nearest2.yml +33 -0
  147. data/spec/support/max_staleness/ReplicaSetWithPrimary/Nearest_tags.yml +36 -0
  148. data/spec/support/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred.yml +27 -0
  149. data/spec/support/max_staleness/ReplicaSetWithPrimary/PrimaryPreferred_incompatible.yml +27 -0
  150. data/spec/support/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred.yml +26 -0
  151. data/spec/support/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags.yml +59 -0
  152. data/spec/support/max_staleness/ReplicaSetWithPrimary/SecondaryPreferred_tags2.yml +43 -0
  153. data/spec/support/max_staleness/ReplicaSetWithPrimary/Secondary_tags.yml +59 -0
  154. data/spec/support/max_staleness/ReplicaSetWithPrimary/Secondary_tags2.yml +43 -0
  155. data/spec/support/max_staleness/ReplicaSetWithPrimary/ShortHeartbeartShortMaxStaleness.yml +29 -0
  156. data/spec/support/max_staleness/ReplicaSetWithPrimary/ShortHeartbeartShortMaxStaleness2.yml +29 -0
  157. data/spec/support/max_staleness/ReplicaSetWithPrimary/ZeroMaxStaleness.yml +27 -0
  158. data/spec/support/max_staleness/Sharded/Incompatible.yml +25 -0
  159. data/spec/support/max_staleness/Sharded/SmallMaxStaleness.yml +20 -0
  160. data/spec/support/max_staleness/Single/Incompatible.yml +18 -0
  161. data/spec/support/max_staleness/Single/SmallMaxStaleness.yml +20 -0
  162. data/spec/support/server_selection.rb +25 -0
  163. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Nearest_multiple.yml +27 -0
  164. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_multi_tags.yml +31 -0
  165. data/spec/support/server_selection/selection/ReplicaSetNoPrimary/read/Secondary_multi_tags2.yml +31 -0
  166. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/Nearest_multiple.yml +34 -0
  167. data/spec/support/server_selection/selection/ReplicaSetWithPrimary/read/SecondaryPreferred_tags.yml +28 -0
  168. data/spec/support/shared/server_selector.rb +4 -3
  169. metadata +91 -6
  170. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b2d9e9f00a79f50cd0a8acbfde72ceb13993a77d
4
- data.tar.gz: 90cea8a2fe4251801c0cc40fdca77856c1c6b153
3
+ metadata.gz: 19ae8d6c4e2881b28ba15899b6f928e5f050ad5b
4
+ data.tar.gz: 7addb2834adeaaaf441891f34f58660faeead9d9
5
5
  SHA512:
6
- metadata.gz: c39d5f4e21bf2ce5390f3cd9baab0dd67f350794b33f41f0deb08a65993b9c669cdbfbe7d2008d8a8105cfcf319da526e557848580f41c1e7c78ac63a40267f9
7
- data.tar.gz: 55be4b7a6f20d2ed52dfd15d010391112927925bd3261c8c7d14a468460151a5dba91197983061004c600cf40b84b402a8d5227a670bdae1495fa845951b8a9c
6
+ metadata.gz: ad67bd7b0d541f6f97645004c983bd73183001fcd5ece022d3294d81ebaa8bb693bf96c3da944fbfdddde4064bfb23aa2503b82766326258dac53ebdafab4e36
7
+ data.tar.gz: 0d2a4a97d7a2b9ba1e8d40ccc19685336cf75c405558fae2db8e19e3b850ca7f4eb3e7cf81a6507fc2f35c2104e7604659e6e3afac3348ef67525806533ebcae
Binary file
data.tar.gz.sig CHANGED
@@ -1,3 +1,2 @@
1
- ��V+f�ӱAbc��F�>��NRή��{�#2�%�S!����!TKV�ض�x �*�9z+2c�;�`v_��o�>�/��C،VeJ��pHAL��I�{m8���r3��m%��Y��$0ρ_ií�Xo�:*�����0���� l��u�\j͎h]�-���7]4fy�����a.t#�Q'��mR�2/�/{����
2
- z+|79��3(���C�����P�����-
3
- �\E�zݝ���"��Y�
1
+ "d��"'�̑ ��(w0K_�u4��1*�^��� �@�?�ȣ��h���r����@]=tE��Z�a`��;-�稓C=p��\떃�4rx�7+QIy\B
2
+ �=.WX��E�:J4z�bc�x\=��jp)��y�s���ڬW)e �|wBos�ͬ���G-Xx��AOfj�`巪Z�`���z{���Wl�P"��J���͏˷P�HHO�2��ftz�h��,g�\hc
@@ -35,7 +35,10 @@ module Mongo
35
35
  attr_reader :options
36
36
 
37
37
  # Delegate various methods to the collection.
38
- def_delegators :@collection, :database, :cluster, :next_primary
38
+ def_delegators :@collection,
39
+ :database,
40
+ :cluster,
41
+ :next_primary
39
42
 
40
43
  def_delegators :database, :client
41
44
 
@@ -51,7 +54,9 @@ module Mongo
51
54
  operation_id = Monitoring.next_operation_id
52
55
  result_combiner = ResultCombiner.new
53
56
  write_with_retry do
57
+ operations = op_combiner.combine
54
58
  server = next_primary
59
+ raise Error::UnsupportedCollation.new if op_combiner.has_collation && !server.features.collation_enabled?
55
60
  operations.each do |operation|
56
61
  execute_operation(
57
62
  operation.keys.first,
@@ -153,12 +158,8 @@ module Mongo
153
158
  end
154
159
  end
155
160
 
156
- def operations
157
- if ordered?
158
- OrderedCombiner.new(requests).combine
159
- else
160
- UnorderedCombiner.new(requests).combine
161
- end
161
+ def op_combiner
162
+ @op_combiner ||= ordered? ? OrderedCombiner.new(requests) : UnorderedCombiner.new(requests)
162
163
  end
163
164
 
164
165
  def split_execute(name, values, server, operation_id, combiner)
@@ -25,6 +25,9 @@ module Mongo
25
25
  # @return [ Array<Hash, BSON::Document> ] requests The provided requests.
26
26
  attr_reader :requests
27
27
 
28
+ # @return [ true, false ] has_collation Whether one or more operations has a collation defined.
29
+ attr_reader :has_collation
30
+
28
31
  # Create the ordered combiner.
29
32
  #
30
33
  # @api private
@@ -37,6 +40,7 @@ module Mongo
37
40
  # @since 2.1.0
38
41
  def initialize(requests)
39
42
  @requests = requests
43
+ @has_collation = false
40
44
  end
41
45
 
42
46
  private
@@ -56,14 +56,20 @@ module Mongo
56
56
  #
57
57
  # @since 2.1.0
58
58
  DELETE_MANY_TRANSFORM = ->(doc){
59
- { Operation::Q => doc[:filter], Operation::LIMIT => 0 }
59
+ { Operation::Q => doc[:filter],
60
+ Operation::LIMIT => 0 }.tap do |d|
61
+ d[Operation::COLLATION] = doc[:collation] if doc[:collation]
62
+ end
60
63
  }
61
64
 
62
65
  # Proc to transform delete one ops.
63
66
  #
64
67
  # @since 2.1.0
65
68
  DELETE_ONE_TRANSFORM = ->(doc){
66
- { Operation::Q => doc[:filter], Operation::LIMIT => 1 }
69
+ { Operation::Q => doc[:filter],
70
+ Operation::LIMIT => 1 }.tap do |d|
71
+ d[Operation::COLLATION] = doc[:collation] if doc[:collation]
72
+ end
67
73
  }
68
74
 
69
75
  # Proc to transform insert one ops.
@@ -82,7 +88,9 @@ module Mongo
82
88
  Operation::U => doc[:replacement],
83
89
  Operation::MULTI => false,
84
90
  Operation::UPSERT => doc.fetch(:upsert, false)
85
- }
91
+ }.tap do |d|
92
+ d[Operation::COLLATION] = doc[:collation] if doc[:collation]
93
+ end
86
94
  }
87
95
 
88
96
  # Proc to transform update many ops.
@@ -94,7 +102,9 @@ module Mongo
94
102
  Operation::U => doc[:update],
95
103
  Operation::MULTI => true,
96
104
  Operation::UPSERT => doc.fetch(:upsert, false)
97
- }
105
+ }.tap do |d|
106
+ d[Operation::COLLATION] = doc[:collation] if doc[:collation]
107
+ end
98
108
  }
99
109
 
100
110
  # Proc to transform update one ops.
@@ -106,7 +116,9 @@ module Mongo
106
116
  Operation::U => doc[:update],
107
117
  Operation::MULTI => false,
108
118
  Operation::UPSERT => doc.fetch(:upsert, false)
109
- }
119
+ }.tap do |d|
120
+ d[Operation::COLLATION] = doc[:collation] if doc[:collation]
121
+ end
110
122
  }
111
123
 
112
124
  # Document mappers from the bulk api input into proper commands.
@@ -40,6 +40,7 @@ module Mongo
40
40
  def validate(name, document)
41
41
  validate_operation(name)
42
42
  validate_document(name, document)
43
+ @has_collation = true if document.respond_to?(:keys) && document[:collation]
43
44
  end
44
45
 
45
46
  private
@@ -32,6 +32,7 @@ module Mongo
32
32
  #
33
33
  # @since 2.1.2
34
34
  VALID_OPTIONS = [
35
+ :app_name,
35
36
  :auth_mech,
36
37
  :auth_mech_properties,
37
38
  :auth_source,
@@ -192,6 +193,8 @@ module Mongo
192
193
  # in which reads on a mongos are retried.
193
194
  # @option options [ Object ] :id_generator A custom object to generate ids
194
195
  # for documents. Must respond to #generate.
196
+ # @option options [ String, Symbol ] :app_name Application name that is printed to the
197
+ # mongod logs upon establishing a connection in server versions >= 3.4.
195
198
  #
196
199
  # @since 2.0.0
197
200
  def initialize(addresses_or_uri, options = Options::Redacted.new)
@@ -14,6 +14,7 @@
14
14
 
15
15
  require 'mongo/cluster/topology'
16
16
  require 'mongo/cluster/cursor_reaper'
17
+ require 'mongo/cluster/app_metadata'
17
18
 
18
19
  module Mongo
19
20
 
@@ -42,6 +43,12 @@ module Mongo
42
43
  # @return [ Object ] The cluster topology.
43
44
  attr_reader :topology
44
45
 
46
+ # @return [ Mongo::Cluster::AppMetadata ] The application metadata, used for connection
47
+ # handshakes.
48
+ #
49
+ # @since 2.4.0
50
+ attr_reader :app_metadata
51
+
45
52
  def_delegators :topology, :replica_set?, :replica_set_name, :sharded?, :single?, :unknown?
46
53
  def_delegators :@cursor_reaper, :register_cursor, :schedule_kill_cursor, :unregister_cursor
47
54
 
@@ -106,6 +113,7 @@ module Mongo
106
113
  @monitoring = monitoring
107
114
  @event_listeners = Event::Listeners.new
108
115
  @options = options.freeze
116
+ @app_metadata ||= AppMetadata.new(self)
109
117
  @topology = Topology.initial(seeds, options)
110
118
  @update_lock = Mutex.new
111
119
  @pool_lock = Mutex.new
@@ -0,0 +1,135 @@
1
+ # Copyright (C) 2016 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 'rbconfig'
16
+
17
+ module Mongo
18
+ class Cluster
19
+
20
+ # Application metadata that is sent to the server in an ismaster command,
21
+ # when a new connection is established.
22
+ #
23
+ # @api private
24
+ #
25
+ # @since 2.4.0
26
+ class AppMetadata
27
+ extend Forwardable
28
+
29
+ # The max application metadata document byte size.
30
+ #
31
+ # @since 2.4.0
32
+ MAX_DOCUMENT_SIZE = 512.freeze
33
+
34
+ # The max application name byte size.
35
+ #
36
+ # @ since 2.4.0
37
+ MAX_APP_NAME_SIZE = 128.freeze
38
+
39
+ # Instantiate the new AppMetadata object.
40
+ #
41
+ # @api private
42
+ #
43
+ # @example Instantiate the app metadata.
44
+ # Mongo::Cluster.AppMetadata.new(cluster)
45
+ #
46
+ # @param [ Mongo::Cluster ] cluster The cluster.
47
+ #
48
+ # @since 2.4.0
49
+ def initialize(cluster)
50
+ @app_name = cluster.options[:app_name]
51
+ end
52
+
53
+ # Get the bytes of the ismaster message including this metadata.
54
+ #
55
+ # @api private
56
+ #
57
+ # @example Get the ismaster message bytes.
58
+ # metadata.ismaster_bytes
59
+ #
60
+ # @return [ String ] The raw bytes.
61
+ #
62
+ # @since 2.4.0
63
+ def ismaster_bytes
64
+ @ismaster_bytes ||= validate! && serialize.to_s
65
+ end
66
+
67
+ private
68
+
69
+ def validate!
70
+ if @app_name && @app_name.bytesize > MAX_APP_NAME_SIZE
71
+ raise Error::InvalidApplicationName.new(@app_name, MAX_APP_NAME_SIZE)
72
+ end
73
+ true
74
+ end
75
+
76
+ def full_client_document
77
+ BSON::Document.new.tap do |doc|
78
+ doc[:application] = { name: @app_name } if @app_name
79
+ doc[:driver] = driver_doc
80
+ doc[:os] = os_doc
81
+ doc[:platform] = platform
82
+ end
83
+ end
84
+
85
+ def serialize
86
+ client_document = full_client_document
87
+ while client_document.to_bson.to_s.size > MAX_DOCUMENT_SIZE do
88
+ if client_document[:os][:name] || client_document[:os][:architecture]
89
+ client_document[:os].delete(:name)
90
+ client_document[:os].delete(:architecture)
91
+ elsif client_document[:platform]
92
+ client_document.delete(:platform)
93
+ else
94
+ client_document = nil
95
+ end
96
+ end
97
+ document = Server::Monitor::Connection::ISMASTER
98
+ document = document.merge(client: client_document) if client_document
99
+ Protocol::Query.new(Database::ADMIN, Database::COMMAND, document, :limit => -1).serialize
100
+ end
101
+
102
+ def driver_doc
103
+ {
104
+ name: :'mongo-ruby-driver',
105
+ version: Mongo::VERSION
106
+ }
107
+ end
108
+
109
+ def os_doc
110
+ {
111
+ type: type,
112
+ name: name,
113
+ architecture: architecture
114
+ }
115
+ end
116
+
117
+ def type
118
+ (RbConfig::CONFIG && RbConfig::CONFIG['host_os']) ?
119
+ RbConfig::CONFIG['host_os'].split('_').first[/[a-z]+/i].downcase.to_sym : :unknown
120
+ end
121
+
122
+ def name
123
+ RbConfig::CONFIG['host_os']
124
+ end
125
+
126
+ def architecture
127
+ RbConfig::CONFIG['target_cpu']
128
+ end
129
+
130
+ def platform
131
+ [RUBY_VERSION, RUBY_PLATFORM, RbConfig::CONFIG['build']].join(', ')
132
+ end
133
+ end
134
+ end
135
+ end
@@ -124,8 +124,7 @@ module Mongo
124
124
  #
125
125
  # @since 2.0.0
126
126
  def write_concern
127
- @write_concern ||= options[:write] ? WriteConcern.get(options[:write]) :
128
- database.write_concern
127
+ @write_concern ||= WriteConcern.get(options[:write] || database.write_concern)
129
128
  end
130
129
 
131
130
  # Provides a new collection with either a new read preference or new write concern
@@ -170,7 +169,15 @@ module Mongo
170
169
  #
171
170
  # @since 2.0.0
172
171
  def create
173
- database.command({ :create => name }.merge(options))
172
+ operation = { :create => name }.merge(options)
173
+ operation.delete(:write)
174
+ server = next_primary
175
+ raise Error::UnsupportedCollation.new if options[:collation] && !server.features.collation_enabled?
176
+ Operation::Commands::Create.new({
177
+ selector: operation,
178
+ db_name: database.name,
179
+ write_concern: write_concern
180
+ }).execute(server)
174
181
  end
175
182
 
176
183
  # Drop the collection. Will also drop all indexes associated with the
@@ -185,7 +192,12 @@ module Mongo
185
192
  #
186
193
  # @since 2.0.0
187
194
  def drop
188
- database.command(:drop => name)
195
+ Operation::Commands::Drop.new({
196
+ selector: { :drop => name },
197
+ db_name: database.name,
198
+ write_concern: write_concern
199
+ }).execute(next_primary)
200
+
189
201
  rescue Error::OperationFailure => ex
190
202
  raise ex unless ex.message =~ /ns not found/
191
203
  false
@@ -223,6 +235,7 @@ module Mongo
223
235
  # @option options [ Integer ] :skip The number of docs to skip before returning results.
224
236
  # @option options [ Hash ] :sort The key and direction pairs by which the result set
225
237
  # will be sorted.
238
+ # @option options [ Hash ] :collation The collation to use.
226
239
  #
227
240
  # @return [ CollectionView ] The collection view.
228
241
  #
@@ -248,6 +261,7 @@ module Mongo
248
261
  # provide results using a cursor.
249
262
  # @option options [ true, false ] :bypass_document_validation Whether or
250
263
  # not to skip document level validation.
264
+ # @option options [ Hash ] :collation The collation to use.
251
265
  #
252
266
  # @return [ Aggregation ] The aggregation object.
253
267
  #
@@ -269,6 +283,7 @@ module Mongo
269
283
  # @option options [ Integer ] :max_time_ms The maximum amount of time to allow the command to run.
270
284
  # @option options [ Integer ] :skip The number of documents to skip before counting.
271
285
  # @option options [ Hash ] :read The read preference options.
286
+ # @option options [ Hash ] :collation The collation to use.
272
287
  #
273
288
  # @return [ Integer ] The document count.
274
289
  #
@@ -288,6 +303,7 @@ module Mongo
288
303
  #
289
304
  # @option options [ Integer ] :max_time_ms The maximum amount of time to allow the command to run.
290
305
  # @option options [ Hash ] :read The read preference options.
306
+ # @option options [ Hash ] :collation The collation to use.
291
307
  #
292
308
  # @return [ Array<Object> ] The list of distinct values.
293
309
  #
@@ -392,12 +408,15 @@ module Mongo
392
408
  # collection.delete_one
393
409
  #
394
410
  # @param [ Hash ] filter The filter to use.
411
+ # @param [ Hash ] options The options.
412
+ #
413
+ # @option options [ Hash ] :collation The collation to use.
395
414
  #
396
415
  # @return [ Result ] The response from the database.
397
416
  #
398
417
  # @since 2.1.0
399
- def delete_one(filter = nil)
400
- find(filter).delete_one
418
+ def delete_one(filter = nil, options = {})
419
+ find(filter).delete_one(options)
401
420
  end
402
421
 
403
422
  # Remove documents from the collection.
@@ -406,12 +425,15 @@ module Mongo
406
425
  # collection.delete_many
407
426
  #
408
427
  # @param [ Hash ] filter The filter to use.
428
+ # @param [ Hash ] options The options.
429
+ #
430
+ # @option options [ Hash ] :collation The collation to use.
409
431
  #
410
432
  # @return [ Result ] The response from the database.
411
433
  #
412
434
  # @since 2.1.0
413
- def delete_many(filter = nil)
414
- find(filter).delete_many
435
+ def delete_many(filter = nil, options = {})
436
+ find(filter).delete_many(options)
415
437
  end
416
438
 
417
439
  # Execute a parallel scan on the collection view.
@@ -424,12 +446,16 @@ module Mongo
424
446
  # collection.parallel_scan(2)
425
447
  #
426
448
  # @param [ Integer ] cursor_count The max number of cursors to return.
449
+ # @param [ Hash ] options The parallel scan command options.
450
+ #
451
+ # @option options [ Integer ] :max_time_ms The maximum amount of time to allow the command
452
+ # to run in milliseconds.
427
453
  #
428
454
  # @return [ Array<Cursor> ] An array of cursors.
429
455
  #
430
456
  # @since 2.1
431
- def parallel_scan(cursor_count)
432
- find.send(:parallel_scan, cursor_count)
457
+ def parallel_scan(cursor_count, options = {})
458
+ find.send(:parallel_scan, cursor_count, options)
433
459
  end
434
460
 
435
461
  # Replaces a single document in the collection with the new document.
@@ -445,6 +471,7 @@ module Mongo
445
471
  # document doesn't exist.
446
472
  # @option options [ true, false ] :bypass_document_validation Whether or
447
473
  # not to skip document level validation.
474
+ # @option options [ Hash ] :collation The collation to use.
448
475
  #
449
476
  # @return [ Result ] The response from the database.
450
477
  #
@@ -466,6 +493,7 @@ module Mongo
466
493
  # document doesn't exist.
467
494
  # @option options [ true, false ] :bypass_document_validation Whether or
468
495
  # not to skip document level validation.
496
+ # @option options [ Hash ] :collation The collation to use.
469
497
  #
470
498
  # @return [ Result ] The response from the database.
471
499
  #
@@ -487,6 +515,7 @@ module Mongo
487
515
  # document doesn't exist.
488
516
  # @option options [ true, false ] :bypass_document_validation Whether or
489
517
  # not to skip document level validation.
518
+ # @option options [ Hash ] :collation The collation to use.
490
519
  #
491
520
  # @return [ Result ] The response from the database.
492
521
  #
@@ -511,6 +540,7 @@ module Mongo
511
540
  # will be sorted.
512
541
  # @option options [ Hash ] :write_concern The write concern options.
513
542
  # Defaults to the collection's write concern.
543
+ # @option options [ Hash ] :collation The collation to use.
514
544
  #
515
545
  # @return [ BSON::Document, nil ] The document, if found.
516
546
  #
@@ -543,6 +573,7 @@ module Mongo
543
573
  # not to skip document level validation.
544
574
  # @option options [ Hash ] :write_concern The write concern options.
545
575
  # Defaults to the collection's write concern.
576
+ # @option options [ Hash ] :collation The collation to use.
546
577
  #
547
578
  # @return [ BSON::Document ] The document.
548
579
  #
@@ -575,6 +606,7 @@ module Mongo
575
606
  # not to skip document level validation.
576
607
  # @option options [ Hash ] :write_concern The write concern options.
577
608
  # Defaults to the collection's write concern.
609
+ # @option options [ Hash ] :collation The collation to use.
578
610
  #
579
611
  # @return [ BSON::Document ] The document.
580
612
  #