# This file was generated by mettle.genes.db.GenPy3 [ver 2.2] on Thu Aug 11 12:14:36 2022
#  Target Database = postgresql
#
import asyncio
import datetime
import uuid
import time
import mettle.lib
import mettle.io
import mettle.db

from bs_audit.db.tables.cfg import tCfg
from bs_audit.db.tables.cfg_key import tCfgKey

from .cfg_select_one import dCfgSelectOne
from .cfg_insert import dCfgInsert

class dCfg:
    __slots__ = ("_dbcon", "rec")

    def __init__(self, dbcon: mettle.db.IAConnect):
        """
        Constructor.

        :param dbcon: Mettle database connection object.
        """
        self.rec    = tCfg()
        self._dbcon = dbcon

    def __enter__(self):
        """
        DAO enter.
        """
        return self

    def __exit__(self, type, value, traceback):
        """
        DAO exit.
        """
        pass

    async def try_select_one(self) -> bool:
        """
        Attempt to select the record.

        :return: True if the record was found.
        """
        _key = tCfgKey()

        self.rec._write_key(_key)

        return await self.try_select_one_by_key(_key)

    async def try_select_one_with(self, _rec: tCfg) -> bool:
        """
        Attempt to select the record using a table rec.

        :param _rec: The table rec to select with and into.
        :return: True if the row as selectd.
        """
        _key = tCfgKey()
        _rec._write_key(_key)

        if not await self.try_select_one_by_key(_key):
            return False

        _rec._copy_from(self.rec)

        return True

    async def try_select_one_deft(self,
                                  id: str) -> bool:
        """
        Attempt to select the record by it's primary key columns.

        :param id: str
        :return: True if the row as selectd.
        """
        _key = tCfgKey()

        _key.id = id

        return await self.try_select_one_by_key(_key)

    async def try_select_one_by_key(self, _key: tCfgKey) -> bool:
        """
        Attempt to select the record with it's primary key.

        :param _key: Primary key of the table record.
        :returns: True if row was selected.
        """
        with dCfgSelectOne(self._dbcon) as _qry:
            await _qry.exec(_key)
            if not await _qry.fetch():
                return False

            self.rec = _qry.orec

        return True

    async def select_one(self) -> "dCfg":
        """
        Selects the record, raises and error if it does not exist.

        :return: Self for convenience.
        """
        if not await self.try_select_one():
            raise mettle.lib.xMettle(f"Not found: [table:dCfg, row:{self.rec}]", err_code=mettle.lib.xMettle.eCode.DBNotFound)

        return self

    async def select_one_with(self, _rec: tCfg) -> "dCfg":
        """
        Attempt to select the record with the table record.

        :param _rec: Table record.
        :returns: Self for convenience.
        """
        if not await self.try_select_one_with(_rec):
            raise mettle.lib.xMettle("SelectOne failed to return a record (dCfg)")

        return self

    async def select_one_deft(self,
                              id: str) -> "dCfg":
        """
        Selects the record by its primary key columns, raises and error if it does not exist.

        :param id: str
        """
        _key = tCfgKey()

        _key.id = id

        if not await self.try_select_one_by_key(_key):
            raise mettle.lib.xMettle(f"Not found: [table:dCfg, row:{_key}]", err_code=mettle.lib.xMettle.eCode.DBNotFound)

        return self

    async def select_one_by_key(self, _key: tCfgKey) -> "dCfg":
        """
        Attempt to select the record with it's primary key.

        :param _key: Primary key of the table record.
        :return: Self for convenience.
        """
        if not await self.try_select_one_by_key(_key):
            raise mettle.lib.xMettle(f"Not found: [table:dCfg, row:{self.irec}]", xMettle.eCode.DBNotFound)

        return self

    async def insert_deft(self,
                          id: str,
                          col_pk: str,
                          col_ignr: str,
                          par_id: str,
                          par_col: str,
                          last_chg: datetime.datetime,
                          audby_col: str,
                          mode: str):
        """
        Insert the record setting all column values.

        :param id: str
        :param col_pk: str
        :param col_ignr: str
        :param par_id: str
        :param par_col: str
        :param last_chg: datetime.datetime
        :param audby_col: str
        :param mode: str
        """
        self.rec.id = id
        self.rec.col_pk = col_pk
        self.rec.col_ignr = col_ignr
        self.rec.par_id = par_id
        self.rec.par_col = par_col
        self.rec.last_chg = last_chg
        self.rec.audby_col = audby_col
        self.rec.mode = mode

        await self.insert()

    async def insert(self, irec: tCfg = None):
        """
        Insert the record in the database with the record or irec if it is not None.

        :param irec: If not None use this record to insert into the database.
        """
        if irec:
            self.rec._copy_from(irec)

        with dCfgInsert(self._dbcon) as _qry:
            await _qry.exec(self.rec)

        if irec:
            irec._copy_from(self.rec)

