from sqlalchemy.engine import Engine
from sqlmodel import create_engine, Session, SQLModel
from sqlmodel.engine.create import _FutureEngine
from typing import Union, Optional
from pyemits.common.validation import raise_if_incorrect_type, raise_if_not_all_value_contains, \
    raise_if_not_all_element_type_uniform, check_all_element_type_uniform, raise_if_value_not_contains
from typing import List


class DBConnectionBase:
    """
    References
    ----------
    for users who want to know the differences between Engine, Connection, Session
    https://stackoverflow.com/questions/34322471/sqlalchemy-engine-connection-and-session-difference

    """

    def __init__(self, db_engine: Union[Engine, _FutureEngine]):
        self._db_engine = db_engine
        SQLModel.metadata.create_all(self._db_engine)

    @classmethod
    def from_db_user(cls, db_type, db_driver, host, user, password, port, db, charset='utf8', echo=True):
        engine = create_engine(f"{db_type}+{db_driver}://{user}:{password}@{host}:{port}/{db}", echo=echo)
        return cls(engine)

    @classmethod
    def from_full_db_path(cls, full_db_path, echo=True):
        engine = 