sensu-plugins-mongodb-mrtrotl 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (181) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +1 -0
  3. data/LICENSE +22 -0
  4. data/README.md +27 -0
  5. data/bin/check-mongodb-metric.rb +144 -0
  6. data/bin/check-mongodb-query-count.rb +267 -0
  7. data/bin/check-mongodb.py +1644 -0
  8. data/bin/check-mongodb.rb +5 -0
  9. data/bin/metrics-mongodb-replication.rb +254 -0
  10. data/bin/metrics-mongodb.rb +133 -0
  11. data/lib/bson/__init__.py +1347 -0
  12. data/lib/bson/__pycache__/__init__.cpython-310.pyc +0 -0
  13. data/lib/bson/__pycache__/_helpers.cpython-310.pyc +0 -0
  14. data/lib/bson/__pycache__/binary.cpython-310.pyc +0 -0
  15. data/lib/bson/__pycache__/code.cpython-310.pyc +0 -0
  16. data/lib/bson/__pycache__/codec_options.cpython-310.pyc +0 -0
  17. data/lib/bson/__pycache__/dbref.cpython-310.pyc +0 -0
  18. data/lib/bson/__pycache__/decimal128.cpython-310.pyc +0 -0
  19. data/lib/bson/__pycache__/errors.cpython-310.pyc +0 -0
  20. data/lib/bson/__pycache__/int64.cpython-310.pyc +0 -0
  21. data/lib/bson/__pycache__/json_util.cpython-310.pyc +0 -0
  22. data/lib/bson/__pycache__/max_key.cpython-310.pyc +0 -0
  23. data/lib/bson/__pycache__/min_key.cpython-310.pyc +0 -0
  24. data/lib/bson/__pycache__/objectid.cpython-310.pyc +0 -0
  25. data/lib/bson/__pycache__/raw_bson.cpython-310.pyc +0 -0
  26. data/lib/bson/__pycache__/regex.cpython-310.pyc +0 -0
  27. data/lib/bson/__pycache__/son.cpython-310.pyc +0 -0
  28. data/lib/bson/__pycache__/timestamp.cpython-310.pyc +0 -0
  29. data/lib/bson/__pycache__/tz_util.cpython-310.pyc +0 -0
  30. data/lib/bson/_cbson.cpython-310-x86_64-linux-gnu.so +0 -0
  31. data/lib/bson/_helpers.py +41 -0
  32. data/lib/bson/binary.py +364 -0
  33. data/lib/bson/code.py +101 -0
  34. data/lib/bson/codec_options.py +414 -0
  35. data/lib/bson/codec_options.pyi +100 -0
  36. data/lib/bson/dbref.py +133 -0
  37. data/lib/bson/decimal128.py +314 -0
  38. data/lib/bson/errors.py +35 -0
  39. data/lib/bson/int64.py +39 -0
  40. data/lib/bson/json_util.py +874 -0
  41. data/lib/bson/max_key.py +55 -0
  42. data/lib/bson/min_key.py +55 -0
  43. data/lib/bson/objectid.py +286 -0
  44. data/lib/bson/py.typed +2 -0
  45. data/lib/bson/raw_bson.py +175 -0
  46. data/lib/bson/regex.py +135 -0
  47. data/lib/bson/son.py +208 -0
  48. data/lib/bson/timestamp.py +124 -0
  49. data/lib/bson/tz_util.py +52 -0
  50. data/lib/gridfs/__init__.py +1015 -0
  51. data/lib/gridfs/__pycache__/__init__.cpython-310.pyc +0 -0
  52. data/lib/gridfs/__pycache__/errors.cpython-310.pyc +0 -0
  53. data/lib/gridfs/__pycache__/grid_file.cpython-310.pyc +0 -0
  54. data/lib/gridfs/errors.py +33 -0
  55. data/lib/gridfs/grid_file.py +907 -0
  56. data/lib/gridfs/py.typed +2 -0
  57. data/lib/pymongo/__init__.py +185 -0
  58. data/lib/pymongo/__pycache__/__init__.cpython-310.pyc +0 -0
  59. data/lib/pymongo/__pycache__/_csot.cpython-310.pyc +0 -0
  60. data/lib/pymongo/__pycache__/aggregation.cpython-310.pyc +0 -0
  61. data/lib/pymongo/__pycache__/auth.cpython-310.pyc +0 -0
  62. data/lib/pymongo/__pycache__/auth_aws.cpython-310.pyc +0 -0
  63. data/lib/pymongo/__pycache__/bulk.cpython-310.pyc +0 -0
  64. data/lib/pymongo/__pycache__/change_stream.cpython-310.pyc +0 -0
  65. data/lib/pymongo/__pycache__/client_options.cpython-310.pyc +0 -0
  66. data/lib/pymongo/__pycache__/client_session.cpython-310.pyc +0 -0
  67. data/lib/pymongo/__pycache__/collation.cpython-310.pyc +0 -0
  68. data/lib/pymongo/__pycache__/collection.cpython-310.pyc +0 -0
  69. data/lib/pymongo/__pycache__/command_cursor.cpython-310.pyc +0 -0
  70. data/lib/pymongo/__pycache__/common.cpython-310.pyc +0 -0
  71. data/lib/pymongo/__pycache__/compression_support.cpython-310.pyc +0 -0
  72. data/lib/pymongo/__pycache__/cursor.cpython-310.pyc +0 -0
  73. data/lib/pymongo/__pycache__/daemon.cpython-310.pyc +0 -0
  74. data/lib/pymongo/__pycache__/database.cpython-310.pyc +0 -0
  75. data/lib/pymongo/__pycache__/driver_info.cpython-310.pyc +0 -0
  76. data/lib/pymongo/__pycache__/encryption.cpython-310.pyc +0 -0
  77. data/lib/pymongo/__pycache__/encryption_options.cpython-310.pyc +0 -0
  78. data/lib/pymongo/__pycache__/errors.cpython-310.pyc +0 -0
  79. data/lib/pymongo/__pycache__/event_loggers.cpython-310.pyc +0 -0
  80. data/lib/pymongo/__pycache__/hello.cpython-310.pyc +0 -0
  81. data/lib/pymongo/__pycache__/helpers.cpython-310.pyc +0 -0
  82. data/lib/pymongo/__pycache__/max_staleness_selectors.cpython-310.pyc +0 -0
  83. data/lib/pymongo/__pycache__/message.cpython-310.pyc +0 -0
  84. data/lib/pymongo/__pycache__/mongo_client.cpython-310.pyc +0 -0
  85. data/lib/pymongo/__pycache__/monitor.cpython-310.pyc +0 -0
  86. data/lib/pymongo/__pycache__/monitoring.cpython-310.pyc +0 -0
  87. data/lib/pymongo/__pycache__/network.cpython-310.pyc +0 -0
  88. data/lib/pymongo/__pycache__/ocsp_cache.cpython-310.pyc +0 -0
  89. data/lib/pymongo/__pycache__/ocsp_support.cpython-310.pyc +0 -0
  90. data/lib/pymongo/__pycache__/operations.cpython-310.pyc +0 -0
  91. data/lib/pymongo/__pycache__/periodic_executor.cpython-310.pyc +0 -0
  92. data/lib/pymongo/__pycache__/pool.cpython-310.pyc +0 -0
  93. data/lib/pymongo/__pycache__/pyopenssl_context.cpython-310.pyc +0 -0
  94. data/lib/pymongo/__pycache__/read_concern.cpython-310.pyc +0 -0
  95. data/lib/pymongo/__pycache__/read_preferences.cpython-310.pyc +0 -0
  96. data/lib/pymongo/__pycache__/response.cpython-310.pyc +0 -0
  97. data/lib/pymongo/__pycache__/results.cpython-310.pyc +0 -0
  98. data/lib/pymongo/__pycache__/saslprep.cpython-310.pyc +0 -0
  99. data/lib/pymongo/__pycache__/server.cpython-310.pyc +0 -0
  100. data/lib/pymongo/__pycache__/server_api.cpython-310.pyc +0 -0
  101. data/lib/pymongo/__pycache__/server_description.cpython-310.pyc +0 -0
  102. data/lib/pymongo/__pycache__/server_selectors.cpython-310.pyc +0 -0
  103. data/lib/pymongo/__pycache__/server_type.cpython-310.pyc +0 -0
  104. data/lib/pymongo/__pycache__/settings.cpython-310.pyc +0 -0
  105. data/lib/pymongo/__pycache__/socket_checker.cpython-310.pyc +0 -0
  106. data/lib/pymongo/__pycache__/srv_resolver.cpython-310.pyc +0 -0
  107. data/lib/pymongo/__pycache__/ssl_context.cpython-310.pyc +0 -0
  108. data/lib/pymongo/__pycache__/ssl_support.cpython-310.pyc +0 -0
  109. data/lib/pymongo/__pycache__/topology.cpython-310.pyc +0 -0
  110. data/lib/pymongo/__pycache__/topology_description.cpython-310.pyc +0 -0
  111. data/lib/pymongo/__pycache__/typings.cpython-310.pyc +0 -0
  112. data/lib/pymongo/__pycache__/uri_parser.cpython-310.pyc +0 -0
  113. data/lib/pymongo/__pycache__/write_concern.cpython-310.pyc +0 -0
  114. data/lib/pymongo/_cmessage.cpython-310-x86_64-linux-gnu.so +0 -0
  115. data/lib/pymongo/_csot.py +118 -0
  116. data/lib/pymongo/aggregation.py +229 -0
  117. data/lib/pymongo/auth.py +549 -0
  118. data/lib/pymongo/auth_aws.py +94 -0
  119. data/lib/pymongo/bulk.py +513 -0
  120. data/lib/pymongo/change_stream.py +457 -0
  121. data/lib/pymongo/client_options.py +302 -0
  122. data/lib/pymongo/client_session.py +1112 -0
  123. data/lib/pymongo/collation.py +224 -0
  124. data/lib/pymongo/collection.py +3204 -0
  125. data/lib/pymongo/command_cursor.py +353 -0
  126. data/lib/pymongo/common.py +984 -0
  127. data/lib/pymongo/compression_support.py +149 -0
  128. data/lib/pymongo/cursor.py +1345 -0
  129. data/lib/pymongo/daemon.py +141 -0
  130. data/lib/pymongo/database.py +1202 -0
  131. data/lib/pymongo/driver_info.py +42 -0
  132. data/lib/pymongo/encryption.py +884 -0
  133. data/lib/pymongo/encryption_options.py +221 -0
  134. data/lib/pymongo/errors.py +365 -0
  135. data/lib/pymongo/event_loggers.py +221 -0
  136. data/lib/pymongo/hello.py +219 -0
  137. data/lib/pymongo/helpers.py +259 -0
  138. data/lib/pymongo/max_staleness_selectors.py +114 -0
  139. data/lib/pymongo/message.py +1440 -0
  140. data/lib/pymongo/mongo_client.py +2144 -0
  141. data/lib/pymongo/monitor.py +440 -0
  142. data/lib/pymongo/monitoring.py +1801 -0
  143. data/lib/pymongo/network.py +311 -0
  144. data/lib/pymongo/ocsp_cache.py +87 -0
  145. data/lib/pymongo/ocsp_support.py +372 -0
  146. data/lib/pymongo/operations.py +507 -0
  147. data/lib/pymongo/periodic_executor.py +183 -0
  148. data/lib/pymongo/pool.py +1660 -0
  149. data/lib/pymongo/py.typed +2 -0
  150. data/lib/pymongo/pyopenssl_context.py +383 -0
  151. data/lib/pymongo/read_concern.py +75 -0
  152. data/lib/pymongo/read_preferences.py +609 -0
  153. data/lib/pymongo/response.py +109 -0
  154. data/lib/pymongo/results.py +217 -0
  155. data/lib/pymongo/saslprep.py +113 -0
  156. data/lib/pymongo/server.py +247 -0
  157. data/lib/pymongo/server_api.py +170 -0
  158. data/lib/pymongo/server_description.py +285 -0
  159. data/lib/pymongo/server_selectors.py +153 -0
  160. data/lib/pymongo/server_type.py +32 -0
  161. data/lib/pymongo/settings.py +159 -0
  162. data/lib/pymongo/socket_checker.py +104 -0
  163. data/lib/pymongo/srv_resolver.py +126 -0
  164. data/lib/pymongo/ssl_context.py +39 -0
  165. data/lib/pymongo/ssl_support.py +99 -0
  166. data/lib/pymongo/topology.py +890 -0
  167. data/lib/pymongo/topology_description.py +639 -0
  168. data/lib/pymongo/typings.py +39 -0
  169. data/lib/pymongo/uri_parser.py +624 -0
  170. data/lib/pymongo/write_concern.py +129 -0
  171. data/lib/pymongo-4.2.0.dist-info/INSTALLER +1 -0
  172. data/lib/pymongo-4.2.0.dist-info/LICENSE +201 -0
  173. data/lib/pymongo-4.2.0.dist-info/METADATA +250 -0
  174. data/lib/pymongo-4.2.0.dist-info/RECORD +167 -0
  175. data/lib/pymongo-4.2.0.dist-info/REQUESTED +0 -0
  176. data/lib/pymongo-4.2.0.dist-info/WHEEL +6 -0
  177. data/lib/pymongo-4.2.0.dist-info/top_level.txt +3 -0
  178. data/lib/sensu-plugins-mongodb/metrics.rb +391 -0
  179. data/lib/sensu-plugins-mongodb/version.rb +9 -0
  180. data/lib/sensu-plugins-mongodb.rb +1 -0
  181. metadata +407 -0
@@ -0,0 +1,507 @@
1
+ # Copyright 2015-present 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
+ """Operation class definitions."""
16
+ from typing import Any, Dict, List, Mapping, Optional, Sequence, Tuple, Union
17
+
18
+ from pymongo import helpers
19
+ from pymongo.collation import validate_collation_or_none
20
+ from pymongo.common import validate_boolean, validate_is_mapping, validate_list
21
+ from pymongo.helpers import _gen_index_name, _index_document, _index_list
22
+ from pymongo.typings import _CollationIn, _DocumentIn, _Pipeline
23
+
24
+
25
+ class InsertOne(object):
26
+ """Represents an insert_one operation."""
27
+
28
+ __slots__ = ("_doc",)
29
+
30
+ def __init__(self, document: _DocumentIn) -> None:
31
+ """Create an InsertOne instance.
32
+
33
+ For use with :meth:`~pymongo.collection.Collection.bulk_write`.
34
+
35
+ :Parameters:
36
+ - `document`: The document to insert. If the document is missing an
37
+ _id field one will be added.
38
+ """
39
+ self._doc = document
40
+
41
+ def _add_to_bulk(self, bulkobj):
42
+ """Add this operation to the _Bulk instance `bulkobj`."""
43
+ bulkobj.add_insert(self._doc)
44
+
45
+ def __repr__(self):
46
+ return "InsertOne(%r)" % (self._doc,)
47
+
48
+ def __eq__(self, other: Any) -> bool:
49
+ if type(other) == type(self):
50
+ return other._doc == self._doc
51
+ return NotImplemented
52
+
53
+ def __ne__(self, other: Any) -> bool:
54
+ return not self == other
55
+
56
+
57
+ _IndexList = Sequence[Tuple[str, Union[int, str, Mapping[str, Any]]]]
58
+ _IndexKeyHint = Union[str, _IndexList]
59
+
60
+
61
+ class DeleteOne(object):
62
+ """Represents a delete_one operation."""
63
+
64
+ __slots__ = ("_filter", "_collation", "_hint")
65
+
66
+ def __init__(
67
+ self,
68
+ filter: Mapping[str, Any],
69
+ collation: Optional[_CollationIn] = None,
70
+ hint: Optional[_IndexKeyHint] = None,
71
+ ) -> None:
72
+ """Create a DeleteOne instance.
73
+
74
+ For use with :meth:`~pymongo.collection.Collection.bulk_write`.
75
+
76
+ :Parameters:
77
+ - `filter`: A query that matches the document to delete.
78
+ - `collation` (optional): An instance of
79
+ :class:`~pymongo.collation.Collation`.
80
+ - `hint` (optional): An index to use to support the query
81
+ predicate specified either by its string name, or in the same
82
+ format as passed to
83
+ :meth:`~pymongo.collection.Collection.create_index` (e.g.
84
+ ``[('field', ASCENDING)]``). This option is only supported on
85
+ MongoDB 4.4 and above.
86
+
87
+ .. versionchanged:: 3.11
88
+ Added the ``hint`` option.
89
+ .. versionchanged:: 3.5
90
+ Added the `collation` option.
91
+ """
92
+ if filter is not None:
93
+ validate_is_mapping("filter", filter)
94
+ if hint is not None:
95
+ if not isinstance(hint, str):
96
+ hint = helpers._index_document(hint)
97
+ self._filter = filter
98
+ self._collation = collation
99
+ self._hint = hint
100
+
101
+ def _add_to_bulk(self, bulkobj):
102
+ """Add this operation to the _Bulk instance `bulkobj`."""
103
+ bulkobj.add_delete(self._filter, 1, collation=self._collation, hint=self._hint)
104
+
105
+ def __repr__(self):
106
+ return "DeleteOne(%r, %r)" % (self._filter, self._collation)
107
+
108
+ def __eq__(self, other: Any) -> bool:
109
+ if type(other) == type(self):
110
+ return (other._filter, other._collation) == (self._filter, self._collation)
111
+ return NotImplemented
112
+
113
+ def __ne__(self, other: Any) -> bool:
114
+ return not self == other
115
+
116
+
117
+ class DeleteMany(object):
118
+ """Represents a delete_many operation."""
119
+
120
+ __slots__ = ("_filter", "_collation", "_hint")
121
+
122
+ def __init__(
123
+ self,
124
+ filter: Mapping[str, Any],
125
+ collation: Optional[_CollationIn] = None,
126
+ hint: Optional[_IndexKeyHint] = None,
127
+ ) -> None:
128
+ """Create a DeleteMany instance.
129
+
130
+ For use with :meth:`~pymongo.collection.Collection.bulk_write`.
131
+
132
+ :Parameters:
133
+ - `filter`: A query that matches the documents to delete.
134
+ - `collation` (optional): An instance of
135
+ :class:`~pymongo.collation.Collation`.
136
+ - `hint` (optional): An index to use to support the query
137
+ predicate specified either by its string name, or in the same
138
+ format as passed to
139
+ :meth:`~pymongo.collection.Collection.create_index` (e.g.
140
+ ``[('field', ASCENDING)]``). This option is only supported on
141
+ MongoDB 4.4 and above.
142
+
143
+ .. versionchanged:: 3.11
144
+ Added the ``hint`` option.
145
+ .. versionchanged:: 3.5
146
+ Added the `collation` option.
147
+ """
148
+ if filter is not None:
149
+ validate_is_mapping("filter", filter)
150
+ if hint is not None:
151
+ if not isinstance(hint, str):
152
+ hint = helpers._index_document(hint)
153
+ self._filter = filter
154
+ self._collation = collation
155
+ self._hint = hint
156
+
157
+ def _add_to_bulk(self, bulkobj):
158
+ """Add this operation to the _Bulk instance `bulkobj`."""
159
+ bulkobj.add_delete(self._filter, 0, collation=self._collation, hint=self._hint)
160
+
161
+ def __repr__(self):
162
+ return "DeleteMany(%r, %r)" % (self._filter, self._collation)
163
+
164
+ def __eq__(self, other: Any) -> bool:
165
+ if type(other) == type(self):
166
+ return (other._filter, other._collation) == (self._filter, self._collation)
167
+ return NotImplemented
168
+
169
+ def __ne__(self, other: Any) -> bool:
170
+ return not self == other
171
+
172
+
173
+ class ReplaceOne(object):
174
+ """Represents a replace_one operation."""
175
+
176
+ __slots__ = ("_filter", "_doc", "_upsert", "_collation", "_hint")
177
+
178
+ def __init__(
179
+ self,
180
+ filter: Mapping[str, Any],
181
+ replacement: Mapping[str, Any],
182
+ upsert: bool = False,
183
+ collation: Optional[_CollationIn] = None,
184
+ hint: Optional[_IndexKeyHint] = None,
185
+ ) -> None:
186
+ """Create a ReplaceOne instance.
187
+
188
+ For use with :meth:`~pymongo.collection.Collection.bulk_write`.
189
+
190
+ :Parameters:
191
+ - `filter`: A query that matches the document to replace.
192
+ - `replacement`: The new document.
193
+ - `upsert` (optional): If ``True``, perform an insert if no documents
194
+ match the filter.
195
+ - `collation` (optional): An instance of
196
+ :class:`~pymongo.collation.Collation`.
197
+ - `hint` (optional): An index to use to support the query
198
+ predicate specified either by its string name, or in the same
199
+ format as passed to
200
+ :meth:`~pymongo.collection.Collection.create_index` (e.g.
201
+ ``[('field', ASCENDING)]``). This option is only supported on
202
+ MongoDB 4.2 and above.
203
+
204
+ .. versionchanged:: 3.11
205
+ Added the ``hint`` option.
206
+ .. versionchanged:: 3.5
207
+ Added the ``collation`` option.
208
+ """
209
+ if filter is not None:
210
+ validate_is_mapping("filter", filter)
211
+ if upsert is not None:
212
+ validate_boolean("upsert", upsert)
213
+ if hint is not None:
214
+ if not isinstance(hint, str):
215
+ hint = helpers._index_document(hint)
216
+
217
+ self._filter = filter
218
+ self._doc = replacement
219
+ self._upsert = upsert
220
+ self._collation = collation
221
+ self._hint = hint
222
+
223
+ def _add_to_bulk(self, bulkobj):
224
+ """Add this operation to the _Bulk instance `bulkobj`."""
225
+ bulkobj.add_replace(
226
+ self._filter, self._doc, self._upsert, collation=self._collation, hint=self._hint
227
+ )
228
+
229
+ def __eq__(self, other: Any) -> bool:
230
+ if type(other) == type(self):
231
+ return (other._filter, other._doc, other._upsert, other._collation, other._hint) == (
232
+ self._filter,
233
+ self._doc,
234
+ self._upsert,
235
+ self._collation,
236
+ other._hint,
237
+ )
238
+ return NotImplemented
239
+
240
+ def __ne__(self, other: Any) -> bool:
241
+ return not self == other
242
+
243
+ def __repr__(self):
244
+ return "%s(%r, %r, %r, %r, %r)" % (
245
+ self.__class__.__name__,
246
+ self._filter,
247
+ self._doc,
248
+ self._upsert,
249
+ self._collation,
250
+ self._hint,
251
+ )
252
+
253
+
254
+ class _UpdateOp(object):
255
+ """Private base class for update operations."""
256
+
257
+ __slots__ = ("_filter", "_doc", "_upsert", "_collation", "_array_filters", "_hint")
258
+
259
+ def __init__(self, filter, doc, upsert, collation, array_filters, hint):
260
+ if filter is not None:
261
+ validate_is_mapping("filter", filter)
262
+ if upsert is not None:
263
+ validate_boolean("upsert", upsert)
264
+ if array_filters is not None:
265
+ validate_list("array_filters", array_filters)
266
+ if hint is not None:
267
+ if not isinstance(hint, str):
268
+ hint = helpers._index_document(hint)
269
+
270
+ self._filter = filter
271
+ self._doc = doc
272
+ self._upsert = upsert
273
+ self._collation = collation
274
+ self._array_filters = array_filters
275
+ self._hint = hint
276
+
277
+ def __eq__(self, other):
278
+ if type(other) == type(self):
279
+ return (
280
+ other._filter,
281
+ other._doc,
282
+ other._upsert,
283
+ other._collation,
284
+ other._array_filters,
285
+ other._hint,
286
+ ) == (
287
+ self._filter,
288
+ self._doc,
289
+ self._upsert,
290
+ self._collation,
291
+ self._array_filters,
292
+ self._hint,
293
+ )
294
+ return NotImplemented
295
+
296
+ def __ne__(self, other):
297
+ return not self == other
298
+
299
+ def __repr__(self):
300
+ return "%s(%r, %r, %r, %r, %r, %r)" % (
301
+ self.__class__.__name__,
302
+ self._filter,
303
+ self._doc,
304
+ self._upsert,
305
+ self._collation,
306
+ self._array_filters,
307
+ self._hint,
308
+ )
309
+
310
+
311
+ class UpdateOne(_UpdateOp):
312
+ """Represents an update_one operation."""
313
+
314
+ __slots__ = ()
315
+
316
+ def __init__(
317
+ self,
318
+ filter: Mapping[str, Any],
319
+ update: Union[Mapping[str, Any], _Pipeline],
320
+ upsert: bool = False,
321
+ collation: Optional[_CollationIn] = None,
322
+ array_filters: Optional[List[Mapping[str, Any]]] = None,
323
+ hint: Optional[_IndexKeyHint] = None,
324
+ ) -> None:
325
+ """Represents an update_one operation.
326
+
327
+ For use with :meth:`~pymongo.collection.Collection.bulk_write`.
328
+
329
+ :Parameters:
330
+ - `filter`: A query that matches the document to update.
331
+ - `update`: The modifications to apply.
332
+ - `upsert` (optional): If ``True``, perform an insert if no documents
333
+ match the filter.
334
+ - `collation` (optional): An instance of
335
+ :class:`~pymongo.collation.Collation`.
336
+ - `array_filters` (optional): A list of filters specifying which
337
+ array elements an update should apply.
338
+ - `hint` (optional): An index to use to support the query
339
+ predicate specified either by its string name, or in the same
340
+ format as passed to
341
+ :meth:`~pymongo.collection.Collection.create_index` (e.g.
342
+ ``[('field', ASCENDING)]``). This option is only supported on
343
+ MongoDB 4.2 and above.
344
+
345
+ .. versionchanged:: 3.11
346
+ Added the `hint` option.
347
+ .. versionchanged:: 3.9
348
+ Added the ability to accept a pipeline as the `update`.
349
+ .. versionchanged:: 3.6
350
+ Added the `array_filters` option.
351
+ .. versionchanged:: 3.5
352
+ Added the `collation` option.
353
+ """
354
+ super(UpdateOne, self).__init__(filter, update, upsert, collation, array_filters, hint)
355
+
356
+ def _add_to_bulk(self, bulkobj):
357
+ """Add this operation to the _Bulk instance `bulkobj`."""
358
+ bulkobj.add_update(
359
+ self._filter,
360
+ self._doc,
361
+ False,
362
+ self._upsert,
363
+ collation=self._collation,
364
+ array_filters=self._array_filters,
365
+ hint=self._hint,
366
+ )
367
+
368
+
369
+ class UpdateMany(_UpdateOp):
370
+ """Represents an update_many operation."""
371
+
372
+ __slots__ = ()
373
+
374
+ def __init__(
375
+ self,
376
+ filter: Mapping[str, Any],
377
+ update: Union[Mapping[str, Any], _Pipeline],
378
+ upsert: bool = False,
379
+ collation: Optional[_CollationIn] = None,
380
+ array_filters: Optional[List[Mapping[str, Any]]] = None,
381
+ hint: Optional[_IndexKeyHint] = None,
382
+ ) -> None:
383
+ """Create an UpdateMany instance.
384
+
385
+ For use with :meth:`~pymongo.collection.Collection.bulk_write`.
386
+
387
+ :Parameters:
388
+ - `filter`: A query that matches the documents to update.
389
+ - `update`: The modifications to apply.
390
+ - `upsert` (optional): If ``True``, perform an insert if no documents
391
+ match the filter.
392
+ - `collation` (optional): An instance of
393
+ :class:`~pymongo.collation.Collation`.
394
+ - `array_filters` (optional): A list of filters specifying which
395
+ array elements an update should apply.
396
+ - `hint` (optional): An index to use to support the query
397
+ predicate specified either by its string name, or in the same
398
+ format as passed to
399
+ :meth:`~pymongo.collection.Collection.create_index` (e.g.
400
+ ``[('field', ASCENDING)]``). This option is only supported on
401
+ MongoDB 4.2 and above.
402
+
403
+ .. versionchanged:: 3.11
404
+ Added the `hint` option.
405
+ .. versionchanged:: 3.9
406
+ Added the ability to accept a pipeline as the `update`.
407
+ .. versionchanged:: 3.6
408
+ Added the `array_filters` option.
409
+ .. versionchanged:: 3.5
410
+ Added the `collation` option.
411
+ """
412
+ super(UpdateMany, self).__init__(filter, update, upsert, collation, array_filters, hint)
413
+
414
+ def _add_to_bulk(self, bulkobj):
415
+ """Add this operation to the _Bulk instance `bulkobj`."""
416
+ bulkobj.add_update(
417
+ self._filter,
418
+ self._doc,
419
+ True,
420
+ self._upsert,
421
+ collation=self._collation,
422
+ array_filters=self._array_filters,
423
+ hint=self._hint,
424
+ )
425
+
426
+
427
+ class IndexModel(object):
428
+ """Represents an index to create."""
429
+
430
+ __slots__ = ("__document",)
431
+
432
+ def __init__(self, keys: _IndexKeyHint, **kwargs: Any) -> None:
433
+ """Create an Index instance.
434
+
435
+ For use with :meth:`~pymongo.collection.Collection.create_indexes`.
436
+
437
+ Takes either a single key or a list of (key, direction) pairs.
438
+ The key(s) must be an instance of :class:`basestring`
439
+ (:class:`str` in python 3), and the direction(s) must be one of
440
+ (:data:`~pymongo.ASCENDING`, :data:`~pymongo.DESCENDING`,
441
+ :data:`~pymongo.GEO2D`, :data:`~pymongo.GEOSPHERE`,
442
+ :data:`~pymongo.HASHED`, :data:`~pymongo.TEXT`).
443
+
444
+ Valid options include, but are not limited to:
445
+
446
+ - `name`: custom name to use for this index - if none is
447
+ given, a name will be generated.
448
+ - `unique`: if ``True``, creates a uniqueness constraint on the index.
449
+ - `background`: if ``True``, this index should be created in the
450
+ background.
451
+ - `sparse`: if ``True``, omit from the index any documents that lack
452
+ the indexed field.
453
+ - `bucketSize`: for use with geoHaystack indexes.
454
+ Number of documents to group together within a certain proximity
455
+ to a given longitude and latitude.
456
+ - `min`: minimum value for keys in a :data:`~pymongo.GEO2D`
457
+ index.
458
+ - `max`: maximum value for keys in a :data:`~pymongo.GEO2D`
459
+ index.
460
+ - `expireAfterSeconds`: <int> Used to create an expiring (TTL)
461
+ collection. MongoDB will automatically delete documents from
462
+ this collection after <int> seconds. The indexed field must
463
+ be a UTC datetime or the data will not expire.
464
+ - `partialFilterExpression`: A document that specifies a filter for
465
+ a partial index.
466
+ - `collation`: An instance of :class:`~pymongo.collation.Collation`
467
+ that specifies the collation to use.
468
+ - `wildcardProjection`: Allows users to include or exclude specific
469
+ field paths from a `wildcard index`_ using the { "$**" : 1} key
470
+ pattern. Requires MongoDB >= 4.2.
471
+ - `hidden`: if ``True``, this index will be hidden from the query
472
+ planner and will not be evaluated as part of query plan
473
+ selection. Requires MongoDB >= 4.4.
474
+
475
+ See the MongoDB documentation for a full list of supported options by
476
+ server version.
477
+
478
+ :Parameters:
479
+ - `keys`: a single key or a list of (key, direction)
480
+ pairs specifying the index to create
481
+ - `**kwargs` (optional): any additional index creation
482
+ options (see the above list) should be passed as keyword
483
+ arguments
484
+
485
+ .. versionchanged:: 3.11
486
+ Added the ``hidden`` option.
487
+ .. versionchanged:: 3.2
488
+ Added the ``partialFilterExpression`` option to support partial
489
+ indexes.
490
+
491
+ .. _wildcard index: https://mongodb.com/docs/master/core/index-wildcard/
492
+ """
493
+ keys = _index_list(keys)
494
+ if "name" not in kwargs:
495
+ kwargs["name"] = _gen_index_name(keys)
496
+ kwargs["key"] = _index_document(keys)
497
+ collation = validate_collation_or_none(kwargs.pop("collation", None))
498
+ self.__document = kwargs
499
+ if collation is not None:
500
+ self.__document["collation"] = collation
501
+
502
+ @property
503
+ def document(self) -> Dict[str, Any]:
504
+ """An index document suitable for passing to the createIndexes
505
+ command.
506
+ """
507
+ return self.__document
@@ -0,0 +1,183 @@
1
+ # Copyright 2014-present MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License"); you
4
+ # may not use this file except in compliance with the License. You
5
+ # 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
12
+ # implied. See the License for the specific language governing
13
+ # permissions and limitations under the License.
14
+
15
+ """Run a target function on a background thread."""
16
+
17
+ import threading
18
+ import time
19
+ import weakref
20
+ from typing import Any, Optional
21
+
22
+
23
+ class PeriodicExecutor(object):
24
+ def __init__(self, interval, min_interval, target, name=None):
25
+ """ "Run a target function periodically on a background thread.
26
+
27
+ If the target's return value is false, the executor stops.
28
+
29
+ :Parameters:
30
+ - `interval`: Seconds between calls to `target`.
31
+ - `min_interval`: Minimum seconds between calls if `wake` is
32
+ called very often.
33
+ - `target`: A function.
34
+ - `name`: A name to give the underlying thread.
35
+ """
36
+ # threading.Event and its internal condition variable are expensive
37
+ # in Python 2, see PYTHON-983. Use a boolean to know when to wake.
38
+ # The executor's design is constrained by several Python issues, see
39
+ # "periodic_executor.rst" in this repository.
40
+ self._event = False
41
+ self._interval = interval
42
+ self._min_interval = min_interval
43
+ self._target = target
44
+ self._stopped = False
45
+ self._thread: Optional[threading.Thread] = None
46
+ self._name = name
47
+ self._skip_sleep = False
48
+
49
+ self._thread_will_exit = False
50
+ self._lock = threading.Lock()
51
+
52
+ def __repr__(self):
53
+ return "<%s(name=%s) object at 0x%x>" % (self.__class__.__name__, self._name, id(self))
54
+
55
+ def open(self) -> None:
56
+ """Start. Multiple calls have no effect.
57
+
58
+ Not safe to call from multiple threads at once.
59
+ """
60
+ with self._lock:
61
+ if self._thread_will_exit:
62
+ # If the background thread has read self._stopped as True
63
+ # there is a chance that it has not yet exited. The call to
64
+ # join should not block indefinitely because there is no
65
+ # other work done outside the while loop in self._run.
66
+ try:
67
+ assert self._thread is not None
68
+ self._thread.join()
69
+ except ReferenceError:
70
+ # Thread terminated.
71
+ pass
72
+ self._thread_will_exit = False
73
+ self._stopped = False
74
+ started: Any = False
75
+ try:
76
+ started = self._thread and self._thread.is_alive()
77
+ except ReferenceError:
78
+ # Thread terminated.
79
+ pass
80
+
81
+ if not started:
82
+ thread = threading.Thread(target=self._run, name=self._name)
83
+ thread.daemon = True
84
+ self._thread = weakref.proxy(thread)
85
+ _register_executor(self)
86
+ thread.start()
87
+
88
+ def close(self, dummy: Any = None) -> None:
89
+ """Stop. To restart, call open().
90
+
91
+ The dummy parameter allows an executor's close method to be a weakref
92
+ callback; see monitor.py.
93
+ """
94
+ self._stopped = True
95
+
96
+ def join(self, timeout: Optional[int] = None) -> None:
97
+ if self._thread is not None:
98
+ try:
99
+ self._thread.join(timeout)
100
+ except (ReferenceError, RuntimeError):
101
+ # Thread already terminated, or not yet started.
102
+ pass
103
+
104
+ def wake(self) -> None:
105
+ """Execute the target function soon."""
106
+ self._event = True
107
+
108
+ def update_interval(self, new_interval: int) -> None:
109
+ self._interval = new_interval
110
+
111
+ def skip_sleep(self) -> None:
112
+ self._skip_sleep = True
113
+
114
+ def __should_stop(self):
115
+ with self._lock:
116
+ if self._stopped:
117
+ self._thread_will_exit = True
118
+ return True
119
+ return False
120
+
121
+ def _run(self):
122
+ while not self.__should_stop():
123
+ try:
124
+ if not self._target():
125
+ self._stopped = True
126
+ break
127
+ except BaseException:
128
+ with self._lock:
129
+ self._stopped = True
130
+ self._thread_will_exit = True
131
+
132
+ raise
133
+
134
+ if self._skip_sleep:
135
+ self._skip_sleep = False
136
+ else:
137
+ deadline = time.monotonic() + self._interval
138
+ while not self._stopped and time.monotonic() < deadline:
139
+ time.sleep(self._min_interval)
140
+ if self._event:
141
+ break # Early wake.
142
+
143
+ self._event = False
144
+
145
+
146
+ # _EXECUTORS has a weakref to each running PeriodicExecutor. Once started,
147
+ # an executor is kept alive by a strong reference from its thread and perhaps
148
+ # from other objects. When the thread dies and all other referrers are freed,
149
+ # the executor is freed and removed from _EXECUTORS. If any threads are
150
+ # running when the interpreter begins to shut down, we try to halt and join
151
+ # them to avoid spurious errors.
152
+ _EXECUTORS = set()
153
+
154
+
155
+ def _register_executor(executor):
156
+ ref = weakref.ref(executor, _on_executor_deleted)
157
+ _EXECUTORS.add(ref)
158
+
159
+
160
+ def _on_executor_deleted(ref):
161
+ _EXECUTORS.remove(ref)
162
+
163
+
164
+ def _shutdown_executors():
165
+ if _EXECUTORS is None:
166
+ return
167
+
168
+ # Copy the set. Stopping threads has the side effect of removing executors.
169
+ executors = list(_EXECUTORS)
170
+
171
+ # First signal all executors to close...
172
+ for ref in executors:
173
+ executor = ref()
174
+ if executor:
175
+ executor.close()
176
+
177
+ # ...then try to join them.
178
+ for ref in executors:
179
+ executor = ref()
180
+ if executor:
181
+ executor.join(1)
182
+
183
+ executor = None