@@ -71,7 +71,7 @@ def write(self, data: dict):
7171
7272
7373class BinaryFileIO (FileIO ):
74- def __init__ (self , db_name : str , data_dir : str = None ):
74+ def __init__ (self , db_name : str , data_dir = None ):
7575 """
7676 Create a new instance.
7777
@@ -87,7 +87,7 @@ def __init__(self, db_name: str, data_dir: str = None):
8787
8888 self ._data_dir = data_dir
8989
90- # Adding ``FileXdb`` specific file extention to the Database-file.
90+ # Adding ``FileXdb`` specific file extension to the Database-file.
9191 self ._db_name = f"{ db_name } .fxdb"
9292
9393 # Setting default Database-file path.
@@ -132,7 +132,7 @@ def read(self) -> dict:
132132 raise IOError (f"Cannot read file.\n \t `{ self ._db_name } ` is not a database" )
133133
134134 else :
135- # Returns an empty dict as
135+ # Initiate an empty dict as
136136 database = {}
137137
138138 return database
@@ -167,12 +167,85 @@ def write(self, data: dict) -> None:
167167
168168
169169class JsonFileIO (FileIO ):
170- def __init__ (self , db_name ):
170+ def __init__ (self , db_name :str , data_dir = None ):
171+
171172 super ().__init__ ()
172- self .db_name = db_name
173+
174+ self ._data_dir = data_dir
175+
176+ # Adding ``JSON`` file extension to the Database-file.
177+ self ._db_name = f"{ db_name } .json"
178+
179+ # Setting default Database-file path.
180+ self ._db_file_path = self ._db_name
181+
182+ # Checking if Data Directory is on root or not.
183+ if self ._data_dir is not None :
184+ # Creating Database-file full path by joining data_dir & db_name.
185+ self ._db_file_path = os .path .join (self ._data_dir , self ._db_name )
186+
187+ # Create the Database/File if it doesn't exist
188+ create_db (self ._db_name , self ._data_dir )
173189
174190 def read (self ) -> dict :
175- pass
191+ """
192+ Reads existing Database-file, either it is empty or non-empty.
193+
194+ If empty returns an empty dict, else returns saved Data.
195+
196+ :return: Database as a python Dictionary.
197+ """
198+ database = None
199+
200+ with open (self ._db_file_path , "r" ) as file :
201+
202+ # Get the file size by moving the cursor to the file end and reading its location.
203+ file .seek (0 , os .SEEK_END )
204+ size = file .tell ()
205+
206+ # check if size of file is 0
207+ if size :
208+ # Bring the cursor to the beginning of Database-file
209+ file .seek (0 )
210+
211+ try :
212+ # Load whole Database form Database-file
213+ database = json .load (file )
214+
215+ except io .UnsupportedOperation :
216+ # Through an Unsupported Operation Error.
217+ raise IOError (f"Cannot read file.\n \t `{ self ._db_name } ` is not a database" )
218+
219+ else :
220+ # Initiate an empty dict as
221+ database = {}
222+
223+ return database
176224
177225 def write (self , data : dict ):
178- pass
226+ """
227+ Write the current state of entire Database to the Database-file.
228+
229+ :param data: Dictionary object to write on Database.
230+ :return: None.
231+ """
232+ with open (self ._db_file_path , "w" ) as file :
233+
234+ # Move the cursor to the beginning of the file just in case.
235+ file .seek (0 )
236+
237+ # Serialize the database state using the user-provided arguments
238+ serialized = json .dumps (data , indent = 4 )
239+
240+ # Write the serialized data to the file
241+ try :
242+ file .write (serialized )
243+ except io .UnsupportedOperation :
244+ raise IOError (f"Cannot write to the file.\n \t `{ self ._db_name } ` is not a database" )
245+
246+ # Ensure the file has been written
247+ file .flush ()
248+ os .fsync (file .fileno ())
249+
250+ # Remove data that is behind the new cursor if the file has gotten shorter.
251+ file .truncate ()
0 commit comments