erioon 0.0.7__py3-none-any.whl → 0.0.9__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.
erioon/update.py ADDED
@@ -0,0 +1,123 @@
1
+ import msgpack
2
+ from azure.storage.blob import ContainerClient
3
+ from erioon.functions import async_log
4
+
5
+
6
+ def handle_update_query(user_id, db_id, coll_id, filter_query, update_query, container_url):
7
+ """
8
+ Updates a single record in a collection stored in Blob Storage based on a filter condition,
9
+ applying one of the supported update operations, and logs the result asynchronously.
10
+
11
+ Supported operations in `update_query`:
12
+ - "$set": Overwrites the value at the specified (possibly nested) key.
13
+ - "$push": Appends a value to a list at the specified key, or initializes the list if it doesn't exist.
14
+ - "$remove": Deletes the specified key from the record.
15
+
16
+ Parameters:
17
+ - user_id (str): Identifier of the user making the update request.
18
+ - db_id (str): Database identifier (used as a directory prefix).
19
+ - coll_id (str): Collection identifier (used as a subdirectory under the database).
20
+ - filter_query (dict): Key-value pairs that must match exactly in the record for it to be updated.
21
+ - update_query (dict): Update operations to apply, using one of the supported operators ($set, $push, $remove).
22
+ - container_url (str): URL of the Blob Storage container where the data is stored.
23
+
24
+ Behavior:
25
+ - Iterates through all shard blobs in the target collection folder.
26
+ - Loads and unpacks each blob's data as a list of records.
27
+ - Finds the first record that matches all key-value pairs in `filter_query`.
28
+ - Applies the specified update operation(s) to the matched record:
29
+ - Dot notation (e.g., "user.name") is supported for nested updates.
30
+ - Re-serializes the modified records and overwrites the original blob.
31
+ - Stops processing after the first successful match and update.
32
+
33
+ Returns:
34
+ - tuple(dict, int): A tuple containing:
35
+ - A dictionary with either:
36
+ - "success": Confirmation message if update succeeded.
37
+ - "error": Error message if update failed.
38
+ - HTTP status code:
39
+ - 200 if a matching record is updated successfully.
40
+ - 404 if no collections or matching records are found.
41
+ - No 500s are explicitly returned; internal exceptions are silently caught.
42
+ """
43
+ container_client = ContainerClient.from_container_url(container_url)
44
+ directory_path = f"{db_id}/{coll_id}/"
45
+
46
+ blob_list = container_client.list_blobs(name_starts_with=directory_path)
47
+ blob_names = [blob.name for blob in blob_list if blob.name.endswith(".msgpack")]
48
+
49
+ if not blob_names:
50
+ async_log(user_id, db_id, coll_id, "PATCH_UPDT", "ERROR",
51
+ f"No collections found for the database {db_id}", 1, container_url)
52
+ return {"error": f"No collections found for the database {db_id}"}, 404
53
+
54
+ updated = False
55
+
56
+ for blob_name in blob_names:
57
+ try:
58
+ blob_client = container_client.get_blob_client(blob_name)
59
+ msgpack_data = blob_client.download_blob().readall()
60
+
61
+ if not msgpack_data:
62
+ continue
63
+
64
+ data_records = msgpack.unpackb(msgpack_data, raw=False)
65
+ modified_records = []
66
+ local_updated = False
67
+
68
+ for record in data_records:
69
+ match_found = all(record.get(k) == v for k, v in filter_query.items())
70
+
71
+ if match_found:
72
+ for op, changes in update_query.items():
73
+ if op == "$set":
74
+ for key, new_value in changes.items():
75
+ keys = key.split(".")
76
+ nested_obj = record
77
+ for k in keys[:-1]:
78
+ nested_obj = nested_obj.setdefault(k, {})
79
+ nested_obj[keys[-1]] = new_value
80
+
81
+ elif op == "$push":
82
+ for key, new_value in changes.items():
83
+ keys = key.split(".")
84
+ nested_obj = record
85
+ for k in keys[:-1]:
86
+ nested_obj = nested_obj.setdefault(k, {})
87
+ last_key = keys[-1]
88
+ if last_key not in nested_obj:
89
+ nested_obj[last_key] = [new_value]
90
+ elif isinstance(nested_obj[last_key], list):
91
+ nested_obj[last_key].append(new_value)
92
+ else:
93
+ nested_obj[last_key] = [nested_obj[last_key], new_value]
94
+
95
+ elif op == "$remove":
96
+ for key in changes:
97
+ keys = key.split(".")
98
+ nested_obj = record
99
+ for k in keys[:-1]:
100
+ nested_obj = nested_obj.get(k, {})
101
+ last_key = keys[-1]
102
+ if isinstance(nested_obj, dict) and last_key in nested_obj:
103
+ del nested_obj[last_key]
104
+
105
+ updated = True
106
+ local_updated = True
107
+
108
+ modified_records.append(record)
109
+
110
+ if local_updated:
111
+ packed_data = msgpack.packb(modified_records, use_bin_type=True)
112
+ blob_client.upload_blob(packed_data, overwrite=True)
113
+ async_log(user_id, db_id, coll_id, "PATCH_UPDT", "SUCCESS",
114
+ "Record updated successfully", len(modified_records), container_url)
115
+ return {"success": "Record updated successfully"}, 200
116
+
117
+ except Exception:
118
+ continue
119
+
120
+ if not updated:
121
+ async_log(user_id, db_id, coll_id, "PATCH_UPDT", "ERROR",
122
+ "No matching record found", 1, container_url)
123
+ return {"error": "No matching record found"}, 404
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: erioon
3
- Version: 0.0.7
3
+ Version: 0.0.9
4
4
  Summary: Erioon SDF for Python
5
5
  Author: Zyber Pireci
6
6
  Author-email: zyber.pireci@erioon.com
@@ -0,0 +1,15 @@
1
+ erioon/auth.py,sha256=McktLrdxsWVyxhiFuk0qFokx63RI1yB8_qP3Mo7uZCI,724
2
+ erioon/client.py,sha256=XUdktzV35uPq5dNAMXNN_1h3dva60p_qgJa-HOpzEOQ,6928
3
+ erioon/collection.py,sha256=XEhrffW-1hz9y26C533bzzlgXq3M1j36yyPBl13oz1I,9623
4
+ erioon/create.py,sha256=ilx0e3urK0lfYiaM3CSUe3Bf3l7GhHuwZyz0Z6ij0ok,10202
5
+ erioon/database.py,sha256=hj5sgaEDXmItg4aeZlO3MP6_hV3jeS-d9qycEnw7xHQ,2449
6
+ erioon/delete.py,sha256=09fbO-0HKjSvTFqyGz5Oy8osz1EtniXVGI71sMCHNSs,10770
7
+ erioon/functions.py,sha256=LWrqslAok-l9QlMEynT-Pvksy5hwkogWoeK5rJf464A,12479
8
+ erioon/ping.py,sha256=BC0vZiane5YgCc07syZA5dKFcqbq1_Z8BUTmvIGRPcs,1829
9
+ erioon/read.py,sha256=kzzqqRuLtYmlniAnkd2xeWNZm4AwMQ2oAMcpKt6JhcQ,10580
10
+ erioon/update.py,sha256=E3d-dYJWh12bcAHx_vT9NFTscF__hViY3K9ZssN7At4,6060
11
+ erioon-0.0.9.dist-info/LICENSE,sha256=xwnq3DNlZpQyteOK9HvtHRhMdYviXTTaCDljEodFRnQ,569
12
+ erioon-0.0.9.dist-info/METADATA,sha256=UtQc63Q51tmnSCfANjY2mALMxGv24aPABP9bDp7EPhU,715
13
+ erioon-0.0.9.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
14
+ erioon-0.0.9.dist-info/top_level.txt,sha256=yjKEg85X5Q5ot46IMML_xukvIGG5YfdrLWcemjalItc,7
15
+ erioon-0.0.9.dist-info/RECORD,,
@@ -1,9 +0,0 @@
1
- erioon/auth.py,sha256=zSMRnkoU2-5khZNYhcWb48PtYTbtYYbAI--ydrFeMbo,714
2
- erioon/client.py,sha256=AURUVA6pkTZf2NfK0oA9oL6t6f5ULGHqJe7tcRVOhmQ,6759
3
- erioon/collection.py,sha256=xCeFaJ9mN6lC65M0H2k1_9Z5KLqyJrQaU597eGOujIs,7624
4
- erioon/database.py,sha256=IjtZYJtQ-8shojxYwNKnN1ZaRwwWZfOhw3PDAgapE8w,1185
5
- erioon-0.0.7.dist-info/LICENSE,sha256=xwnq3DNlZpQyteOK9HvtHRhMdYviXTTaCDljEodFRnQ,569
6
- erioon-0.0.7.dist-info/METADATA,sha256=nK9brNhMQtYryCckTebzGlbCYZoelfoqRW-EWfZHlcg,715
7
- erioon-0.0.7.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
8
- erioon-0.0.7.dist-info/top_level.txt,sha256=yjKEg85X5Q5ot46IMML_xukvIGG5YfdrLWcemjalItc,7
9
- erioon-0.0.7.dist-info/RECORD,,
File without changes