diff --git a/samudra/conf/database/core.py b/samudra/conf/database/core.py index 83bfc93..9eb2466 100644 --- a/samudra/conf/database/core.py +++ b/samudra/conf/database/core.py @@ -7,21 +7,20 @@ import peewee as pw +from conf.local import get_database_info +from conf.setup import settings from samudra.conf.database.options import DatabaseEngine -from samudra.conf.setup import settings # TODO: Enforce requirements per database engine # As settings -# ENGINE = settings.get("database").get("engine", None) +ENGINE = settings.get("database").get("engine", None) # DATABASE_NAME = settings.get("database").get("name", "samudra") db_state_default = {"closed": None, "conn": None, "ctx": None, "transactions": None} db_state = ContextVar("db_state", default=db_state_default.copy()) -# ! Cannot set this func as a @property of class Database -# ! so we separate as its own function and call it as an attribute of the class def get_database(db_name: str, engine: DatabaseEngine, **kwargs) -> pw.Database: """ Returns the connection class based on the engine. @@ -33,7 +32,9 @@ def get_database(db_name: str, engine: DatabaseEngine, **kwargs) -> pw.Database: ) ) if engine == DatabaseEngine.SQLite: - return create_sqlite(folder=db_name, path=kwargs.pop("path"), **kwargs) + return get_sqlite( + folder=db_name, path=kwargs.pop("path"), new=kwargs.pop("new"), **kwargs + ) DATABASE_HOST = os.getenv("DATABASE_HOST") DATABASE_PORT = int(os.getenv("DATABASE_PORT")) @@ -57,7 +58,7 @@ def get_database(db_name: str, engine: DatabaseEngine, **kwargs) -> pw.Database: return return_db -def create_sqlite(folder: str, path: str, db_file: str = "samudra.db"): +def get_sqlite(folder: str, path: str, db_file: str = "samudra.db", new: bool = False): # Defaults to make it async-compatible (according to FastAPI/Pydantic) class PeeweeConnectionState(pw._ConnectionState): def __init__(self, **kwargs): @@ -73,31 +74,40 @@ def __getattr__(self, name): # The DB connection object # ? Perlu ke test? # TODO Add Test - base_path: Path = Path(path, folder) - full_path: Path = Path(base_path, db_file) - try: - base_path.mkdir(parents=True) - except FileExistsError: - if full_path in [*base_path.iterdir()]: - raise FileExistsError( - f"A samudra database already exists in {full_path.resolve()}" + if new: + base_path: Path = Path(path, folder) + full_path: Path = Path(base_path, db_file) + try: + base_path.mkdir(parents=True) + except FileExistsError: + if full_path in [*base_path.iterdir()]: + raise FileExistsError( + f"A samudra database already exists in {full_path.resolve()}" + ) + elif [*base_path.iterdir()] is [None]: + print(f"Populating empty folder `{base_path.resolve()}` with {db_file}") + else: + raise FileExistsError( + f"The path `{base_path.resolve()}` is already occupied with something else. Consider using other folder." + ) + # Set up readme + README = Path(base_path, "README.md") + README.touch() + with README.open(mode="w") as f: + f.writelines( + [ + f"# {folder.title()}\n", + "Created using [samudra](https://github.com/samudradev/samudra)", + ] ) - elif [*base_path.iterdir()] is [None]: - print(f"Populating empty folder `{base_path.resolve()}` with {db_file}") - else: - raise FileExistsError( - f"The path `{base_path.resolve()}` is already occupied with something else. Consider using other folder." + else: + db_obj = get_database_info(name=db_file) + if db_obj is None: + return FileNotFoundError( + f"The database name {db_file} is not found. Perhaps it is not created yet. Pass the key `new=True` if that's the case" ) - # Set up readme - README = Path(base_path, "README.md") - README.touch() - with README.open(mode="w") as f: - f.writelines( - [ - f"# {folder.title()}\n", - "Created using [samudra](https://github.com/samudradev/samudra)", - ] - ) + base_path: Path = Path(db_obj["path"], folder=db_file) + full_path: Path = Path(base_path, db_file) return_db = pw.SqliteDatabase( full_path.resolve(), check_same_thread=False, diff --git a/samudra/serve.py b/samudra/serve.py index 740ddb6..ef58858 100644 --- a/samudra/serve.py +++ b/samudra/serve.py @@ -9,7 +9,6 @@ from fastapi.middleware.cors import CORSMiddleware from samudra.conf.server.cors_policy import ALLOWED_ORIGINS -from samudra.server.setup import check_tables from samudra.server import lemmas, auth, golongan_kata SLEEP_TIME: int = 10 @@ -37,7 +36,7 @@ def root() -> Dict[str, str]: if __name__ == "__main__": - check_tables(create_tables=True) + # TODO Bind to database uvicorn.run("serve:app", port=8000, reload=True) # TODO: CLI diff --git a/samudra/server/setup.py b/samudra/server/setup.py index 99104e0..8b13789 100644 --- a/samudra/server/setup.py +++ b/samudra/server/setup.py @@ -1,42 +1 @@ -import logging -import peewee as pw - -from samudra import models -from samudra.conf import get_database -from samudra.conf.database.core import ENGINE -from samudra.conf.database.options import DatabaseEngine - -# TODO Remove ENGINE config -SERVER_DATABASE: pw.Database = get_database(engine=DatabaseEngine[ENGINE]) - - -def check_tables(create_tables: bool = False) -> None: - """Checks whether the tables exist or not - - Args: - create_tables (bool, optional): Option to create tables if not exist. Defaults to False. - - Raises: - pw.DatabaseError: Raises Database does not exist if `create_tables` is False. - - Returns: - None: None - """ - for TABLE in models.TABLES: - if SERVER_DATABASE.table_exists(TABLE): - logging.debug(f"{TABLE.__name__} existed in {SERVER_DATABASE.database}") - else: - if not create_tables: - raise pw.DatabaseError( - f"{TABLE.__name__} not existed in {SERVER_DATABASE.database}" - ) - if create_tables: - SERVER_DATABASE.create_tables([*models.TABLES, *models.JOIN_TABLES], safe=True) - return None - - -def drop_tables() -> None: - """Drop all tables to start a new server from scratch""" - SERVER_DATABASE.drop_tables([*models.TABLES, *models.JOIN_TABLES]) - logging.info("TABLES DROPPED")