diff options
Diffstat (limited to 'buildbot_gentoo_ci/db/builds.py')
-rw-r--r-- | buildbot_gentoo_ci/db/builds.py | 184 |
1 files changed, 114 insertions, 70 deletions
diff --git a/buildbot_gentoo_ci/db/builds.py b/buildbot_gentoo_ci/db/builds.py index 21adcc0..47413a3 100644 --- a/buildbot_gentoo_ci/db/builds.py +++ b/buildbot_gentoo_ci/db/builds.py @@ -15,7 +15,11 @@ # Copyright Buildbot Team Members # Origins: buildbot.db.* # Modifyed by Gentoo Authors. -# Copyright 2023 Gentoo Authors +# Copyright 2024 Gentoo Authors + +from __future__ import annotations +from dataclasses import dataclass +from typing import TYPE_CHECKING import uuid import sqlalchemy as sa @@ -23,94 +27,134 @@ import sqlalchemy as sa from twisted.internet import defer from buildbot.db import base +from buildbot.warnings import warn_deprecated + +if TYPE_CHECKING: + import datetime + +@dataclass +class ProjectsBuildsModel: + id : int + build_id : int + project_uuid : str + version_uuid : str + buildbot_build_id : int + bug_id : int + status : str + requested : bool + created_at : datetime.datetime | None + updated_at : datetime.datetime | None + deleted : bool + deleted_at: datetime.datetime | None + + # For backward compatibility + def __getitem__(self, key: str): + warn_deprecated( + '4.1.0', + ( + 'VersionsConnectorComponent getVersionByName, ' + 'getBuildByNumber, getPrevSuccessfulBuild, ' + 'getBuildsForChange, getBuilds, ' + '_getRecentBuilds, and _getBuild ' + 'no longer return Build as dictionnaries. ' + 'Usage of [] accessor is deprecated: please access the member directly' + ), + ) + + if hasattr(self, key): + return getattr(self, key) + + raise KeyError(key) + +def _db2data_ProjectsBuilds(model: ProjectsBuildsModel): + if model is None: + return None + return { + 'id' : model.id, + 'build_id' : model.build_id, + 'project_uuid' : model.project_uuid, + 'version_uuid' : model.version_uuid, + 'buildbot_build_id' : model.buildbot_build_id, + 'bug_id' : model.bug_id, + 'status' : model.status, + 'requested' : model.requested, + 'created_at' : model.created_at, + 'updated_at' : model.updated_at, + 'deleted' : model.deleted, + 'deleted_at' : model.deleted_at + } class BuildsConnectorComponent(base.DBConnectorComponent): - #@defer.inlineCallbacks def addBuild(self, project_build_data): - created_at = int(self.master.reactor.seconds()) - def thd(conn, no_recurse=False): - tbl = self.db.model.projects_builds + def thd(conn): # get the highest current number - r = conn.execute(sa.select([sa.func.max(tbl.c.build_id)], - whereclause=(tbl.c.project_uuid == project_build_data['project_uuid']))) + tbl = self.db.model.projects_builds + r = conn.execute( + sa.select(sa.func.max(tbl.c.build_id)).where(tbl.c.project_uuid == project_build_data['project_uuid']) + ) number = r.scalar() new_number = 1 if number is None else number + 1 + insert_row = { + 'project_uuid' : project_build_data['project_uuid'], + 'version_uuid' : project_build_data['version_uuid'], + 'status' : project_build_data['status'], + 'requested' : project_build_data['requested'], + 'created_at' : int(self.master.reactor.seconds()), + 'buildbot_build_id' : 0, + 'build_id' : new_number, + 'bug_id' : 0, + } try: - q = tbl.insert() - r = conn.execute(q, dict(project_uuid=project_build_data['project_uuid'], - version_uuid=project_build_data['version_uuid'], - status=project_build_data['status'], - requested=project_build_data['requested'], - created_at=created_at, - buildbot_build_id=0, - build_id=new_number, - bug_id=0 - )) + r = conn.execute(tbl.insert(), insert_row) + conn.commit() except (sa.exc.IntegrityError, sa.exc.ProgrammingError): - id = None - new_number = None - else: - id = r.inserted_primary_key[0] - return id, new_number + conn.rollback() + return None, None + return r.inserted_primary_key[0], new_number return self.db.pool.do(thd) - @defer.inlineCallbacks def setStatusBuilds(self, id, status): - updated_at = int(self.master.reactor.seconds()) - def thd(conn, no_recurse=False): - tbl = self.db.model.projects_builds - q = tbl.update() - q = q.where(tbl.c.id == id) - conn.execute(q, updated_at=updated_at, - status=status) - yield self.db.pool.do(thd) - - @defer.inlineCallbacks + def thd(conn): + tbl = self.db.model.projects_builds + q = tbl.update().where(tbl.c.id == id) + conn.execute(q.values(updated_at=int(self.master.reactor.seconds()), status=status)) + return self.db.pool.do(thd) + def setBuildbotBuildIdBuilds(self, id, buildbot_build_id): - updated_at = int(self.master.reactor.seconds()) - def thd(conn, no_recurse=False): - tbl = self.db.model.projects_builds - q = tbl.update() - q = q.where(tbl.c.id == id) - conn.execute(q, updated_at=updated_at, - buildbot_build_id=buildbot_build_id) - yield self.db.pool.do(thd) - - @defer.inlineCallbacks + def thd(conn): + tbl = self.db.model.projects_builds + q = tbl.update().where(tbl.c.id == id) + conn.execute(q.values(updated_at=int(self.master.reactor.seconds()), buildbot_build_id=buildbot_build_id)) + return self.db.pool.do(thd) + def setBugIdBuilds(self, id, bug_id): - updated_at = int(self.master.reactor.seconds()) - def thd(conn, no_recurse=False): - tbl = self.db.model.projects_builds - q = tbl.update() - q = q.where(tbl.c.id == id) - conn.execute(q, updated_at=updated_at, bug_id=bug_id) - yield self.db.pool.do(thd) - - @defer.inlineCallbacks - def getBuildsByVersionUuid(self, uuid): def thd(conn): tbl = self.db.model.projects_builds + q = tbl.update().where(tbl.c.id == id) + conn.execute(q.values(updated_at=int(self.master.reactor.seconds()), bug_id=bug_id)) + return self.db.pool.do(thd) + + def getBuildsByVersionUuid(self, uuid) -> defer.Deferred[list[ProjectsBuildsModel]]: + def thd(conn) -> list[ProjectsBuildsModel]: + tbl = self.db.model.projects_builds q = tbl.select() q = q.where(tbl.c.version_uuid == uuid) res = conn.execute(q) - row = res.fetchone() - return [self._row2dict(conn, row) - for row in conn.execute(q).fetchall()] - res = yield self.db.pool.do(thd) - return res - - @defer.inlineCallbacks - def removeBuild(self, id): - def thd(conn, no_recurse=False): - tbl = self.db.model.projects_builds - q = tbl.delete() - q = q.where(tbl.c.id == id) - conn.execute(q) - yield self.db.pool.do(thd) - - def _row2dict(self, conn, row): - return dict( + return list(self._model_from_row(row) for row in res.fetchall()) + return self.db.pool.do(thd) + + def removeBuild(self, id: int) -> defer.Deferred[None]: + def thd(conn) -> None: + tbl = self.db.model.projects_builds + q = tbl.delete().where(tbl.c.id == id) + res = conn.execute(q) + conn.commit() + res.close() + return self.db.pool.do(thd) + + def _model_from_row(self, row): + return ProjectsBuildsModel( id=row.id, build_id=row.build_id, project_uuid=row.project_uuid, |