1
- import os , shutil
1
+ import os , shutil , json
2
2
from datetime import datetime
3
3
from tinydb import TinyDB , Query
4
+ from abc import ABC , abstractmethod
4
5
5
6
class CollectionDoesNotExist (Exception ):
6
7
"""Exception raised when attempting to access a collection that does not exist."""
7
8
def __init__ (self , form_name ):
8
9
message = f"The collection '{ form_name } ' does not exist."
9
10
super ().__init__ (message )
10
11
11
- class ManageTinyDB :
12
- def __init__ (self , config : dict , db_path : str = "instance/" ):
12
+ class ManageDocumentDB ( ABC ) :
13
+ def __init__ (self , config : dict ):
13
14
self .config = config
15
+
16
+ # Here we'll set metadata field names
17
+ self .is_deleted_field = "_is_deleted"
18
+ self .created_at_field = "_created_at"
19
+ self .last_modified_field = "_last_modified"
20
+ self .ip_address_field = "_ip_address"
21
+ self .created_by_field = "_created_by"
22
+ self .signature_field = "_signature"
23
+ self .last_editor_field = "_last_editor"
24
+ self .approved_field = "_approved"
25
+ self .approved_by_field = "_approved_by"
26
+ self .approval_signature_field = "_approval_signature"
27
+
28
+ # Finally we'll initialize the database instances
29
+ self ._initialize_database_collections ()
30
+
31
+ @abstractmethod
32
+ def _initialize_database_collections (self ):
33
+ """Establishes database instances / collections for each form."""
34
+ pass
35
+
36
+ @abstractmethod
37
+ def _check_form_exists (self , form_name :str ):
38
+ """Checks if the form exists in the configuration."""
39
+ pass
40
+
41
+ @abstractmethod
42
+ def create_document (self , form_name :str , json_data ):
43
+ """Adds an entry to the specified form's database."""
44
+ pass
45
+
46
+ @abstractmethod
47
+ def update_document (self , form_name :str , json_data , metadata = {}):
48
+ """Updates existing form in specified form's database."""
49
+ pass
50
+
51
+ @abstractmethod
52
+ def sign_document (self , form_name :str , json_data , metadata = {}):
53
+ """Manage signatures existing form in specified form's database."""
54
+ pass
55
+
56
+ @abstractmethod
57
+ def approve_document (self , form_name :str , json_data , metadata = {}):
58
+ """Manage approval for existing form in specified form's database."""
59
+ pass
60
+
61
+ @abstractmethod
62
+ def search_documents (self , form_name :str , search_query , exclude_deleted = True ):
63
+ """Searches for entries that match the search query."""
64
+ pass
65
+
66
+ @abstractmethod
67
+ def delete_document (self , form_name :str , search_query , permanent :bool = False ):
68
+ """Deletes entries that match the search query, permanently or soft delete."""
69
+ pass
70
+
71
+ @abstractmethod
72
+ def get_all_documents (self , form_name :str , exclude_deleted = True ):
73
+ """Retrieves all entries from the specified form's database."""
74
+ pass
75
+
76
+ @abstractmethod
77
+ def get_one_document (self , form_name :str , search_query , exclude_deleted = True ):
78
+ """Retrieves a single entry that matches the search query."""
79
+ pass
80
+
81
+ @abstractmethod
82
+ def restore_document (self , form_name :str , search_query ):
83
+ """Restores soft deleted entries that match the search query."""
84
+ pass
85
+
86
+ @abstractmethod
87
+ def backup_database (self , form_name :str ):
88
+ """Creates a backup of the specified form's database."""
89
+ pass
90
+
91
+ @abstractmethod
92
+ def restore_database_from_backup (self , form_name :str , backup_filename :str , backup_before_overwriting :bool = True ):
93
+ """Restores the specified form's database from its backup."""
94
+ pass
95
+
96
+
97
+ class ManageTinyDB (ManageDocumentDB ):
98
+ def __init__ (self , config : dict , db_path : str = "instance/" ):
14
99
self .db_path = db_path
15
100
os .makedirs (self .db_path , exist_ok = True )
16
101
102
+ super ().__init__ (config )
17
103
18
104
# Here we create a Query object to ship with the class
19
105
self .Form = Query ()
20
106
21
- # Here we'll set metadata field names
22
- self .is_deleted_field = "_is_deleted"
23
-
24
- # Finally we'll initialize the database instances
25
- self ._initialize_database_instances ()
26
107
27
- def _initialize_database_instances (self ):
108
+ def _initialize_database_collections (self ):
28
109
"""Establishes database instances for each form."""
29
110
# Initialize databases
30
111
self .databases = {}
@@ -35,26 +116,60 @@ def _get_db_path(self, form_name:str):
35
116
"""Constructs a file path for the given form's database."""
36
117
return os .path .join (self .db_path , f"{ form_name } .json" )
37
118
38
- def _check_form_exists (self , form_name ):
119
+ def _check_form_exists (self , form_name : str ):
39
120
"""Checks if the form exists in the configuration."""
40
121
if form_name not in self .config :
41
122
raise CollectionDoesNotExist (form_name )
42
123
43
- def add_entry (self , form_name :str , entry ):
44
- """Adds an entry to the specified form's database."""
124
+ def create_document (self , form_name :str , json_data , metadata = {} ):
125
+ """Adds json data to the specified form's database."""
45
126
self ._check_form_exists (form_name )
46
- document_id = self .databases [form_name ].insert (entry )
127
+
128
+ current_timestamp = datetime .now ()
129
+
130
+ # data_dict = json.loads(json_data)
131
+ data_dict = {
132
+ "data" : json_data ,
133
+ "metadata" : {
134
+ self .is_deleted_field : metadata .get (self .is_deleted_field , False ),
135
+ self .created_at_field : metadata .get (self .created_at_field , current_timestamp .isoformat ()),
136
+ self .last_modified_field : metadata .get (self .last_modified_field , current_timestamp .isoformat ()),
137
+ self .ip_address_field : metadata .get (self .ip_address_field , None ),
138
+ self .created_by_field : metadata .get (self .created_by_field , None ),
139
+ self .signature_field : metadata .get (self .signature_field , None ),
140
+ self .last_editor_field : metadata .get (self .last_editor_field , None ),
141
+ self .approved_field : metadata .get (self .approved_field , None ),
142
+ self .approved_by_field : metadata .get (self .approved_by_field , None ),
143
+ self .approval_signature_field : metadata .get (self .approval_signature_field , None ),
144
+ }
145
+ }
146
+
147
+ document_id = self .databases [form_name ].insert (data_dict )
47
148
48
149
return document_id
49
150
50
- def search_entries (self , form_name :str , search_query , exclude_deleted = True ):
151
+ def update_document (self , form_name :str , json_data , metadata = {}):
152
+ """Updates existing form in specified form's database."""
153
+ pass
154
+
155
+ def sign_document (self , form_name :str , json_data , metadata = {}):
156
+ """Manage signatures existing form in specified form's database."""
157
+ pass
158
+
159
+
160
+ def approve_document (self , form_name :str , json_data , metadata = {}):
161
+ """Manage approval for existing form in specified form's database."""
162
+ pass
163
+
164
+
165
+ def search_documents (self , form_name :str , search_query , exclude_deleted = True ):
51
166
"""Searches for entries that match the search query."""
52
167
self ._check_form_exists (form_name )
53
168
if exclude_deleted :
54
169
search_query &= Query ()[self .is_deleted_field ] == False
55
170
return self .databases [form_name ].search (search_query )
56
171
57
- def delete_entry (self , form_name :str , search_query , permanent = False ):
172
+ def delete_document (self , form_name :str , search_query , permanent : bool = False ):
58
173
"""Deletes entries that match the search query, permanently or soft delete."""
59
174
self ._check_form_exists (form_name )
60
175
if permanent :
@@ -64,22 +179,22 @@ def delete_entry(self, form_name:str, search_query, permanent=False):
64
179
for doc_id in [d .doc_id for d in self .databases [form_name ].search (search_query )]:
65
180
self .databases [form_name ].update ({self .is_deleted_field : True }, doc_ids = [doc_id ])
66
181
67
- def get_all_entries (self , form_name :str , exclude_deleted = True ):
182
+ def get_all_documents (self , form_name :str , exclude_deleted = True ):
68
183
"""Retrieves all entries from the specified form's database."""
69
184
self ._check_form_exists (form_name )
70
185
if exclude_deleted :
71
186
return self .databases [form_name ].search (Query ()[self .is_deleted_field ] == False )
72
187
else :
73
188
return self .databases [form_name ].all ()
74
189
75
- def get_one_entry (self , form_name :str , search_query , exclude_deleted = True ):
190
+ def get_one_document (self , form_name :str , search_query , exclude_deleted = True ):
76
191
"""Retrieves a single entry that matches the search query."""
77
192
self ._check_form_exists (form_name )
78
193
if exclude_deleted :
79
194
search_query &= Query ()[self .is_deleted_field ] == False
80
195
return self .databases [form_name ].get (search_query )
81
196
82
- def restore_entry (self , form_name :str , search_query ):
197
+ def restore_document (self , form_name :str , search_query ):
83
198
"""Restores soft deleted entries that match the search query."""
84
199
self ._check_form_exists (form_name )
85
200
for doc_id in [d .doc_id for d in self .databases [form_name ].search (search_query )]:
@@ -120,7 +235,7 @@ def restore_database_from_backup(self, form_name:str, backup_filename:str, backu
120
235
raise FileNotFoundError ("Backup file does not exist." )
121
236
122
237
# Reinitialize the databse instances
123
- self ._initialize_database_instances ()
238
+ self ._initialize_database_collections ()
124
239
125
- class ManageMongoDB :
240
+ class ManageMongoDB ( ManageDocumentDB ) :
126
241
pass
0 commit comments