mongo 2.0.5 → 2.0.6
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongo/auth/cr/conversation.rb +0 -1
- data/lib/mongo/client.rb +19 -5
- data/lib/mongo/cluster.rb +84 -16
- data/lib/mongo/cluster/topology.rb +3 -4
- data/lib/mongo/cluster/topology/replica_set.rb +75 -0
- data/lib/mongo/cluster/topology/sharded.rb +60 -0
- data/lib/mongo/cluster/topology/single.rb +51 -0
- data/lib/mongo/cluster/topology/unknown.rb +62 -0
- data/lib/mongo/error/invalid_bulk_operation.rb +2 -1
- data/lib/mongo/event.rb +9 -9
- data/lib/mongo/event/{server_added.rb → description_changed.rb} +6 -5
- data/lib/mongo/event/{server_removed.rb → standalone_discovered.rb} +15 -15
- data/lib/mongo/operation/aggregate.rb +6 -5
- data/lib/mongo/operation/command.rb +5 -6
- data/lib/mongo/operation/kill_cursors.rb +3 -2
- data/lib/mongo/operation/map_reduce.rb +6 -5
- data/lib/mongo/operation/read/collections_info.rb +5 -4
- data/lib/mongo/operation/read/get_more.rb +8 -7
- data/lib/mongo/operation/read/indexes.rb +4 -3
- data/lib/mongo/operation/read/list_collections.rb +5 -4
- data/lib/mongo/operation/read/list_indexes.rb +7 -6
- data/lib/mongo/operation/read/query.rb +8 -7
- data/lib/mongo/operation/read_preferrable.rb +6 -2
- data/lib/mongo/operation/write/bulk/bulk_delete.rb +13 -12
- data/lib/mongo/operation/write/bulk/bulk_insert.rb +10 -9
- data/lib/mongo/operation/write/bulk/bulk_insert/result.rb +2 -2
- data/lib/mongo/operation/write/bulk/bulk_update.rb +12 -11
- data/lib/mongo/operation/write/create_index.rb +8 -7
- data/lib/mongo/operation/write/create_user.rb +4 -3
- data/lib/mongo/operation/write/delete.rb +13 -12
- data/lib/mongo/operation/write/drop_index.rb +6 -5
- data/lib/mongo/operation/write/insert.rb +8 -7
- data/lib/mongo/operation/write/insert/result.rb +1 -1
- data/lib/mongo/operation/write/remove_user.rb +4 -3
- data/lib/mongo/operation/write/update.rb +10 -9
- data/lib/mongo/operation/write/update_user.rb +4 -3
- data/lib/mongo/server.rb +8 -15
- data/lib/mongo/server/context.rb +2 -2
- data/lib/mongo/server/description.rb +65 -3
- data/lib/mongo/server/description/features.rb +2 -1
- data/lib/mongo/server/description/inspector.rb +5 -5
- data/lib/mongo/server/description/inspector/{server_added.rb → description_changed.rb} +3 -5
- data/lib/mongo/server/description/inspector/{server_removed.rb → standalone_discovered.rb} +12 -15
- data/lib/mongo/version.rb +1 -1
- data/spec/mongo/auth/cr_spec.rb +1 -1
- data/spec/mongo/auth/ldap_spec.rb +1 -1
- data/spec/mongo/auth/scram_spec.rb +1 -1
- data/spec/mongo/auth/x509_spec.rb +1 -1
- data/spec/mongo/client_spec.rb +4 -0
- data/spec/mongo/cluster/topology/replica_set_spec.rb +254 -4
- data/spec/mongo/cluster/topology/sharded_spec.rb +70 -19
- data/spec/mongo/cluster/topology/single_spec.rb +25 -4
- data/spec/mongo/cluster/topology/unknown_spec.rb +167 -0
- data/spec/mongo/cluster/topology_spec.rb +6 -6
- data/spec/mongo/cluster_spec.rb +179 -1
- data/spec/mongo/operation/read_preferrable_spec.rb +81 -28
- data/spec/mongo/operation/write/bulk/bulk_delete_spec.rb +1 -0
- data/spec/mongo/server/connection_pool_spec.rb +10 -10
- data/spec/mongo/server/connection_spec.rb +1 -1
- data/spec/mongo/server/description/features_spec.rb +23 -3
- data/spec/mongo/server/description/inspector/description_changed_spec.rb +78 -0
- data/spec/mongo/server/description_spec.rb +238 -0
- data/spec/mongo/server/monitor_spec.rb +1 -1
- data/spec/mongo/server_discovery_and_monitoring_spec.rb +20 -4
- data/spec/mongo/server_selection_spec.rb +2 -2
- data/spec/mongo/server_spec.rb +12 -8
- data/spec/support/authorization.rb +8 -8
- data/spec/support/sdam/rs/discover_passives.yml +36 -0
- data/spec/support/sdam/rs/new_primary_wrong_set_name.yml +2 -2
- data/spec/support/sdam/rs/primary_becomes_standalone.yml +1 -1
- data/spec/support/sdam/rs/primary_changes_set_name.yml +2 -2
- data/spec/support/sdam/rs/primary_disconnect.yml +1 -1
- data/spec/support/sdam/rs/primary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name.yml +1 -1
- data/spec/support/sdam/rs/secondary_wrong_set_name_with_primary.yml +2 -2
- data/spec/support/sdam/sharded/single_mongos.yml +33 -0
- data/spec/support/shared/operation.rb +12 -4
- data/spec/support/shared/server_selector.rb +1 -1
- metadata +12 -10
- metadata.gz.sig +0 -0
- data/spec/mongo/server/description/inspector/server_added_spec.rb +0 -92
- data/spec/mongo/server/description/inspector/server_removed_spec.rb +0 -95
@@ -72,6 +72,7 @@ module Mongo
|
|
72
72
|
# @since 2.0.0
|
73
73
|
def initialize(options, seeds = [])
|
74
74
|
@options = options
|
75
|
+
@seeds = seeds
|
75
76
|
end
|
76
77
|
|
77
78
|
# An unknown topology is not a replica set.
|
@@ -139,6 +140,67 @@ module Mongo
|
|
139
140
|
# @since 2.0.0
|
140
141
|
def unknown?; true; end
|
141
142
|
|
143
|
+
# Whether a server description's hosts may be added to the cluster.
|
144
|
+
#
|
145
|
+
# @example Check if a description's hosts may be added to the cluster.
|
146
|
+
# topology.add_hosts?(description, servers)
|
147
|
+
#
|
148
|
+
# @param [ Mongo::Server::Description ] description The description.
|
149
|
+
# @param [ Array<Mongo::Server> ] servers The cluster servers.
|
150
|
+
#
|
151
|
+
# @return [ true, false ] Whether a description's hosts may be added.
|
152
|
+
#
|
153
|
+
# @since 2.0.6
|
154
|
+
def add_hosts?(description, servers)
|
155
|
+
!(description.unknown? || description.ghost?)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Whether a description can be used to remove hosts from the cluster.
|
159
|
+
#
|
160
|
+
# @example Check if a description can be used to remove hosts from the cluster.
|
161
|
+
# topology.remove_hosts?(description)
|
162
|
+
#
|
163
|
+
# @param [ Mongo::Server::Description ] description The description.
|
164
|
+
#
|
165
|
+
# @return [ true, false ] Whether hosts may be removed from the cluster.
|
166
|
+
#
|
167
|
+
# @since 2.0.6
|
168
|
+
def remove_hosts?(description)
|
169
|
+
description.standalone?
|
170
|
+
end
|
171
|
+
|
172
|
+
# Whether a specific server in the cluster can be removed, given a description.
|
173
|
+
#
|
174
|
+
# @example Check if a specific server can be removed from the cluster.
|
175
|
+
# topology.remove_server?(description, server)
|
176
|
+
#
|
177
|
+
# @param [ Mongo::Server::Description ] description The description.
|
178
|
+
# @param [ Mongo::Serve ] server The server in question.
|
179
|
+
#
|
180
|
+
# @return [ true, false ] Whether the server can be removed from the cluster.
|
181
|
+
#
|
182
|
+
# @since 2.0.6
|
183
|
+
def remove_server?(description, server)
|
184
|
+
description.standalone? && description.is_server?(server)
|
185
|
+
end
|
186
|
+
|
187
|
+
# Notify the topology that a standalone was discovered.
|
188
|
+
#
|
189
|
+
# @example Notify the topology that a standalone was discovered.
|
190
|
+
# topology.standalone_discovered
|
191
|
+
#
|
192
|
+
# @return [ Topology::Unknown, Topology::Single ] Either self or a
|
193
|
+
# new Single topology.
|
194
|
+
#
|
195
|
+
# @since 2.0.6
|
196
|
+
def standalone_discovered
|
197
|
+
if @seeds.size == 1
|
198
|
+
Single.new(options, @seeds)
|
199
|
+
else
|
200
|
+
self
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
142
204
|
private
|
143
205
|
|
144
206
|
def initialize_replica_set(description, servers)
|
@@ -25,7 +25,8 @@ module Mongo
|
|
25
25
|
# @example Instantiate the exception.
|
26
26
|
# Mongo::Error::InvalidBulkOperation.new(name)
|
27
27
|
#
|
28
|
-
# @param [ String ]
|
28
|
+
# @param [ String ] type The bulk operation type.
|
29
|
+
# @param [ Hash ] operation The bulk operation.
|
29
30
|
#
|
30
31
|
# @since 2.0.0
|
31
32
|
def initialize(type, operation)
|
data/lib/mongo/event.rb
CHANGED
@@ -16,25 +16,25 @@ require 'mongo/event/listeners'
|
|
16
16
|
require 'mongo/event/publisher'
|
17
17
|
require 'mongo/event/subscriber'
|
18
18
|
require 'mongo/event/primary_elected'
|
19
|
-
require 'mongo/event/
|
20
|
-
require 'mongo/event/
|
19
|
+
require 'mongo/event/description_changed'
|
20
|
+
require 'mongo/event/standalone_discovered'
|
21
21
|
|
22
22
|
module Mongo
|
23
23
|
module Event
|
24
24
|
|
25
|
-
# When a
|
25
|
+
# When a standalone is discovered.
|
26
26
|
#
|
27
|
-
# @since 2.0.
|
28
|
-
|
27
|
+
# @since 2.0.6
|
28
|
+
STANDALONE_DISCOVERED = 'standalone_discovered'.freeze
|
29
29
|
|
30
|
-
# When a server is
|
30
|
+
# When a server is elected primary.
|
31
31
|
#
|
32
32
|
# @since 2.0.0
|
33
|
-
|
33
|
+
PRIMARY_ELECTED = 'primary_elected'.freeze
|
34
34
|
|
35
35
|
# When a server is to be removed from a cluster.
|
36
36
|
#
|
37
|
-
# @since 2.0.
|
38
|
-
|
37
|
+
# @since 2.0.6
|
38
|
+
DESCRIPTION_CHANGED = 'description_changed'.freeze
|
39
39
|
end
|
40
40
|
end
|
@@ -16,10 +16,10 @@
|
|
16
16
|
module Mongo
|
17
17
|
module Event
|
18
18
|
|
19
|
-
# This handles
|
19
|
+
# This handles a change in description.
|
20
20
|
#
|
21
|
-
# @since 2.0.
|
22
|
-
class
|
21
|
+
# @since 2.0.6
|
22
|
+
class DescriptionChanged
|
23
23
|
|
24
24
|
# @return [ Mongo::Cluster ] cluster The event publisher.
|
25
25
|
attr_reader :cluster
|
@@ -45,8 +45,9 @@ module Mongo
|
|
45
45
|
# @param [ Address ] address The added host.
|
46
46
|
#
|
47
47
|
# @since 2.0.0
|
48
|
-
def handle(
|
49
|
-
cluster.
|
48
|
+
def handle(updated)
|
49
|
+
cluster.add_hosts(updated)
|
50
|
+
cluster.remove_hosts(updated)
|
50
51
|
end
|
51
52
|
end
|
52
53
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
# Copyright (C)
|
1
|
+
# Copyright (C) 2015 MongoDB, Inc.
|
2
2
|
#
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
4
4
|
# you may not use this file except in compliance with the License.
|
@@ -15,38 +15,38 @@
|
|
15
15
|
module Mongo
|
16
16
|
module Event
|
17
17
|
|
18
|
-
# This handles
|
18
|
+
# This handles when a standalone is discovered.
|
19
19
|
#
|
20
|
-
# @since 2.0.
|
21
|
-
class
|
22
|
-
include Loggable
|
20
|
+
# @since 2.0.6
|
21
|
+
class StandaloneDiscovered
|
23
22
|
|
24
23
|
# @return [ Mongo::Cluster ] cluster The event publisher.
|
25
24
|
attr_reader :cluster
|
26
25
|
|
27
|
-
# Initialize the new
|
26
|
+
# Initialize the new standalone discovered event handler.
|
28
27
|
#
|
29
28
|
# @example Create the new handler.
|
30
|
-
#
|
29
|
+
# StandaloneDiscovered.new(cluster)
|
31
30
|
#
|
32
31
|
# @param [ Mongo::Cluster ] cluster The cluster to publish from.
|
33
32
|
#
|
34
|
-
# @since 2.0.
|
33
|
+
# @since 2.0.6
|
35
34
|
def initialize(cluster)
|
36
35
|
@cluster = cluster
|
37
36
|
end
|
38
37
|
|
39
|
-
# This event
|
40
|
-
#
|
38
|
+
# This event tells the cluster to notify its topology that a standalone
|
39
|
+
# was discovered.
|
41
40
|
#
|
42
41
|
# @example Handle the event.
|
43
|
-
#
|
42
|
+
# standalone_discovered.handle(description)
|
44
43
|
#
|
45
|
-
# @param [
|
44
|
+
# @param [ Server::Description ] description The description of the
|
45
|
+
# server.
|
46
46
|
#
|
47
|
-
# @since 2.0.
|
48
|
-
def handle(
|
49
|
-
cluster.
|
47
|
+
# @since 2.0.6
|
48
|
+
def handle(description)
|
49
|
+
cluster.standalone_discovered
|
50
50
|
end
|
51
51
|
end
|
52
52
|
end
|
@@ -31,12 +31,13 @@ module Mongo
|
|
31
31
|
# :db_name => 'test_db'
|
32
32
|
# })
|
33
33
|
#
|
34
|
-
#
|
34
|
+
# Initialization:
|
35
|
+
# param [ Hash ] spec The specifications for the operation.
|
35
36
|
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
37
|
+
# option spec :selector [ Hash ] The aggregate selector.
|
38
|
+
# option spec :db_name [ String ] The name of the database on which
|
39
|
+
# the operation should be executed.
|
40
|
+
# option spec :options [ Hash ] Options for the aggregate command.
|
40
41
|
#
|
41
42
|
# @since 2.0.0
|
42
43
|
class Aggregate
|
@@ -20,14 +20,13 @@ module Mongo
|
|
20
20
|
# @example Create the command operation.
|
21
21
|
# Mongo::Operation::Command.new({ :selector => { :isMaster => 1 } })
|
22
22
|
#
|
23
|
-
#
|
23
|
+
# Initialization:
|
24
|
+
# param [ Hash ] spec The specifications for the command.
|
24
25
|
#
|
25
|
-
#
|
26
|
-
#
|
27
|
-
# @option spec :selector [ Hash ] The command selector.
|
28
|
-
# @option spec :db_name [ String ] The name of the database on which
|
26
|
+
# option spec :selector [ Hash ] The command selector.
|
27
|
+
# option spec :db_name [ String ] The name of the database on which
|
29
28
|
# the command should be executed.
|
30
|
-
#
|
29
|
+
# option spec :options [ Hash ] Options for the command.
|
31
30
|
#
|
32
31
|
# @since 2.0.0
|
33
32
|
class Command
|
@@ -20,9 +20,10 @@ module Mongo
|
|
20
20
|
# @example Create the kill cursors operation.
|
21
21
|
# Mongo::Operation::KillCursor.new({ :cursor_ids => [1, 2] })
|
22
22
|
#
|
23
|
-
#
|
23
|
+
# Initialization:
|
24
|
+
# param [ Hash ] spec The specifications for the operation.
|
24
25
|
#
|
25
|
-
#
|
26
|
+
# option spec :cursor_ids [ Array ] The ids of cursors to kill.
|
26
27
|
#
|
27
28
|
# @since 2.0.0
|
28
29
|
class KillCursors
|
@@ -33,12 +33,13 @@ module Mongo
|
|
33
33
|
# :db_name => 'test_db'
|
34
34
|
# })
|
35
35
|
#
|
36
|
-
#
|
36
|
+
# Initialization:
|
37
|
+
# param [ Hash ] spec The specifications for the operation.
|
37
38
|
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
39
|
+
# option spec :selector [ Hash ] The map reduce selector.
|
40
|
+
# option spec :db_name [ String ] The name of the database on which
|
41
|
+
# the operation should be executed.
|
42
|
+
# option spec :options [ Hash ] Options for the map reduce command.
|
42
43
|
#
|
43
44
|
# @since 2.0.0
|
44
45
|
class MapReduce
|
@@ -21,11 +21,12 @@ module Mongo
|
|
21
21
|
# @example Create the collection names operation.
|
22
22
|
# Read::CollectionNames.new(:db_name => 'test-db')
|
23
23
|
#
|
24
|
-
#
|
24
|
+
# Initialization:
|
25
|
+
# param [ Hash ] spec The specifications for the collection names operation.
|
25
26
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
27
|
+
# option spec :db_name [ String ] The name of the database whose collection
|
28
|
+
# names is requested.
|
29
|
+
# option spec :options [ Hash ] Options for the operation.
|
29
30
|
#
|
30
31
|
# @since 2.0.0
|
31
32
|
class CollectionsInfo
|
@@ -26,14 +26,15 @@ module Mongo
|
|
26
26
|
# :coll_name => 'test_coll'
|
27
27
|
# })
|
28
28
|
#
|
29
|
-
#
|
29
|
+
# Initialization:
|
30
|
+
# param [ Hash ] spec The specifications for the operation.
|
30
31
|
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
32
|
+
# option spec :to_return [ Integer ] The number of results to return.
|
33
|
+
# option spec :cursor_id [ Integer ] The id of the cursor.
|
34
|
+
# option spec :db_name [ String ] The name of the database on which
|
35
|
+
# the operation should be executed.
|
36
|
+
# option spec :coll_name [ String ] The name of the collection on which
|
37
|
+
# the operation should be executed.
|
37
38
|
#
|
38
39
|
# @since 2.0.0
|
39
40
|
class GetMore
|
@@ -23,10 +23,11 @@ module Mongo
|
|
23
23
|
# @example Instantiate the operation.
|
24
24
|
# Read::Indexes.new(:db_name => 'test', :coll_name => 'test_coll')
|
25
25
|
#
|
26
|
-
#
|
26
|
+
# Initialization:
|
27
|
+
# param [ Hash ] spec The specifications for the insert.
|
27
28
|
#
|
28
|
-
#
|
29
|
-
#
|
29
|
+
# option spec :db_name [ String ] The name of the database.
|
30
|
+
# option spec :coll_name [ String ] The name of the collection.
|
30
31
|
#
|
31
32
|
# @since 2.0.0
|
32
33
|
class Indexes
|
@@ -25,11 +25,12 @@ module Mongo
|
|
25
25
|
#
|
26
26
|
# @note A command is actually a query on the virtual '$cmd' collection.
|
27
27
|
#
|
28
|
-
#
|
28
|
+
# Initialization:
|
29
|
+
# param [ Hash ] spec The specifications for the command.
|
29
30
|
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
31
|
+
# option spec :db_name [ String ] The name of the database whose list of
|
32
|
+
# collection names is requested.
|
33
|
+
# option spec :options [ Hash ] Options for the command.
|
33
34
|
#
|
34
35
|
# @since 2.0.0
|
35
36
|
class ListCollections
|
@@ -25,13 +25,14 @@ module Mongo
|
|
25
25
|
#
|
26
26
|
# @note A command is actually a query on the virtual '$cmd' collection.
|
27
27
|
#
|
28
|
-
#
|
28
|
+
# Initialization:
|
29
|
+
# param [ Hash ] spec The specifications for the command.
|
29
30
|
#
|
30
|
-
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
31
|
+
# option spec :coll_name [ Hash ] The name of the collection whose index
|
32
|
+
# info is requested.
|
33
|
+
# option spec :db_name [ String ] The name of the database on which
|
34
|
+
# the command should be executed.
|
35
|
+
# option spec :options [ Hash ] Options for the command.
|
35
36
|
#
|
36
37
|
# @since 2.0.0
|
37
38
|
class ListIndexes
|
@@ -26,14 +26,15 @@ module Mongo
|
|
26
26
|
# :options => { :limit => 2 }
|
27
27
|
# })
|
28
28
|
#
|
29
|
-
#
|
29
|
+
# Initialization:
|
30
|
+
# param [ Hash ] spec The specifications for the query.
|
30
31
|
#
|
31
|
-
#
|
32
|
-
#
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
32
|
+
# option spec :selector [ Hash ] The query selector.
|
33
|
+
# option spec :db_name [ String ] The name of the database on which
|
34
|
+
# the query should be run.
|
35
|
+
# option spec :coll_name [ String ] The name of the collection on which
|
36
|
+
# the query should be run.
|
37
|
+
# option spec :options [ Hash ] Options for the query.
|
37
38
|
#
|
38
39
|
# @since 2.0.0
|
39
40
|
class Query
|
@@ -22,7 +22,7 @@ module Mongo
|
|
22
22
|
|
23
23
|
# The constant for slave ok flags.
|
24
24
|
#
|
25
|
-
# @since 2.0.
|
25
|
+
# @since 2.0.6
|
26
26
|
SLAVE_OK = :slave_ok
|
27
27
|
|
28
28
|
private
|
@@ -36,8 +36,12 @@ module Mongo
|
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
|
+
def slave_ok?(context)
|
40
|
+
(context.cluster.single? && !context.mongos?) || read.slave_ok?
|
41
|
+
end
|
42
|
+
|
39
43
|
def update_options(context)
|
40
|
-
if
|
44
|
+
if slave_ok?(context)
|
41
45
|
options.dup.tap do |opts|
|
42
46
|
(opts[:flags] ||= []) << SLAVE_OK
|
43
47
|
end
|
@@ -31,19 +31,20 @@ module Mongo
|
|
31
31
|
# :write_concern => write_concern
|
32
32
|
# })
|
33
33
|
#
|
34
|
-
#
|
34
|
+
# Initialization:
|
35
|
+
# param [ Hash ] spec The specifications for the delete.
|
35
36
|
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
39
|
-
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
43
|
-
#
|
44
|
-
#
|
45
|
-
#
|
46
|
-
#
|
37
|
+
# option spec :deletes [ Array ] The delete documents.
|
38
|
+
# option spec :db_name [ String ] The name of the database on which
|
39
|
+
# the delete should be executed.
|
40
|
+
# option spec :coll_name [ String ] The name of the collection on which
|
41
|
+
# the delete should be executed.
|
42
|
+
# option spec :write_concern [ Mongo::WriteConcern ] The write concern
|
43
|
+
# for this operation.
|
44
|
+
# option spec :ordered [ true, false ] Whether the operations should be
|
45
|
+
# executed in order.
|
46
|
+
# option spec :options [Hash] Options for the command, if it ends up being a
|
47
|
+
# write command.
|
47
48
|
#
|
48
49
|
# @since 2.0.0
|
49
50
|
class BulkDelete
|