From 4cde0ac617027bd3b4fb927bc7aba15bd508c093 Mon Sep 17 00:00:00 2001 From: ZenithClown Date: Tue, 17 Mar 2026 14:22:09 +0530 Subject: [PATCH 1/3] =?UTF-8?q?=F0=9F=9B=A0=EF=B8=8F=F0=9F=90=9B=20bug=20f?= =?UTF-8?q?ix=20check=20if=20the=20job=5Fname=20already=20exists?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - if the job with the same name already exists continue the process with a message; else - creates a new job id as previously --- aptracker/database/sqlalchemy.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/aptracker/database/sqlalchemy.py b/aptracker/database/sqlalchemy.py index ff3759e..7dfde35 100644 --- a/aptracker/database/sqlalchemy.py +++ b/aptracker/database/sqlalchemy.py @@ -7,6 +7,8 @@ import logging import datetime as dt +import sqlalchemy as sa + from sqlalchemy.ext.asyncio import ( AsyncSession, async_sessionmaker, @@ -110,14 +112,30 @@ async def create(self, job_name : str) -> str: now = dt.datetime.now(tz = dt.timezone.utc) retvalue = f"ID: {self.job_id} Job Name: {job_name}" + # ? check if the job already exists; unique constraint async with self._session_factory() as db_session: - db_session.add(ProjectRecord( - job_id = self.job_id, - job_name = job_name, - created_on = now - )) - - await db_session.commit() + _exists = ( + await db_session.execute( + sa.select(ProjectRecord).where( + ProjectRecord.job_name == job_name + ) + ) + ).scalar_one_or_none() + + if _exists: + print( + f"WARN:: JOB : {job_name} Alread Exists. " + f"Use the Existing ID: {_exists.job_id}. " + f"Current ID: {self.job_id} is discarded." + ) + else: + db_session.add(ProjectRecord( + job_id = self.job_id, + job_name = job_name, + created_on = now + )) + + await db_session.commit() return retvalue From 89f024264b4f29fae7fcb71936d729ad54bee36c Mon Sep 17 00:00:00 2001 From: ZenithClown Date: Tue, 17 Mar 2026 14:30:59 +0530 Subject: [PATCH 2/3] =?UTF-8?q?=F0=9F=90=9B=F0=9F=A9=B9=20on=20session=20d?= =?UTF-8?q?isconnect,=20always=20update=20decommissioned=20flag?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- aptracker/database/sqlalchemy.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/aptracker/database/sqlalchemy.py b/aptracker/database/sqlalchemy.py index 7dfde35..155df70 100644 --- a/aptracker/database/sqlalchemy.py +++ b/aptracker/database/sqlalchemy.py @@ -90,6 +90,24 @@ async def disconnect(self) -> None: disconnected. To reconnect, call :meth:`connect` again. """ + # ! once .disconnect() is invoked always flag decomissioned + async with self._session_factory() as db_session: + _current = ( + await db_session.execute( + sa.select(SessionRecord).where( + SessionRecord.session_id == self.session_id + ) + ) + ).scalar_one_or_none() + + if _current: + _current.decommissioned_on = dt.datetime.now( + tz = dt.timezone.utc + ) + _current.decommissioned_by = self.session.CREATED_BY + + await db_session.commit() + await self.engine.dispose() self._status = False From 222d3730be2951a26396eb9682e3d14d58c1de90 Mon Sep 17 00:00:00 2001 From: ZenithClown Date: Tue, 17 Mar 2026 14:31:24 +0530 Subject: [PATCH 3/3] =?UTF-8?q?=E2=9C=A8=20keep=20same=20job=20name=20for?= =?UTF-8?q?=20testing?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- example/basic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/basic.py b/example/basic.py index fc216d5..596f5e2 100644 --- a/example/basic.py +++ b/example/basic.py @@ -16,7 +16,7 @@ from aptracker.database.sqlalchemy import SQLAlchemyDB async def main(session : SessionConfig) -> None: - job_name = f"[{str(uuid.uuid4()).upper()[:3]}] Example Project" + job_name = f"Example Project" session_name = f"[{str(uuid.uuid4()).upper()[:3]}] Example Session" logging.basicConfig(level = logging.INFO)