11from typing import List , Optional
22from pydantic import BaseModel
3+ from pathlib import Path
4+ from abc import ABC , abstractmethod
5+ import json
36
47
58class ForeignKey (BaseModel ):
@@ -20,11 +23,38 @@ class Table(BaseModel):
2023 data : List [dict ] = []
2124
2225
23- class TablesSnapshot (BaseModel ):
26+ class ITablesSnapshot (ABC ):
27+ @abstractmethod
28+ def get_table (self , name : str ) -> Optional [Table ]:
29+ raise NotImplementedError ("get_table method must be implemented" )
30+
31+
32+ class InMemoryTables (BaseModel , ITablesSnapshot ):
2433 tables : List [Table ]
2534
2635 def get_table (self , name : str ) -> Optional [Table ]:
2736 for table in self .tables :
2837 if table .name == name :
2938 return table
3039 return None
40+
41+
42+ class FileSystemTables (ITablesSnapshot ):
43+ workdir : Path
44+
45+ def __init__ (self , workdir : Path ):
46+ self .workdir = workdir
47+
48+ def get_table (self , name : str ):
49+ table_path = self .workdir / f"{ name } .json"
50+ if not table_path .exists ():
51+ raise FileNotFoundError (f"File { table_path } does not exist" )
52+ rows = json .loads (table_path .read_text ())
53+ columns = set ()
54+ for row in rows :
55+ assert isinstance (row , dict ), f"Row { row } is not a dictionary"
56+ for key , value in row .items ():
57+ if key not in columns :
58+ col = Column (name = key , type = type (value ).__name__ )
59+ columns .add (col )
60+ return Table (name = name , columns = list (columns ), data = rows )
0 commit comments