11import json
22from typing import Mapping , List
33
4- from .document import Document
4+ from .document import Document , JsonArray
55from .fileio import FileIO
66
77
1414
1515
1616class Collection :
17- def __init__ (self , col_name : str , binary_file : FileIO ) -> None :
17+ def __init__ (self , col_name : str , file_handler : FileIO ) -> None :
1818 self ._col_name = col_name
19- self ._binary_file = binary_file
19+ self ._file_handler = file_handler
2020
2121 # Get the data of existing Database or empty database.
22- self ._database = self ._binary_file . read ()
22+ self ._database = self ._get_database ()
2323
24- self ._cursor : int = 0
25-
26- # Initiate a default Collection.
27- # Check the Collection is already exists or no.
28- if self ._col_name in self ._database .keys ():
24+ # Initiating Collecting
25+ self ._collection : JsonArray = self ._get_collection ()
2926
30- # Get the existing Collection
31- self ._collection : list = self ._database [self ._col_name ]
32-
33- else :
34- # Create new Collection
35- self ._database [self ._col_name ] = []
36- self ._collection : list = self ._database [self ._col_name ]
27+ # Cursor
28+ self ._cursor : int = 0
3729
3830 def insert (self , document : Mapping ) -> str :
3931 """
4032 Inserts a single Document into the Database.
4133
4234 Document should be JSON Object.
4335
44- :param document: Document to insert into database
45- :return: None
36+ :param document: Document to insert into the database.
37+ :return: Document ID.
4638 """
39+
4740 # Make sure the document implements the ``Mapping`` interface
4841 if not isinstance (document , Mapping ):
4942 raise ValueError ('Document is not a Dictionary' )
@@ -52,30 +45,33 @@ def insert(self, document: Mapping) -> str:
5245 if "_id_" in document .keys ():
5346 raise KeyError (f"You are not allowed to modify key `_id_`" )
5447
48+ # getting Database
49+ _database = self ._get_database ()
50+
5551 # Create a Document
5652 _document = Document (document )
5753
58- # id of Document
59- _doc_id : str = _document .id
54+ # ID of Document
55+ _doc_id : str = str ( _document .id )
6056
6157 # check Document is already exist or not
62- if not self ._doc_is_exists (_document .id ):
58+ if not self ._doc_is_exists (str ( _document .id ) ):
6359
6460 # Append the document into the Collection
6561 self ._collection .append (_document )
6662
6763 # Add modified Collection to Database
68- self . _database [self ._col_name ] = self ._collection
64+ _database [self ._col_name ] = self ._collection
6965
7066 # print(self._database)
7167 # Write current state of Database into the Database-file
72- self ._binary_file .write (self . _database )
68+ self ._file_handler .write (_database )
7369
7470 return _doc_id
7571 else :
7672 raise ValueError (f"Document id `{ _document .id } ` is already exists" )
7773
78- def insert_all (self , document_list : List [Mapping ]) -> List [ str ] :
74+ def insert_all (self , document_list : List [Mapping ]) -> JsonArray :
7975 """
8076 Inserts a single ``Document`` into the ``Database``.
8177
@@ -97,43 +93,9 @@ def insert_all(self, document_list: List[Mapping]) -> List[str]:
9793 # insert every single document in Database & increment ``doc_count``.
9894 _doc_id .append (self .insert (document ))
9995
100- return _doc_id
101-
102- """ FIND_ONE
103- def __find_one(self, query: Mapping = None) -> Document | None:
104- "
105- Finds a single ``Document`` of ``Collection``.
106-
107- If ``query`` is None then returns all the ``Documents`` of ``Collection``.
108-
109- If ``query`` is not None then returns only the first occurrence.
96+ return JsonArray (_doc_id )
11097
111- :param query: Condition to search Document
112- :return: Document
113- "
114- # Default result
115- _result = {}
116-
117- # Make sure the query implements the ``Mapping`` interface.
118- if not isinstance(query, Mapping | None):
119- raise ValueError('Document is not a Dictionary')
120-
121-
122-
123- # Check if has ``query`` or not
124- if query is None:
125- _result = self._collection[self._cursor]
126- self._reset_cursor()
127- else:
128- print(self._cursor)
129- _result = self._find_document_by_query(query)
130- self._reset_cursor()
131- _result = _result[self._cursor]
132-
133- return _result
134- """
135-
136- def find (self , query = None , limit = None ) -> List [Document ]:
98+ def find (self , query = None , limit = None ) -> JsonArray :
13799 """
138100 Finds all ``Document`` of ``Collection``.
139101
@@ -160,7 +122,7 @@ def find(self, query=None, limit=None) -> List[Document]:
160122 raise ValueError ('Document is not a Tuple' )
161123
162124 # if limit, Check everything ok
163- _limit_start = _limit_end = None
125+ _limit_start = _limit_end = 0
164126
165127 if limit and type (limit ) == type ((1 , 3 )):
166128 if len (limit ) == 2 :
@@ -189,7 +151,7 @@ def find(self, query=None, limit=None) -> List[Document]:
189151 else :
190152 _result = self ._collection
191153
192- return _result
154+ return JsonArray ( _result )
193155
194156 elif query is not None and type (query ) == type ({}):
195157 if limit :
@@ -208,7 +170,7 @@ def find(self, query=None, limit=None) -> List[Document]:
208170 self ._reset_cursor ()
209171
210172 # check if lower limit is valid or not
211- if _limit_start >= len (_result ):
173+ if _limit_start >= len (_result ) and _limit_start != 0 :
212174 raise ValueError (f"lower limit should be smaller than length of result" )
213175 else :
214176 # Travers limited result
@@ -225,9 +187,9 @@ def find(self, query=None, limit=None) -> List[Document]:
225187
226188 self ._reset_cursor ()
227189
228- return _result
190+ return JsonArray ( _result )
229191
230- def delete (self , query = None ) -> List [ str ] :
192+ def delete (self , query = None ) -> JsonArray :
231193 """
232194 Delete single or multiple Document when meet the Conditions or ``query``.
233195
@@ -248,11 +210,11 @@ def delete(self, query=None) -> List[str]:
248210 self ._collection .remove (_doc )
249211 _doc_id .append (_doc ["_id_" ])
250212
251- self ._binary_file .write (self ._database )
213+ self ._file_handler .write (self ._database )
252214
253- return _doc_id
215+ return JsonArray ( _doc_id )
254216
255- def update (self , document : Mapping , query = None ) -> List [ str ] :
217+ def update (self , document : Mapping , query = None ) -> JsonArray :
256218 """
257219 Fetch all the Documents mathc the conditions and update them.
258220
@@ -284,30 +246,105 @@ def update(self, document: Mapping, query=None) -> List[str]:
284246 _doc_id .append (_doc ["_id_" ])
285247
286248 # Write current state of Database
287- self ._binary_file .write (self ._database )
249+ self ._file_handler .write (self ._database )
288250
289- return _doc_id
251+ return JsonArray ( _doc_id )
290252
291- def count (self , query = None , limit : tuple = None ) -> int :
253+ def rename (self , new_name : str ) -> int :
292254 """
293- Return amount of Document found.
255+ This method used to change the name of collection.
256+ Takes current name & new name to change name of the collection.
294257
295- :param query: Condition to search Document.
296- :param limit: If there is any limit.
297- :return: (int) amount of Document found.
258+ :param new_name: New name for collection.
259+ :return: Amount of affected collection.
298260 """
299- count = len (self .find (query = query , limit = limit ))
261+
262+ # Initiating counter
263+ count = 0
264+
265+ # Checking the collection is already exist or not
266+ if new_name not in self ._database .keys ():
267+ # Creating new collection and
268+ # Putting old data into new collection
269+ self ._database [new_name ] = self ._collection
270+
271+ # Writing Current database status into the file
272+ self ._file_handler .write (self ._database )
273+
274+ # Remove old collection
275+ self .drop ()
276+
277+ # Increasing counter
278+ count += 1
279+
280+ return count
281+
282+ def drop (self ) -> int :
283+ """
284+ Deletes the selected collection from the database
285+
286+ :return: Amount of affected collection
287+ """
288+
289+ # Initiating counter
290+ count = 0
291+
292+ # Getting database
293+ _database = self ._file_handler .read ()
294+
295+ # Check database has the collection or not
296+ if self ._col_name in _database .keys ():
297+ # Removing collection from database
298+ _database .pop (self ._col_name )
299+
300+ # Writing current status of database into the file system.
301+ self ._file_handler .write (_database )
302+
303+ # Increasing counter
304+ count += 1
300305
301306 return count
302307
308+ # ----------------------------------------------------------------#
309+ def _get_database (self ) -> Document :
310+ """
311+ Getting Database
312+
313+ :return: Database
314+ """
315+ # Get the data of existing Database or empty database.
316+ database = Document (self ._file_handler .read (), False )
317+
318+ return database
319+
320+ def _get_collection (self ) -> JsonArray :
321+ """
322+ Getting Collection
323+
324+ :return: Collection
325+ """
326+ # Initiate a default Collection.
327+ # Check the Collection is already exists or no.
328+ if self ._col_name in self ._database .keys ():
329+
330+ # Get the existing Collection
331+ _collection : JsonArray = self ._database [self ._col_name ]
332+
333+ else :
334+ # Create new Collection
335+ self ._database [self ._col_name ] = JsonArray ([])
336+ _collection = self ._database [self ._col_name ]
337+
338+ return JsonArray (_collection )
339+
303340 def _reset_cursor (self ) -> None :
304341 """
305342 Reset Cursor Pointer to 0th index
306343 :return: None
307344 """
308345 self ._cursor = 0
309346
310- def _find_document_by_query (self , query : Mapping ) -> List :
347+ def _find_document_by_query (self , query : Mapping ) -> JsonArray | None :
311348 """
312349 Finds a single ``Document`` of ``Collection``.
313350
@@ -371,20 +408,12 @@ def _find_document_by_query(self, query: Mapping) -> List:
371408 else :
372409 return None
373410
374- return result
411+ return JsonArray ( result )
375412
376- # ======================== #
377413 def _doc_is_exists (self , doc_id : str ) -> bool :
378414 # Iterate over all Documents of Collection
379415 for doc in self ._collection :
380416 if doc ["_id_" ] == doc_id :
381417 return True
382418
383419 return False
384-
385- def _find_document_by_id (self , doc_id ) -> Document :
386- for doc in self ._collection :
387- if doc ["_id_" ] == doc_id :
388- return doc
389- else :
390- return None
0 commit comments