Skip to content

Commit

Permalink
Merge pull request #7658 from tdesveaux/typing/db/projects
Browse files Browse the repository at this point in the history
typing: Add ProjectModel dataclass
  • Loading branch information
p12tic committed May 22, 2024
2 parents b71cbfd + 460eda7 commit 0d2392b
Show file tree
Hide file tree
Showing 8 changed files with 171 additions and 127 deletions.
24 changes: 15 additions & 9 deletions master/buildbot/data/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,27 @@
#
# Copyright Buildbot Team Members

from __future__ import annotations

from typing import TYPE_CHECKING

from twisted.internet import defer

from buildbot.data import base
from buildbot.data import types

if TYPE_CHECKING:
from buildbot.db.projects import ProjectModel


def project_db_to_data(dbdict, active=None):
def project_db_to_data(model: ProjectModel, active=None):
return {
"projectid": dbdict["id"],
"name": dbdict["name"],
"slug": dbdict["slug"],
"description": dbdict["description"],
"description_format": dbdict["description_format"],
"description_html": dbdict["description_html"],
"projectid": model.id,
"name": model.name,
"slug": model.slug,
"description": model.description,
"description_format": model.description_format,
"description_html": model.description_html,
"active": active,
}

Expand Down Expand Up @@ -69,8 +75,8 @@ def get(self, result_spec, kwargs):
# This is not optimized case which is assumed to be infrequently required
dbdicts_all = yield self.master.db.projects.get_projects()
dbdicts_active = yield self.master.db.projects.get_active_projects()
ids_active = set(dbdict["id"] for dbdict in dbdicts_active)
dbdicts = [dbdict for dbdict in dbdicts_all if dbdict["id"] not in ids_active]
ids_active = set(dbdict.id for dbdict in dbdicts_active)
dbdicts = [dbdict for dbdict in dbdicts_all if dbdict.id not in ids_active]

return [project_db_to_data(dbdict, active=active) for dbdict in dbdicts]

Expand Down
85 changes: 59 additions & 26 deletions master/buildbot/db/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,45 @@
#
# Copyright Buildbot Team Members

from __future__ import annotations

from dataclasses import dataclass

from twisted.internet import defer

from buildbot.db import base
from buildbot.warnings import warn_deprecated


@dataclass
class ProjectModel:
id: int
name: str
slug: str
description: str | None
description_format: str | None
description_html: str | None

# For backward compatibility
def __getitem__(self, key: str):
warn_deprecated(
'4.1.0',
(
'ProjectsConnectorComponent '
'get_project, get_projects, and get_active_projects '
'no longer return Project as dictionnaries. '
'Usage of [] accessor is deprecated: please access the member directly'
),
)

if hasattr(self, key):
return getattr(self, key)

raise KeyError(key)


class ProjectsConnectorComponent(base.DBConnectorComponent):
def find_project_id(self, name, auto_create=True):
def find_project_id(self, name: str, auto_create: bool = True) -> defer.Deferred[int | None]:
name_hash = self.hashColumns(name)
return self.findSomethingId(
tbl=self.db.model.projects,
Expand All @@ -33,9 +64,8 @@ def find_project_id(self, name, auto_create=True):
autoCreate=auto_create,
)

@defer.inlineCallbacks
def get_project(self, projectid):
def thd(conn):
def get_project(self, projectid: int) -> defer.Deferred[ProjectModel | None]:
def thd(conn) -> ProjectModel | None:
q = self.db.model.projects.select().where(
self.db.model.projects.c.id == projectid,
)
Expand All @@ -44,41 +74,44 @@ def thd(conn):

rv = None
if row:
rv = self._project_dict_from_row(row)
rv = self._model_from_row(row)
res.close()
return rv

return (yield self.db.pool.do(thd))
return self.db.pool.do(thd)

# returns a Deferred that returns a value
def get_projects(self):
def thd(conn):
def get_projects(self) -> defer.Deferred[list[ProjectModel]]:
def thd(conn) -> list[ProjectModel]:
tbl = self.db.model.projects
q = tbl.select()
q = q.order_by(tbl.c.name)
res = conn.execute(q)
return [self._project_dict_from_row(row) for row in res.fetchall()]
return [self._model_from_row(row) for row in res.fetchall()]

return self.db.pool.do(thd)

# returns a Deferred that returns a value
def get_active_projects(self):
def thd(conn):
def get_active_projects(self) -> defer.Deferred[list[ProjectModel]]:
def thd(conn) -> list[ProjectModel]:
projects_tbl = self.db.model.projects
builders_tbl = self.db.model.builders
bm_tbl = self.db.model.builder_masters

q = projects_tbl.select().join(builders_tbl).join(bm_tbl).order_by(projects_tbl.c.name)
res = conn.execute(q)
return [self._project_dict_from_row(row) for row in res.fetchall()]
return [self._model_from_row(row) for row in res.fetchall()]

return self.db.pool.do(thd)

# returns a Deferred that returns a value
def update_project_info(
self, projectid, slug, description, description_format, description_html
):
def thd(conn):
self,
projectid: int,
slug: str,
description: str | None,
description_format: str | None,
description_html: str | None,
) -> defer.Deferred[None]:
def thd(conn) -> None:
q = self.db.model.projects.update().where(self.db.model.projects.c.id == projectid)
conn.execute(
q.values(
Expand All @@ -91,12 +124,12 @@ def thd(conn):

return self.db.pool.do(thd)

def _project_dict_from_row(self, row):
return {
"id": row.id,
"name": row.name,
"slug": row.slug,
"description": row.description,
"description_format": row.description_format,
"description_html": row.description_html,
}
def _model_from_row(self, row):
return ProjectModel(
id=row.id,
name=row.name,
slug=row.slug,
description=row.description,
description_format=row.description_format,
description_html=row.description_html,
)
37 changes: 25 additions & 12 deletions master/buildbot/test/fakedb/projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
#
# Copyright Buildbot Team Members

from __future__ import annotations

from twisted.internet import defer

from buildbot.db.projects import ProjectModel
from buildbot.test.fakedb.base import FakeDBComponent
from buildbot.test.fakedb.row import Row

Expand Down Expand Up @@ -65,8 +67,7 @@ def insert_test_data(self, rows):
"description_html": row.description_html,
}

# Returns Deferred that yields a number
def find_project_id(self, name, auto_create=True):
def find_project_id(self, name: str, auto_create: bool = True) -> defer.Deferred[int | None]:
for m in self.projects.values():
if m['name'] == name:
return defer.succeed(m['id'])
Expand All @@ -83,18 +84,18 @@ def find_project_id(self, name, auto_create=True):
}
return defer.succeed(id)

def get_project(self, projectid):
def get_project(self, projectid: int) -> defer.Deferred[ProjectModel | None]:
if projectid in self.projects:
return defer.succeed(self._row2dict(self.projects[projectid]))
return defer.succeed(self._model_from_row(self.projects[projectid]))
return defer.succeed(None)

def get_projects(self):
def get_projects(self) -> list[ProjectModel]:
rv = []
for project in self.projects.values():
rv.append(self._row2dict(project))
rv.append(self._model_from_row(project))
return rv

def get_active_projects(self):
def get_active_projects(self) -> list[ProjectModel]:
rv = []

active_builderids = {
Expand All @@ -110,12 +111,17 @@ def get_active_projects(self):
for id, project in self.projects.items():
if id not in active_projectids:
continue
rv.append(self._row2dict(project))
rv.append(self._model_from_row(project))
return rv

def update_project_info(
self, projectid, slug, description, description_format, description_html
):
self,
projectid: int,
slug: str,
description: str | None,
description_format: str | None,
description_html: str | None,
) -> defer.Deferred[None]:
if projectid not in self.projects:
return defer.succeed(None)
project = self.projects[projectid]
Expand All @@ -125,5 +131,12 @@ def update_project_info(
project["description_html"] = description_html
return defer.succeed(None)

def _row2dict(self, row):
return row.copy()
def _model_from_row(self, row):
return ProjectModel(
id=row['id'],
name=row['name'],
slug=row['slug'],
description=row['description'],
description_format=row['description_format'],
description_html=row['description_html'],
)
17 changes: 9 additions & 8 deletions master/buildbot/test/unit/data/test_projects.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

from buildbot.data import projects
from buildbot.data import resultspec
from buildbot.db.projects import ProjectModel
from buildbot.test import fakedb
from buildbot.test.fake import fakemaster
from buildbot.test.reactor import TestReactorMixin
Expand Down Expand Up @@ -155,13 +156,13 @@ def test_update_project_info(self):
self.assertEqual(
projects,
[
{
"id": 13,
"name": "fake_project",
"slug": "slug13",
"description": "project13 desc",
"description_format": "format",
"description_html": "html desc",
}
ProjectModel(
id=13,
name="fake_project",
slug="slug13",
description="project13 desc",
description_format="format",
description_html="html desc",
)
],
)

0 comments on commit 0d2392b

Please sign in to comment.