atomicshop 2.16.40__py3-none-any.whl → 2.16.42__py3-none-any.whl

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.

Potentially problematic release.


This version of atomicshop might be problematic. Click here for more details.

atomicshop/__init__.py CHANGED
@@ -1,4 +1,4 @@
1
1
  """Atomic Basic functions and classes to make developer life easier"""
2
2
 
3
3
  __author__ = "Den Kras"
4
- __version__ = '2.16.40'
4
+ __version__ = '2.16.42'
@@ -64,7 +64,7 @@ class MongoDBWrapper:
64
64
  self.client.close()
65
65
  self.client = None
66
66
 
67
- def index(
67
+ def insert(
68
68
  self,
69
69
  object_instance: Union[list[dict], dict],
70
70
  collection_name: str,
@@ -84,7 +84,7 @@ class MongoDBWrapper:
84
84
 
85
85
  self.connect()
86
86
 
87
- index(
87
+ insert(
88
88
  object_instance=object_instance,
89
89
  database=self.db, collection_name=collection_name,
90
90
  add_timestamp=add_timestamp, convert_mixed_lists_to_strings=convert_mixed_lists_to_strings,
@@ -92,7 +92,7 @@ class MongoDBWrapper:
92
92
 
93
93
  def delete(
94
94
  self,
95
- query_instance: Union[list[dict], dict],
95
+ filter_instance: Union[list[dict], dict],
96
96
  collection_name: str
97
97
  ):
98
98
  """
@@ -100,7 +100,7 @@ class MongoDBWrapper:
100
100
  For pure mongo, this is the list of queries to remove.
101
101
  Each query for a single item.
102
102
 
103
- :param query_instance: dict or list of dictionaries, the list of queries to remove from the collection.
103
+ :param filter_instance: dict or list of dictionaries (the list of filters to remove from the collection).
104
104
  :param collection_name: str, the name of the collection.
105
105
 
106
106
  :return: None
@@ -109,21 +109,21 @@ class MongoDBWrapper:
109
109
  self.connect()
110
110
 
111
111
  delete(
112
- query_instance=query_instance,
112
+ filter_instance=filter_instance,
113
113
  database=self.db, collection_name=collection_name,
114
114
  mongo_client=self.client, close_client=False)
115
115
 
116
116
  def delete_many(
117
117
  self,
118
- query: dict,
118
+ filter_query: dict,
119
119
  collection_name: str
120
120
  ):
121
121
  """
122
- Remove all entries that match the query from a MongoDB collection.
122
+ Remove all entries that match the filter query from a MongoDB collection.
123
123
 
124
- :param query: dict, the query to search for.
124
+ :param filter_query: dict, the filter query to search for.
125
125
  Example, search for all entries with column name 'name' equal to 'John':
126
- query = {'name': 'John'}
126
+ filter query = {'name': 'John'}
127
127
  :param collection_name: str, the name of the collection.
128
128
 
129
129
  :return: result of the operation.
@@ -132,17 +132,51 @@ class MongoDBWrapper:
132
132
  self.connect()
133
133
 
134
134
  return delete_many(
135
- query=query,
135
+ filter_query=filter_query,
136
136
  database=self.db, collection_name=collection_name,
137
137
  mongo_client=self.client, close_client=False)
138
138
 
139
+ def create_index(
140
+ self,
141
+ collection_name: str,
142
+ fields_list: list[tuple[str, int]],
143
+ name: str = None
144
+ ):
145
+ """
146
+ Create an index in a MongoDB collection.
147
+ :param collection_name: str, the name of the collection.
148
+ :param fields_list: list of tuples, each tuple will contain
149
+ [0] string of the field name and
150
+ [1] the integer value of the order
151
+ to sort by, this is pymongo default, 1 for ascending and -1 for descending.
152
+ Example:
153
+ [
154
+ ('vendor', 1),
155
+ ('model', -1)
156
+ ]
157
+
158
+ Explanation:
159
+ This will create a compound index that will sort the collection by the field 'vendor'
160
+ in ascending order, and then by the field 'model' in descending order.
161
+ :param name: str, the name of the index.
162
+
163
+ :return: None
164
+ """
165
+
166
+ self.connect()
167
+
168
+ create_index(
169
+ database=self.db, collection_name=collection_name,
170
+ fields_list=fields_list, name=name,
171
+ mongo_client=self.client, close_client=False)
172
+
139
173
  def find(
140
174
  self,
141
175
  collection_name: str,
142
- query: dict = None,
176
+ filter_query: dict = None,
143
177
  page: int = None,
144
178
  items: int = None,
145
- sorting: dict[str, Literal[
179
+ sort: dict[str, Literal[
146
180
  'asc', 'desc',
147
181
  1, -1]] = None,
148
182
  convert_object_id_to_str: bool = False,
@@ -151,18 +185,18 @@ class MongoDBWrapper:
151
185
  """
152
186
  Find entries in a MongoDB collection by query.
153
187
  :param collection_name: str, the name of the collection.
154
- :param query: dict, the query to search for.
188
+ :param filter_query: dict, the query to search for.
155
189
  Example, search for all entries with column name 'name' equal to 'John':
156
- query = {'name': 'John'}
190
+ filter_query = {'name': 'John'}
157
191
  Example, return all entries from collection:
158
- query = None
192
+ filter_query = None
159
193
 
160
194
  CHECK MORE EXAMPLES IN THE DOCSTRING OF THE FUNCTION 'find' BELOW which is not in this class.
161
195
  :param page: int, the page number (Optional).
162
196
  The results are filtered after results are fetched from db.
163
197
  :param items: int, the number of results per page (Optional).
164
198
  The results are filtered after results are fetched from db.
165
- :param sorting: dict, the name of the field and the order to sort the containers by.
199
+ :param sort: dict, the name of the field and the order to sort the containers by.
166
200
  You can use several fields to sort the containers by several fields.
167
201
  In this case the containers will be sorted by the first field, then by the second field, etc.
168
202
  You can also use only singular field to sort the containers by only one field.
@@ -195,7 +229,7 @@ class MongoDBWrapper:
195
229
 
196
230
  entries: list[dict] = find(
197
231
  database=self.db, collection_name=collection_name,
198
- query=query, page=page, items=items, sorting=sorting,
232
+ filter_query=filter_query, page=page, items=items, sort=sort,
199
233
  convert_object_id_to_str=convert_object_id_to_str, key_convert_to_dict=keys_convert_to_dict,
200
234
  mongo_client=self.client, close_client=False)
201
235
 
@@ -205,7 +239,7 @@ class MongoDBWrapper:
205
239
  self,
206
240
  collection_name: str,
207
241
  field_name: str,
208
- query: dict = None
242
+ filter_query: dict = None
209
243
  ) -> list:
210
244
  """
211
245
  Get distinct values of a field from a MongoDB collection.
@@ -227,7 +261,7 @@ class MongoDBWrapper:
227
261
 
228
262
  :param collection_name: str, the name of the collection.
229
263
  :param field_name: str, the name of the field.
230
- :param query: dict, the query to search for. If None, the query will not be executed.
264
+ :param filter_query: dict, the filter query to search for. If None, the filter query will not be executed.
231
265
 
232
266
  :return: list, the list of distinct values.
233
267
  """
@@ -236,26 +270,26 @@ class MongoDBWrapper:
236
270
 
237
271
  distinct_values = distinct(
238
272
  database=self.db, collection_name=collection_name,
239
- field_name=field_name, query=query, mongo_client=self.client, close_client=False)
273
+ field_name=field_name, filter_query=filter_query, mongo_client=self.client, close_client=False)
240
274
 
241
275
  return distinct_values
242
276
 
243
277
  def update(
244
278
  self,
245
279
  collection_name: str,
246
- query: dict,
280
+ filter_query: dict,
247
281
  update_instance: Union[dict, list[dict]],
248
282
  add_timestamp: bool = False,
249
283
  convert_mixed_lists_to_strings: bool = False
250
284
  ):
251
285
  """
252
- Update one entry in a MongoDB collection by query.
286
+ Update one entry in a MongoDB collection by filter query.
253
287
  :param collection_name: str, the name of the collection.
254
- :param query: dict, the query to search for.
288
+ :param filter_query: dict, the filter query to search for.
255
289
  Example, search for all entries with column name 'name' equal to 'John':
256
- query = {'name': 'John'}
290
+ filter_query = {'name': 'John'}
257
291
  Find by Object id:
258
- query = {'_id': ObjectId('5f3e3b3b4b9f3b3b4b9f3b3b')}
292
+ filter_query = {'_id': ObjectId('5f3e3b3b4b9f3b3b4b9f3b3b')}
259
293
  :param update_instance: dict or list of dicts, the update to apply.
260
294
  Get examples for operators for each dict in the docstring of the function 'update' below.
261
295
  :param add_timestamp: bool, if True, a current time timestamp will be added to the object.
@@ -268,26 +302,26 @@ class MongoDBWrapper:
268
302
 
269
303
  return update(
270
304
  database=self.db, collection_name=collection_name,
271
- query=query, update_instance=update_instance, add_timestamp=add_timestamp,
305
+ filter_query=filter_query, update_instance=update_instance, add_timestamp=add_timestamp,
272
306
  convert_mixed_lists_to_strings=convert_mixed_lists_to_strings,
273
307
  mongo_client=self.client, close_client=False)
274
308
 
275
309
  def replace(
276
310
  self,
277
311
  collection_name: str,
278
- query: dict,
312
+ filter_query: dict,
279
313
  replacement: dict,
280
314
  add_timestamp: bool = False,
281
315
  convert_mixed_lists_to_strings: bool = False
282
316
  ):
283
317
  """
284
- Replace one entry in a MongoDB collection by query.
318
+ Replace one entry in a MongoDB collection by filter query.
285
319
  :param collection_name: str, the name of the collection.
286
- :param query: dict, the query to search for.
320
+ :param filter_query: dict, the filter query to search for.
287
321
  Example, search for all entries with column name 'name' equal to 'John':
288
- query = {'name': 'John'}
322
+ filter_query = {'name': 'John'}
289
323
  Find by Object id:
290
- query = {'_id': ObjectId('5f3e3b3b4b9f3b3b4b9f3b3b')}
324
+ filter_query = {'_id': ObjectId('5f3e3b3b4b9f3b3b4b9f3b3b')}
291
325
  :param replacement: dict, the replacement to apply.
292
326
  :param add_timestamp: bool, if True, a current time timestamp will be added to the object.
293
327
  :param convert_mixed_lists_to_strings: bool, if True, mixed lists or tuples when entries are
@@ -299,24 +333,62 @@ class MongoDBWrapper:
299
333
 
300
334
  return replace(
301
335
  database=self.db, collection_name=collection_name,
302
- query=query, replacement=replacement,
336
+ filter_query=filter_query, replacement=replacement,
303
337
  add_timestamp=add_timestamp, convert_mixed_lists_to_strings=convert_mixed_lists_to_strings,
304
338
  mongo_client=self.client, close_client=False)
305
339
 
340
+ def get_all_indexes_in_collection(
341
+ self,
342
+ collection_name: str
343
+ ) -> dict:
344
+ """
345
+ Get all indexes in a MongoDB collection.
346
+ :param collection_name: str, the name of the collection.
347
+ :return: list of dictionaries, the list of indexes.
348
+ """
349
+
350
+ self.connect()
351
+
352
+ indexes: dict = get_all_indexes_in_collection(
353
+ database=self.db, collection_name=collection_name,
354
+ mongo_client=self.client, close_client=False)
355
+
356
+ return indexes
357
+
358
+ def is_index_name_in_collection(
359
+ self,
360
+ collection_name: str,
361
+ index_name: str
362
+ ) -> bool:
363
+ """
364
+ Check if an index name exists in a MongoDB collection.
365
+ :param collection_name: str, the name of the collection.
366
+ :param index_name: str, the name of the index.
367
+ :return: bool, if the index name exists in the collection.
368
+ """
369
+
370
+ self.connect()
371
+
372
+ exists: bool = is_index_name_in_collection(
373
+ database=self.db, collection_name=collection_name,
374
+ index_name=index_name, mongo_client=self.client, close_client=False)
375
+
376
+ return exists
377
+
306
378
  def count_entries_in_collection(
307
379
  self,
308
380
  collection_name: str,
309
- query: dict = None
381
+ filter_query: dict = None
310
382
  ) -> int:
311
383
  """
312
384
  Count entries in a MongoDB collection by query.
313
385
 
314
386
  :param collection_name: str, the name of the collection.
315
- :param query: dict, the query to search for.
387
+ :param filter_query: dict, the query to search for.
316
388
  Example, search for all entries with column name 'name' equal to 'John':
317
- query = {'name': 'John'}
389
+ filter_query = {'name': 'John'}
318
390
  Example, return all entries from collection:
319
- query = None
391
+ filter_query = None
320
392
 
321
393
  :return: int, the number of entries that match the query.
322
394
  """
@@ -325,7 +397,7 @@ class MongoDBWrapper:
325
397
 
326
398
  count = count_entries_in_collection(
327
399
  database=self.db, collection_name=collection_name,
328
- query=query, mongo_client=self.client, close_client=False)
400
+ filter_query=filter_query, mongo_client=self.client, close_client=False)
329
401
 
330
402
  return count
331
403
 
@@ -392,7 +464,7 @@ def get_db(
392
464
  return mongo_client[database]
393
465
 
394
466
 
395
- def index(
467
+ def insert(
396
468
  object_instance: Union[list[dict], dict],
397
469
  database: Union[str, pymongo.database.Database],
398
470
  collection_name: str,
@@ -452,7 +524,7 @@ def index(
452
524
 
453
525
 
454
526
  def delete(
455
- query_instance: Union[list[dict], dict],
527
+ filter_instance: Union[list[dict], dict],
456
528
  database: Union[str, pymongo.database.Database],
457
529
  collection_name: str,
458
530
  mongo_client: pymongo.MongoClient = None,
@@ -461,9 +533,10 @@ def delete(
461
533
  """
462
534
  Remove a dict or list of dictionaries or a dictionary from a MongoDB collection.
463
535
 
464
- :param query_instance: list of dictionaries, the list of dictionaries to remove from the collection.
465
- For pure mongo, this is the list of queries to remove.
466
- Each query for a single item.
536
+ :param filter_instance: dict or list of dictionaries,
537
+ dict, the regular filter for pymongo.
538
+ list of dictionaries to remove from the collection, for pure mongo, this is the list of filtered to remove.
539
+ Each filter for a single item.
467
540
  :param database: String or the database object.
468
541
  str - the name of the database. In this case the database object will be created.
469
542
  pymongo.database.Database - the database object that will be used instead of creating a new one.
@@ -475,7 +548,7 @@ def delete(
475
548
  :return: None
476
549
  """
477
550
 
478
- _is_object_list_of_dicts_or_dict(query_instance)
551
+ _is_object_list_of_dicts_or_dict(filter_instance)
479
552
 
480
553
  if not mongo_client:
481
554
  mongo_client = connect()
@@ -484,10 +557,10 @@ def delete(
484
557
  db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
485
558
  collection = db[collection_name]
486
559
 
487
- if isinstance(query_instance, dict):
488
- collection.delete_one(query_instance)
489
- elif isinstance(query_instance, list):
490
- for doc in query_instance:
560
+ if isinstance(filter_instance, dict):
561
+ collection.delete_one(filter_instance)
562
+ elif isinstance(filter_instance, list):
563
+ for doc in filter_instance:
491
564
  collection.delete_one(doc)
492
565
 
493
566
  if close_client:
@@ -495,18 +568,18 @@ def delete(
495
568
 
496
569
 
497
570
  def delete_many(
498
- query: dict,
571
+ filter_query: dict,
499
572
  database: Union[str, pymongo.database.Database],
500
573
  collection_name: str,
501
574
  mongo_client: pymongo.MongoClient = None,
502
575
  close_client: bool = False
503
576
  ):
504
577
  """
505
- Remove all entries that match the query from a MongoDB collection.
578
+ Remove all entries that match the filter query from a MongoDB collection.
506
579
 
507
- :param query: dict, the query to search for.
580
+ :param filter_query: dict, the filter query to search for.
508
581
  Example, search for all entries with column name 'name' equal to 'John':
509
- query = {'name': 'John'}
582
+ filter_query = {'name': 'John'}
510
583
  :param database: String or the database object.
511
584
  str - the name of the database. In this case the database object will be created.
512
585
  pymongo.database.Database - the database object that will be used instead of creating a new one.
@@ -525,7 +598,7 @@ def delete_many(
525
598
  db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
526
599
  collection = db[collection_name]
527
600
 
528
- result = collection.delete_many(query)
601
+ result = collection.delete_many(filter_query)
529
602
 
530
603
  if close_client:
531
604
  mongo_client.close()
@@ -533,13 +606,62 @@ def delete_many(
533
606
  return result
534
607
 
535
608
 
609
+ def create_index(
610
+ database: Union[str, pymongo.database.Database],
611
+ collection_name: str,
612
+ fields_list: list[tuple[str, int]],
613
+ name: str = None,
614
+ mongo_client: pymongo.MongoClient = None,
615
+ close_client: bool = False
616
+ ):
617
+ """
618
+ Create an index in a MongoDB collection.
619
+ :param database: String or the database object.
620
+ str - the name of the database. In this case the database object will be created.
621
+ pymongo.database.Database - the database object that will be used instead of creating a new one.
622
+ :param collection_name: str, the name of the collection.
623
+ :param fields_list: list of tuples, each tuple will contain
624
+ [0] string of the field name and
625
+ [1] the integer value of the order
626
+ to sort by, this is pymongo default, 1 for ascending and -1 for descending.
627
+ Example:
628
+ [
629
+ ('vendor', 1),
630
+ ('model', -1)
631
+ ]
632
+
633
+ Explanation:
634
+ This will create a compound index that will sort the collection by the field 'vendor' in ascending order,
635
+ and then by the field 'model' in descending order.
636
+ :param name: str, the name of the index.
637
+ :param mongo_client: pymongo.MongoClient, the connection object.
638
+ If None, a new connection will be created to default URI.
639
+ :param close_client: bool, if True, the connection will be closed after the operation.
640
+
641
+ :return: None
642
+ """
643
+
644
+ if not mongo_client:
645
+ mongo_client = connect()
646
+ close_client = True
647
+
648
+ db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
649
+ collection = db[collection_name]
650
+
651
+ collection.create_index(fields_list, name=name)
652
+
653
+ if close_client:
654
+ mongo_client.close()
655
+
656
+
536
657
  def find(
537
658
  database: Union[str, pymongo.database.Database],
538
659
  collection_name: str,
539
- query: dict = None,
660
+ filter_query: dict = None,
661
+ projection: dict = None,
540
662
  page: int = None,
541
663
  items: int = None,
542
- sorting: Union[
664
+ sort: Union[
543
665
  dict[str, Literal[
544
666
  'asc', 'desc',
545
667
  'ASC', 'DESC',
@@ -558,55 +680,62 @@ def find(
558
680
  str - the name of the database. In this case the database object will be created.
559
681
  pymongo.database.Database - the database object that will be used instead of creating a new one.
560
682
  :param collection_name: str, the name of the collection.
561
- :param query: dict, the query to search for.
683
+ :param filter_query: dict, the query to search for.
562
684
  Example, return all entries from collection:
563
- query = None
685
+ filter_query = None
564
686
  Example, search for all entries with column name 'name' equal to 'John':
565
- query = {'name': 'John'}
687
+ filter_query = {'name': 'John'}
566
688
 
567
689
  Additional parameters to use in the value of the query:
568
690
  $regex: Will search for a regex pattern in the field.
569
691
  Example for searching for a value that contains 'test':
570
- query = {'field_name': {'$regex': 'test'}}
692
+ filter_query = {'field_name': {'$regex': 'test'}}
571
693
  This will return all entries where the field 'field_name' contains the word 'test':
572
694
  'test', 'test1', '2test', etc.
573
695
 
574
696
  Example for searching for a value that starts with 'test':
575
- query = {'field_name': {'$regex': '^test'}}
697
+ filter_query = {'field_name': {'$regex': '^test'}}
576
698
  $options: The options for the regex search.
577
699
  'i': case-insensitive search.
578
700
  Example for case-insensitive search:
579
- query = {'field_name': {'$regex': 'test', '$options': 'i'}}
701
+ filter_query = {'field_name': {'$regex': 'test', '$options': 'i'}}
580
702
  $and: Will search for entries that match all the conditions.
581
703
  Example for searching for entries that match all the conditions:
582
- query = {'$and': [
704
+ filter_query = {'$and': [
583
705
  {'field_name1': 'value1'},
584
706
  {'field_name2': 'value2'}
585
707
  ]}
586
708
  $or: Will search for entries that match at least one of the conditions.
587
709
  Example for searching for entries that match at least one of the conditions:
588
- query = {'$or': [
710
+ filter_query = {'$or': [
589
711
  {'field_name1': 'value1'},
590
712
  {'field_name2': 'value2'}
591
713
  ]}
592
714
  $in: Will search for a value in a list of values.
593
715
  Example for searching for a value that is in a list of values:
594
- query = {'field_name': {'$in': ['value1', 'value2', 'value3']}}
716
+ filter_query = {'field_name': {'$in': ['value1', 'value2', 'value3']}}
595
717
  $nin: Will search for a value not in a list of values.
596
718
  Example for searching for a value that is not in a list of values:
597
- query = {'field_name': {'$nin': ['value1', 'value2', 'value3']}}
719
+ filter_query = {'field_name': {'$nin': ['value1', 'value2', 'value3']}}
598
720
  $exists: Will search for entries where the field exists or not.
599
721
  Example for searching for entries where the field exists:
600
- query = {'field_name': {'$exists': True}}
722
+ filter_query = {'field_name': {'$exists': True}}
601
723
  Example for searching for entries where the field does not exist:
602
- query = {'field_name': {'$exists': False}}
724
+ filter_query = {'field_name': {'$exists': False}}
603
725
  $ne: Will search for entries where the field is not equal to the value.
604
726
  Example for searching for entries where the field is not equal to the value:
605
- query = {'field_name': {'$ne': 'value'}}
606
-
727
+ filter_query = {'field_name': {'$ne': 'value'}}
728
+
729
+ :param projection: dict, the only fields to return or exclude.
730
+ Example, return only the field 'name' and 'age':
731
+ projection = {'name': 1, 'age': 1}
732
+ Example, return all fields except the field 'age':
733
+ projection = {'age': 0}
734
+ Example, return all fields except the field 'age' and 'name':
735
+ projection = {'age': 0, 'name': 0}
607
736
  :param page: int, the page number (Optional).
608
737
  :param items: int, the number of results per page (Optional).
609
- :param sorting: dict or list of tuples:
738
+ :param sort: dict or list of tuples:
610
739
  dict, the name of the field and the order to sort the containers by.
611
740
  You can use several fields to sort the containers by several fields.
612
741
  In this case the containers will be sorted by the first field, then by the second field, etc.
@@ -647,8 +776,8 @@ def find(
647
776
  elif items and not page:
648
777
  page = 1
649
778
 
650
- if sorting and isinstance(sorting, dict):
651
- for key_to_sort_by, order in sorting.items():
779
+ if sort and isinstance(sort, dict):
780
+ for key_to_sort_by, order in sort.items():
652
781
  if order.lower() not in ['asc', 'desc', 1, -1]:
653
782
  raise ValueError("The order must be 'asc', 'desc', 1 or -1.")
654
783
 
@@ -659,35 +788,42 @@ def find(
659
788
  db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
660
789
  collection = db[collection_name]
661
790
 
662
- if query is None:
663
- query = {}
791
+ if filter_query is None:
792
+ filter_query = {}
793
+
794
+ # 'skip_items' can be 0, if we ask for the first page, so we still need to cut the number of items.
795
+ # In this case checking if 'items' is not None is enough.
796
+ if items is None:
797
+ items = 0
664
798
 
665
799
  # Calculate the number of documents to skip
666
800
  skip_items = 0
667
801
  if page and items:
668
802
  skip_items = (page - 1) * items
669
803
 
670
- collection_items = collection.find(query)
671
-
672
- if sorting:
673
- sorting_list_of_tuples: list[tuple[str, int]] = []
674
- if isinstance(sorting, dict):
675
- for key_to_sort_by, order in sorting.items():
804
+ # noinspection PyTypeChecker
805
+ sorting_list_of_tuples: list[tuple[str, int]] = None
806
+ if sort:
807
+ sorting_list_of_tuples = []
808
+ if isinstance(sort, dict):
809
+ for key_to_sort_by, order in sort.items():
676
810
  if order.lower() == 'asc':
677
811
  order = pymongo.ASCENDING
678
812
  elif order.lower() == 'desc':
679
813
  order = pymongo.DESCENDING
680
814
 
681
815
  sorting_list_of_tuples.append((key_to_sort_by, order))
682
- elif sorting and isinstance(sorting, list):
683
- sorting_list_of_tuples = sorting
816
+ elif sort and isinstance(sort, list):
817
+ sorting_list_of_tuples = sort
684
818
 
685
- collection_items = collection_items.sort(sorting_list_of_tuples)
819
+ # collection_items = collection_items.sort(sorting_list_of_tuples)
820
+ collection_items = collection.find(
821
+ filter_query, projection=projection, sort=sorting_list_of_tuples, skip=skip_items, limit=items)
686
822
 
687
- # 'skip_items' can be 0, if we ask for the first page, so we still need to cut the number of items.
688
- # In this case checking if 'items' is not None is enough.
689
- if items:
690
- collection_items = collection_items.skip(skip_items).limit(items)
823
+ # # 'skip_items' can be 0, if we ask for the first page, so we still need to cut the number of items.
824
+ # # In this case checking if 'items' is not None is enough.
825
+ # if items:
826
+ # collection_items = collection_items.skip(skip_items).limit(items)
691
827
 
692
828
  entries: list[dict] = list(collection_items)
693
829
 
@@ -708,7 +844,7 @@ def distinct(
708
844
  database: Union[str, pymongo.database.Database],
709
845
  collection_name: str,
710
846
  field_name: str,
711
- query: dict = None,
847
+ filter_query: dict = None,
712
848
  mongo_client: pymongo.MongoClient = None,
713
849
  close_client: bool = False
714
850
  ) -> list:
@@ -735,8 +871,8 @@ def distinct(
735
871
  pymongo.database.Database - the database object that will be used instead of creating a new one.
736
872
  :param collection_name: str, the name of the collection.
737
873
  :param field_name: str, the name of the field.
738
- :param query: dict, the query to search for.
739
- If None, the query will not be executed.
874
+ :param filter_query: dict, the filter query to search for.
875
+ If None, the filter query will not be executed.
740
876
  :param mongo_client: pymongo.MongoClient, the connection object.
741
877
  If None, a new connection will be created to default URI.
742
878
  :param close_client: bool, if True, the connection will be closed after the operation.
@@ -751,7 +887,7 @@ def distinct(
751
887
  db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
752
888
  collection = db[collection_name]
753
889
 
754
- distinct_values = collection.distinct(field_name, query)
890
+ distinct_values = collection.distinct(field_name, filter_query)
755
891
 
756
892
  if close_client:
757
893
  mongo_client.close()
@@ -762,7 +898,7 @@ def distinct(
762
898
  def update(
763
899
  database: Union[str, pymongo.database.Database],
764
900
  collection_name: str,
765
- query: dict,
901
+ filter_query: dict,
766
902
  update_instance: Union[dict, list[dict]],
767
903
  add_timestamp: bool = False,
768
904
  convert_mixed_lists_to_strings: bool = False,
@@ -770,16 +906,16 @@ def update(
770
906
  close_client: bool = False
771
907
  ):
772
908
  """
773
- Update one entry in a MongoDB collection by query.
909
+ Update one entry in a MongoDB collection by filter query.
774
910
  :param database: String or the database object.
775
911
  str - the name of the database. In this case the database object will be created.
776
912
  pymongo.database.Database - the database object that will be used instead of creating a new one.
777
913
  :param collection_name: str, the name of the collection.
778
- :param query: dict, the query to search for.
914
+ :param filter_query: dict, the filter query to search for.
779
915
  Example, search for all entries with column name 'name' equal to 'John':
780
- query = {'name': 'John'}
916
+ filter_query = {'name': 'John'}
781
917
  Find by Object id:
782
- query = {'_id': ObjectId('5f3e3b3b4b9f3b3b4b9f3b3b')}
918
+ filter_query = {'_id': ObjectId('5f3e3b3b4b9f3b3b4b9f3b3b')}
783
919
  :param update_instance: dict or list of dicts, the update to apply.
784
920
  If dict, the update will be applied to one entry using 'update_one'.
785
921
  If list of dicts, the update will be applied to multiple entries using 'update_many'.
@@ -814,7 +950,7 @@ def update(
814
950
 
815
951
  if convert_mixed_lists_to_strings:
816
952
  if isinstance(update_instance, dict):
817
- object_instance = dicts.convert_int_to_str_in_mixed_lists(update_instance)
953
+ update_instance = dicts.convert_int_to_str_in_mixed_lists(update_instance)
818
954
  elif isinstance(update_instance, list):
819
955
  for doc_index, doc in enumerate(update_instance):
820
956
  update_instance[doc_index] = dicts.convert_int_to_str_in_mixed_lists(doc)
@@ -829,9 +965,9 @@ def update(
829
965
 
830
966
  result = None
831
967
  if isinstance(update_instance, dict):
832
- result = collection.update_one(query, update_instance)
968
+ result = collection.update_one(filter_query, update_instance)
833
969
  elif isinstance(update_instance, list):
834
- result = collection.update_many(query, update_instance)
970
+ result = collection.update_many(filter_query, update_instance)
835
971
 
836
972
  if result.matched_count == 0:
837
973
  raise MongoDBUpdateOneError("No document found to update.")
@@ -845,7 +981,7 @@ def update(
845
981
  def replace(
846
982
  database: Union[str, pymongo.database.Database],
847
983
  collection_name: str,
848
- query: dict,
984
+ filter_query: dict,
849
985
  replacement: dict,
850
986
  add_timestamp: bool = False,
851
987
  convert_mixed_lists_to_strings: bool = False,
@@ -853,16 +989,16 @@ def replace(
853
989
  close_client: bool = False
854
990
  ):
855
991
  """
856
- Replace one entry in a MongoDB collection by query.
992
+ Replace one entry in a MongoDB collection by filter query.
857
993
  :param database: String or the database object.
858
994
  str - the name of the database. In this case the database object will be created.
859
995
  pymongo.database.Database - the database object that will be used instead of creating a new one.
860
996
  :param collection_name: str, the name of the collection.
861
- :param query: dict, the query to search for.
997
+ :param filter_query: dict, the filter query to search for.
862
998
  Example, search for all entries with column name 'name' equal to 'John':
863
- query = {'name': 'John'}
999
+ filter_query = {'name': 'John'}
864
1000
  Find by Object id:
865
- query = {'_id': ObjectId('5f3e3b3b4b9f3b3b4b9f3b3b')}
1001
+ filter_query = {'_id': ObjectId('5f3e3b3b4b9f3b3b4b9f3b3b')}
866
1002
  :param replacement: dict, the replacement to apply.
867
1003
  :param add_timestamp: bool, if True, a current time timestamp will be added to the object.
868
1004
  :param convert_mixed_lists_to_strings: bool, if True, mixed lists or tuples when entries are strings and integers,
@@ -888,7 +1024,7 @@ def replace(
888
1024
  timestamp = datetime.datetime.now()
889
1025
  replacement['timestamp'] = timestamp
890
1026
 
891
- result = collection.replace_one(query, replacement)
1027
+ result = collection.replace_one(filter_query, replacement)
892
1028
  if result.matched_count == 0:
893
1029
  raise MongoDBReplaceOneError("No document found to replace.")
894
1030
 
@@ -898,10 +1034,73 @@ def replace(
898
1034
  return result
899
1035
 
900
1036
 
1037
+ def get_all_indexes_in_collection(
1038
+ database: Union[str, pymongo.database.Database],
1039
+ collection_name: str,
1040
+ mongo_client: pymongo.MongoClient = None,
1041
+ close_client: bool = False
1042
+ ) -> dict:
1043
+ """
1044
+ Get all indexes in a MongoDB collection.
1045
+ :param database: String or the database object.
1046
+ str - the name of the database. In this case the database object will be created.
1047
+ pymongo.database.Database - the database object that will be used instead of creating a new one.
1048
+ :param collection_name: str, the name of the collection.
1049
+ :param mongo_client: pymongo.MongoClient, the connection object.
1050
+ If None, a new connection will be created to default URI.
1051
+ :param close_client: bool, if True, the connection will be closed after the operation.
1052
+
1053
+ :return: list, the list of indexes.
1054
+ """
1055
+
1056
+ if not mongo_client:
1057
+ mongo_client = connect()
1058
+ close_client = True
1059
+
1060
+ db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
1061
+ collection = db[collection_name]
1062
+
1063
+ # noinspection PyTypeChecker
1064
+ indexes: dict = collection.index_information()
1065
+
1066
+ if close_client:
1067
+ mongo_client.close()
1068
+
1069
+ return indexes
1070
+
1071
+
1072
+ def is_index_name_in_collection(
1073
+ database: Union[str, pymongo.database.Database],
1074
+ collection_name: str,
1075
+ index_name: str,
1076
+ mongo_client: pymongo.MongoClient = None,
1077
+ close_client: bool = False
1078
+ ) -> bool:
1079
+ """
1080
+ Check if an index name is in a MongoDB collection.
1081
+ :param database: String or the database object.
1082
+ str - the name of the database. In this case the database object will be created.
1083
+ pymongo.database.Database - the database object that will be used instead of creating a new one.
1084
+ :param collection_name: str, the name of the collection.
1085
+ :param index_name: str, the name of the index.
1086
+ :param mongo_client: pymongo.MongoClient, the connection object.
1087
+ If None, a new connection will be created to default URI.
1088
+ :param close_client: bool, if True, the connection will be closed after the operation.
1089
+
1090
+ :return: bool, if the index name is in the collection.
1091
+ """
1092
+
1093
+ indexes = get_all_indexes_in_collection(
1094
+ database=database, collection_name=collection_name,
1095
+ mongo_client=mongo_client, close_client=close_client)
1096
+
1097
+ return index_name in indexes
1098
+
1099
+
901
1100
  def count_entries_in_collection(
902
1101
  database: Union[str, pymongo.database.Database],
903
1102
  collection_name: str,
904
- query: dict = None,
1103
+ filter_query: dict = None,
905
1104
  mongo_client: pymongo.MongoClient = None,
906
1105
  close_client: bool = False
907
1106
  ) -> int:
@@ -912,11 +1111,11 @@ def count_entries_in_collection(
912
1111
  str - the name of the database. In this case the database object will be created.
913
1112
  pymongo.database.Database - the database object that will be used instead of creating a new one.
914
1113
  :param collection_name: str, the name of the collection.
915
- :param query: dict, the query to search for.
1114
+ :param filter_query: dict, the query to search for.
916
1115
  Example, search for all entries with column name 'name' equal to 'John':
917
- query = {'name': 'John'}
1116
+ filter_query = {'name': 'John'}
918
1117
  Example, return all entries from collection:
919
- query = None
1118
+ filter_query = None
920
1119
  :param mongo_client: pymongo.MongoClient, the connection object.
921
1120
  If None, a new connection will be created to default URI.
922
1121
  :param close_client: bool, if True, the connection will be closed after the operation.
@@ -931,10 +1130,10 @@ def count_entries_in_collection(
931
1130
  db = _get_pymongo_db_from_string_or_pymongo_db(database, mongo_client)
932
1131
  collection = db[collection_name]
933
1132
 
934
- if query is None:
935
- query = {}
1133
+ if filter_query is None:
1134
+ filter_query = {}
936
1135
 
937
- count = collection.count_documents(query)
1136
+ count = collection.count_documents(filter_query)
938
1137
 
939
1138
  if close_client:
940
1139
  mongo_client.close()
@@ -1011,7 +1210,7 @@ def overwrite_collection(
1011
1210
  mongo_client=mongo_client
1012
1211
  )
1013
1212
 
1014
- index(
1213
+ insert(
1015
1214
  object_instance=object_instance,
1016
1215
  database=database, collection_name=collection_name,
1017
1216
  add_timestamp=add_timestamp, convert_mixed_lists_to_strings=convert_mixed_lists_to_strings,
@@ -11,7 +11,8 @@ def parse_args():
11
11
  :return: Parsed arguments.
12
12
  """
13
13
  parser = argparse.ArgumentParser(description='Install PyCharm Community Edition.')
14
- parser.add_argument('--install', action='store_true', help='Install PyCharm Community Edition with snapd.')
14
+ parser.add_argument('-ic', '--install_community', action='store_true', required=True,
15
+ help='Install PyCharm Community Edition with snapd.')
15
16
  parser.add_argument('--enable_sudo_execution', action='store_true',
16
17
  help='There is a problem when trying to run snapd installed Pycharm as sudo, need to enable '
17
18
  'this.')
@@ -29,7 +30,7 @@ def install_main():
29
30
 
30
31
  args = parse_args()
31
32
 
32
- if args.install:
33
+ if args.install_community:
33
34
  process.execute_script('sudo snap install pycharm-community --classic', shell=True)
34
35
 
35
36
  if args.enable_sudo_execution:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: atomicshop
3
- Version: 2.16.40
3
+ Version: 2.16.42
4
4
  Summary: Atomic functions and classes to make developer life easier
5
5
  Author: Denis Kras
6
6
  License: MIT License
@@ -1,4 +1,4 @@
1
- atomicshop/__init__.py,sha256=TYS9D6MSyq30CdEEe2eYbOWhb54piD6vL52TzPe8dpU,124
1
+ atomicshop/__init__.py,sha256=tWZJJS59JBaRpS5l3fKPYI9YQJf0dM6cQNGppw5sjoo,124
2
2
  atomicshop/_basics_temp.py,sha256=6cu2dd6r2dLrd1BRNcVDKTHlsHs_26Gpw8QS6v32lQ0,3699
3
3
  atomicshop/_create_pdf_demo.py,sha256=Yi-PGZuMg0RKvQmLqVeLIZYadqEZwUm-4A9JxBl_vYA,3713
4
4
  atomicshop/_patch_import.py,sha256=ENp55sKVJ0e6-4lBvZnpz9PQCt3Otbur7F6aXDlyje4,6334
@@ -257,7 +257,7 @@ atomicshop/wrappers/mongodbw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NM
257
257
  atomicshop/wrappers/mongodbw/install_mongodb_ubuntu.py,sha256=pmI9AwWJ2cv5h8GionSpSJkllg6kfp0M381pk6y4Y5U,4015
258
258
  atomicshop/wrappers/mongodbw/install_mongodb_win.py,sha256=3ZPqrXxj3lC-PnAKGXclylLuOqsbyXYeUpb5iGjdeUU,6626
259
259
  atomicshop/wrappers/mongodbw/mongo_infra.py,sha256=IjEF0jPzQz866MpTm7rnksnyyWQeUT_B2h2DA9ryAio,2034
260
- atomicshop/wrappers/mongodbw/mongodbw.py,sha256=DlKiZaB__OIkWNQgQxKD569qrzm1l7m1TWKH2NTe8qs,44278
260
+ atomicshop/wrappers/mongodbw/mongodbw.py,sha256=Vxsw0lNaJxAVzQWRx_9dNQXKTIKjMyZnx9FbYbINkBk,52435
261
261
  atomicshop/wrappers/nodejsw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
262
262
  atomicshop/wrappers/nodejsw/install_nodejs.py,sha256=TKGa3jSlSqZTL2NA0nMkWDFtlkz7rxGGn44ywCg7MN8,5228
263
263
  atomicshop/wrappers/playwrightw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -280,7 +280,7 @@ atomicshop/wrappers/psutilw/processes.py,sha256=ZOkqEEF36NFeQg7G-baUUdTaV8DQe_jp
280
280
  atomicshop/wrappers/psutilw/psutilw.py,sha256=q3EwgprqyrR4zLCjl4l5DHFOQoukEvQMIPjNB504oQ0,21262
281
281
  atomicshop/wrappers/psycopgw/psycopgw.py,sha256=XJvVf0oAUjCHkrYfKeFuGCpfn0Oxj3u4SbKMKA1508E,7118
282
282
  atomicshop/wrappers/pycharmw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
283
- atomicshop/wrappers/pycharmw/ubuntu.py,sha256=l2_9SXrw7ApSvFOROGZdPZa5ylZBKofk4sYqf4IugQs,1223
283
+ atomicshop/wrappers/pycharmw/ubuntu.py,sha256=m9MpgqvIYygulhPxo9g2zlGGXrihBpiY3GNLNyT-B7U,1290
284
284
  atomicshop/wrappers/pycharmw/win.py,sha256=jdnTkUqZX_BrMW8AmW-xGtxdV-wmmNr_NMA2jB6JHsQ,2725
285
285
  atomicshop/wrappers/pywin32w/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
286
286
  atomicshop/wrappers/pywin32w/cert_store.py,sha256=bpFm5nH9j6I9eJdLjPnSvo-g4OyJO7Sb5VddzVE9-UM,3156
@@ -314,8 +314,8 @@ atomicshop/wrappers/socketw/ssl_base.py,sha256=kmiif84kMhBr5yjQW17p935sfjR5JKG0L
314
314
  atomicshop/wrappers/socketw/statistics_csv.py,sha256=w1AH-zf4mBuT4euf28UKij9ihM-b1BRU9Qfby0QDdqI,2957
315
315
  atomicshop/wrappers/winregw/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
316
316
  atomicshop/wrappers/winregw/winreg_network.py,sha256=4tIBitgT4X_y76k3T1ychRu85KNRflLfjFumSmoj7es,7138
317
- atomicshop-2.16.40.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
318
- atomicshop-2.16.40.dist-info/METADATA,sha256=NyWOjqsrP_CG0cIBGpMKCCH_m0J1VM68t3hFLoSs5TM,10473
319
- atomicshop-2.16.40.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
320
- atomicshop-2.16.40.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
321
- atomicshop-2.16.40.dist-info/RECORD,,
317
+ atomicshop-2.16.42.dist-info/LICENSE.txt,sha256=lLU7EYycfYcK2NR_1gfnhnRC8b8ccOTElACYplgZN88,1094
318
+ atomicshop-2.16.42.dist-info/METADATA,sha256=PPS3bp3ZqUTDio5PNmC2vlny1J9gavc8P4HHXhrnaQE,10473
319
+ atomicshop-2.16.42.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
320
+ atomicshop-2.16.42.dist-info/top_level.txt,sha256=EgKJB-7xcrAPeqTRF2laD_Np2gNGYkJkd4OyXqpJphA,11
321
+ atomicshop-2.16.42.dist-info/RECORD,,