1+ use crate :: log:: { Logger , Operation } ;
12use crate :: schema:: { infer_schema, Schema } ;
23use serde_json:: Value ;
34use std:: collections:: BTreeMap ;
@@ -6,36 +7,51 @@ use uuid::Uuid;
67pub struct MemTable {
78 documents : BTreeMap < String , Value > ,
89 schema : Schema ,
10+ logger : Logger ,
911}
1012
1113impl MemTable {
12- pub fn new ( ) -> Self {
14+ pub fn new ( log_path : & str ) -> Self {
15+ let logger = Logger :: new ( log_path) . unwrap ( ) ;
1316 MemTable {
1417 documents : BTreeMap :: new ( ) ,
1518 schema : Schema {
1619 types : vec ! [ ] ,
1720 properties : None ,
1821 items : None ,
1922 } ,
23+ logger,
2024 }
2125 }
2226
2327 pub fn insert ( & mut self , doc : Value ) -> String {
2428 let doc_schema = infer_schema ( & doc) ;
25- self . schema . merge ( doc_schema) ;
29+ self . schema . merge ( doc_schema. clone ( ) ) ;
2630 let id = Uuid :: now_v7 ( ) . to_string ( ) ;
27- self . documents . insert ( id. clone ( ) , doc) ;
31+ self . documents . insert ( id. clone ( ) , doc. clone ( ) ) ;
32+ self . logger
33+ . log ( Operation :: Insert { doc } )
34+ . expect ( "Failed to log insert" ) ;
2835 id
2936 }
3037
3138 pub fn delete ( & mut self , id : & str ) {
3239 self . documents . remove ( id) ;
40+ self . logger
41+ . log ( Operation :: Delete { id : id. to_string ( ) } )
42+ . expect ( "Failed to log delete" ) ;
3343 }
3444
3545 pub fn update ( & mut self , id : & str , doc : Value ) {
3646 let doc_schema = infer_schema ( & doc) ;
3747 self . schema . merge ( doc_schema) ;
38- self . documents . insert ( id. to_string ( ) , doc) ;
48+ self . documents . insert ( id. to_string ( ) , doc. clone ( ) ) ;
49+ self . logger
50+ . log ( Operation :: Update {
51+ id : id. to_string ( ) ,
52+ doc,
53+ } )
54+ . expect ( "Failed to log update" ) ;
3955 }
4056}
4157
@@ -44,10 +60,17 @@ mod tests {
4460 use super :: * ;
4561 use crate :: schema:: SchemaType ;
4662 use serde_json:: json;
63+ use tempfile:: NamedTempFile ;
64+
65+ fn create_test_memtable ( ) -> ( NamedTempFile , MemTable ) {
66+ let log_file = NamedTempFile :: new ( ) . unwrap ( ) ;
67+ let memtable = MemTable :: new ( log_file. path ( ) . to_str ( ) . unwrap ( ) ) ;
68+ ( log_file, memtable)
69+ }
4770
4871 #[ test]
4972 fn test_memtable_insert ( ) {
50- let mut memtable = MemTable :: new ( ) ;
73+ let ( _log_file , mut memtable) = create_test_memtable ( ) ;
5174 memtable. insert ( json ! ( { "a" : 1 } ) ) ;
5275 memtable. insert ( json ! ( { "b" : "hello" } ) ) ;
5376
@@ -62,7 +85,7 @@ mod tests {
6285
6386 #[ test]
6487 fn test_memtable_delete ( ) {
65- let mut memtable = MemTable :: new ( ) ;
88+ let ( _log_file , mut memtable) = create_test_memtable ( ) ;
6689 let id = memtable. insert ( json ! ( { "a" : 1 } ) ) ;
6790 assert_eq ! ( memtable. documents. len( ) , 1 ) ;
6891 memtable. delete ( & id) ;
@@ -71,7 +94,7 @@ mod tests {
7194
7295 #[ test]
7396 fn test_memtable_update ( ) {
74- let mut memtable = MemTable :: new ( ) ;
97+ let ( _log_file , mut memtable) = create_test_memtable ( ) ;
7598 let id = memtable. insert ( json ! ( { "a" : 1 } ) ) ;
7699 memtable. update ( & id, json ! ( { "b" : "hello" } ) ) ;
77100
@@ -85,4 +108,40 @@ mod tests {
85108 assert_eq ! ( props. get( "a" ) . unwrap( ) . types, vec![ SchemaType :: Integer ] ) ;
86109 assert_eq ! ( props. get( "b" ) . unwrap( ) . types, vec![ SchemaType :: String ] ) ;
87110 }
111+
112+ #[ test]
113+ fn test_log_content ( ) {
114+ let ( log_file, mut memtable) = create_test_memtable ( ) ;
115+ let doc1 = json ! ( { "a" : 1 } ) ;
116+ let id1 = memtable. insert ( doc1. clone ( ) ) ;
117+
118+ let doc2 = json ! ( { "b" : "hello" } ) ;
119+ memtable. update ( & id1, doc2. clone ( ) ) ;
120+
121+ memtable. delete ( & id1) ;
122+
123+ let log_content = std:: fs:: read_to_string ( log_file. path ( ) ) . unwrap ( ) ;
124+ let mut lines = log_content. lines ( ) ;
125+
126+ let entry1: crate :: log:: LogEntry = serde_json:: from_str ( lines. next ( ) . unwrap ( ) ) . unwrap ( ) ;
127+ match entry1. op {
128+ Operation :: Insert { doc } => assert_eq ! ( doc, doc1) ,
129+ _ => panic ! ( "Expected insert operation" ) ,
130+ }
131+
132+ let entry2: crate :: log:: LogEntry = serde_json:: from_str ( lines. next ( ) . unwrap ( ) ) . unwrap ( ) ;
133+ match entry2. op {
134+ Operation :: Update { id, doc } => {
135+ assert_eq ! ( id, id1) ;
136+ assert_eq ! ( doc, doc2) ;
137+ }
138+ _ => panic ! ( "Expected update operation" ) ,
139+ }
140+
141+ let entry3: crate :: log:: LogEntry = serde_json:: from_str ( lines. next ( ) . unwrap ( ) ) . unwrap ( ) ;
142+ match entry3. op {
143+ Operation :: Delete { id } => assert_eq ! ( id, id1) ,
144+ _ => panic ! ( "Expected delete operation" ) ,
145+ }
146+ }
88147}
0 commit comments