@@ -6,11 +6,13 @@ use serde::{Deserialize, Serialize};
66use std:: collections:: HashMap ;
77use std:: fs:: File ;
88use std:: io:: { BufReader , BufWriter , Write } ;
9+ use std:: path:: Path ;
910
1011#[ derive( Serialize , Deserialize , Debug , Default ) ]
1112pub struct RDatabaseMetadata {
1213 tables : Vec < RTableMetadata > ,
1314 tables_hashmap : HashMap < String , usize > ,
15+ db_filepath : Option < String > ,
1416}
1517
1618#[ pyclass]
@@ -19,6 +21,8 @@ pub struct RDatabase {
1921 tables : Vec < RTable > ,
2022 // Map table names to index on the tables: Vec<RTable>
2123 tables_hashmap : HashMap < String , usize > ,
24+
25+ db_filepath : Option < String > ,
2226}
2327
2428#[ pymethods]
@@ -28,39 +32,67 @@ impl RDatabase {
2832 RDatabase {
2933 tables : vec ! [ ] ,
3034 tables_hashmap : HashMap :: new ( ) ,
35+ db_filepath : None ,
3136 }
3237 }
3338
34- fn open ( & mut self , _path : String ) {
35- // TODO: Read the metadata of the database
36- let db_meta = RDatabaseMetadata :: default ( ) ;
39+ fn open ( & mut self , path : String ) {
40+ if self . db_filepath . is_none ( ) {
41+ self . db_filepath = Some ( path. clone ( ) ) ;
42+ }
43+
44+ if let Some ( p) = & self . db_filepath {
45+ if !Path :: new ( & p) . exists ( ) {
46+ // The database has not been closed yet
47+ // Assuming the users makes sure to close the database before they want to open it
48+ // again, we don't have to do anything else. We can just exit. The rest of the function
49+ // only needs to load up the database if something exists to load up
50+ return ;
51+ }
52+ }
53+
54+ // Read the metadata of the database
55+ let file = BufReader :: new ( File :: open ( path) . expect ( "Should open file." ) ) ;
56+ let db_meta: RDatabaseMetadata =
57+ bincode:: deserialize_from ( file) . expect ( "Should deserialize." ) ;
3758
3859 // Load each table metadata into this current databases' tables
60+ let mut index = 0 ;
3961 for table in & db_meta. tables {
4062 self . tables . push ( table. load_state ( ) ) ;
63+ self . tables_hashmap . insert ( table. name . clone ( ) , index) ;
64+ index += 1 ;
4165 }
4266 }
4367
4468 fn close ( & self ) {
45- // TODO: Save the metadata of the database
46-
47- let hardcoded_filename = "./database.data" ;
48-
49- let database_meta = RDatabaseMetadata {
69+ let mut database_meta = RDatabaseMetadata {
5070 tables : Vec :: < RTableMetadata > :: new ( ) ,
5171 tables_hashmap : self . tables_hashmap . clone ( ) ,
72+ db_filepath : self . db_filepath . clone ( ) ,
5273 } ;
5374
5475 for table in & self . tables {
55- // TODO: Get the metadata for each table
56- // TODO: Push it to database_meta.tables
57- table. save_state ( )
76+ // Get the metadata for each table
77+ let tm: RTableMetadata = table. get_metadata ( ) ;
78+ // Push it to database_meta.tables
79+ database_meta. tables . push ( tm) ;
80+
81+ // Save the table to disk
82+ table. save_state ( ) ;
5883 }
5984
6085 let table_bytes: Vec < u8 > = bincode:: serialize ( & database_meta) . expect ( "Should serialize." ) ;
6186
62- let mut file = BufWriter :: new ( File :: create ( hardcoded_filename) . expect ( "Should open file." ) ) ;
63- file. write_all ( & table_bytes) . expect ( "Should serialize." ) ;
87+ match & self . db_filepath {
88+ Some ( p) => {
89+ let mut file = BufWriter :: new ( File :: create ( p) . expect ( "Should open file." ) ) ;
90+ file. write_all ( & table_bytes) . expect ( "Should serialize." ) ;
91+ }
92+ None => {
93+ panic ! ( "Could no write!" ) /* Quietly fail to write to disk */
94+ }
95+ }
6496 }
6597
6698 pub fn create_table (
0 commit comments