Skip to content

Commit

Permalink
Rm CRUD ops from model class
Browse files Browse the repository at this point in the history
  • Loading branch information
layday committed Jan 30, 2024
1 parent 870d63c commit 5f37bb3
Show file tree
Hide file tree
Showing 4 changed files with 78 additions and 74 deletions.
4 changes: 2 additions & 2 deletions gui-webview/src/instawow_gui/json_rpc_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ async def respond(self, managers: _ManagersManager) -> list[pkg_models.Pkg]:
.mappings()
.all()
)
return [pkg_models.Pkg.from_row_mapping(connection, p) for p in installed_pkgs]
return [manager.build_pkg_from_row_mapping(connection, p) for p in installed_pkgs]


@_register_method('search')
Expand Down Expand Up @@ -488,7 +488,7 @@ async def respond(self, managers: _ManagersManager) -> list[ReconcileInstalledCa

with manager.ctx.database.connect() as connection:
installed_pkgs = [
pkg_models.Pkg.from_row_mapping(connection, p)
manager.build_pkg_from_row_mapping(connection, p)
for p in connection.execute(
sa.select(pkg_db.pkg).order_by(sa.func.lower(pkg_db.pkg.c.name))
)
Expand Down
6 changes: 3 additions & 3 deletions src/instawow/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def filter_results(result: R.Result):
def installed_pkgs_to_defns():
with mw.manager.ctx.database.connect() as connection:
return [
pkg_models.Pkg.from_row_mapping(connection, p).to_defn()
mw.manager.build_pkg_from_row_mapping(connection, p).to_defn()
for p in connection.execute(sa.select(pkg_db.pkg)).mappings().all()
]

Expand Down Expand Up @@ -571,7 +571,7 @@ def select_alternative_pkg(installed_pkg: pkg_models.Pkg, pkgs: Sequence[pkg_mod

with mw.manager.ctx.database.connect() as connection:
installed_pkgs = [
pkg_models.Pkg.from_row_mapping(connection, p)
mw.manager.build_pkg_from_row_mapping(connection, p)
for p in connection.execute(
sa.select(pkg_db.pkg).order_by(sa.func.lower(pkg_db.pkg.c.name))
)
Expand Down Expand Up @@ -799,7 +799,7 @@ def format_deps(pkg: pkg_models.Pkg):
)

def row_mappings_to_pkgs():
return map(pkg_models.Pkg.from_row_mapping, repeat(connection), pkg_mappings)
return map(mw.manager.build_pkg_from_row_mapping, repeat(connection), pkg_mappings)

pkg_select_query = sa.select(pkg_db.pkg)
if addons:
Expand Down
80 changes: 73 additions & 7 deletions src/instawow/pkg_management.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import datetime as dt
from collections.abc import (
Awaitable,
Callable,
Expand All @@ -9,15 +10,16 @@
Sequence,
)
from contextlib import asynccontextmanager
from functools import wraps
from functools import lru_cache, wraps
from itertools import filterfalse, product, repeat, starmap
from pathlib import Path
from shutil import move
from tempfile import NamedTemporaryFile
from typing import Concatenate, TypeVar

import sqlalchemy as sa
from attrs import evolve
from attrs import asdict, evolve
from cattrs import Converter
from loguru import logger
from typing_extensions import Never, ParamSpec
from yarl import URL
Expand Down Expand Up @@ -52,6 +54,13 @@
_DOWNLOAD_PKG_LOCK = '_DOWNLOAD_PKG_'


@lru_cache(1)
def _make_db_pkg_converter():
converter = Converter()
converter.register_structure_hook(dt.datetime, lambda d, _: d)
return converter


def bucketise_results(
values: Iterable[tuple[Defn, R.AnyResult[_T]]],
):
Expand Down Expand Up @@ -110,6 +119,29 @@ async def _download_pkg_archive(ctx: ManagerCtx, defn: Defn, pkg: pkg_models.Pkg
)


def _insert_db_pkg(pkg: pkg_models.Pkg, transaction: sa.Connection):
values = asdict(pkg)
source_and_id = {'pkg_source': values['source'], 'pkg_id': values['id']}

transaction.execute(sa.insert(pkg_db.pkg), [values])
transaction.execute(
sa.insert(pkg_db.pkg_folder), [{**f, **source_and_id} for f in values['folders']]
)
transaction.execute(sa.insert(pkg_db.pkg_options), [{**values['options'], **source_and_id}])
if values['deps']:
transaction.execute(
sa.insert(pkg_db.pkg_dep), [{**d, **source_and_id} for d in values['deps']]
)
transaction.execute(
sa.insert(pkg_db.pkg_version_log).prefix_with('OR IGNORE'),
[{'version': values['version'], **source_and_id}],
)


def _delete_db_pkg(pkg: pkg_models.Pkg, transaction: sa.Connection):
transaction.execute(sa.delete(pkg_db.pkg).filter_by(source=pkg.source, id=pkg.id))


@run_in_thread
def _install_pkg(
ctx: ManagerCtx, pkg: pkg_models.Pkg, archive: Path, replace_folders: bool
Expand Down Expand Up @@ -142,7 +174,7 @@ def _install_pkg(

pkg = evolve(pkg, folders=[pkg_models.PkgFolder(name=f) for f in sorted(top_level_folders)])
with ctx.database.begin() as transaction:
pkg.insert(transaction)
_insert_db_pkg(pkg, transaction)

return R.PkgInstalled(pkg)

Expand Down Expand Up @@ -186,8 +218,8 @@ def _update_pkg(
new_pkg, folders=[pkg_models.PkgFolder(name=f) for f in sorted(top_level_folders)]
)
with ctx.database.begin() as transaction:
old_pkg.delete(transaction)
new_pkg.insert(transaction)
_delete_db_pkg(old_pkg, transaction)
_insert_db_pkg(new_pkg, transaction)

return R.PkgUpdated(old_pkg, new_pkg)

Expand All @@ -202,7 +234,7 @@ def _remove_pkg(ctx: ManagerCtx, pkg: pkg_models.Pkg, keep_folders: bool) -> R.P
)

with ctx.database.begin() as transaction:
pkg.delete(transaction)
_delete_db_pkg(pkg, transaction)

return R.PkgRemoved(pkg)

Expand Down Expand Up @@ -287,7 +319,41 @@ def get_pkg(self, defn: Defn, partial_match: bool = False) -> pkg_models.Pkg | N
.first()
)
if maybe_row_mapping is not None:
return pkg_models.Pkg.from_row_mapping(connection, maybe_row_mapping)
return self.build_pkg_from_row_mapping(connection, maybe_row_mapping)

def build_pkg_from_row_mapping(
self, connection: sa.Connection, row_mapping: sa.RowMapping
) -> pkg_models.Pkg:
source_and_id = {'pkg_source': row_mapping['source'], 'pkg_id': row_mapping['id']}
return _make_db_pkg_converter().structure(
{
**row_mapping,
'options': connection.execute(
sa.select(pkg_db.pkg_options).filter_by(**source_and_id)
)
.mappings()
.one(),
'folders': connection.execute(
sa.select(pkg_db.pkg_folder.c.name).filter_by(**source_and_id)
)
.mappings()
.all(),
'deps': connection.execute(
sa.select(pkg_db.pkg_dep.c.id).filter_by(**source_and_id)
)
.mappings()
.all(),
'logged_versions': connection.execute(
sa.select(pkg_db.pkg_version_log)
.filter_by(**source_and_id)
.order_by(pkg_db.pkg_version_log.c.install_time.desc())
.limit(10)
)
.mappings()
.all(),
},
pkg_models.Pkg,
)

async def find_equivalent_pkg_defns(
self, pkgs: Collection[pkg_models.Pkg]
Expand Down
62 changes: 0 additions & 62 deletions src/instawow/pkg_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,11 @@

from datetime import datetime

import sqlalchemy as sa
from attrs import asdict, field, frozen
from cattrs import Converter
from typing_extensions import Self

from . import pkg_db
from .common import Defn, StrategyValues

_db_pkg_converter = Converter()
_db_pkg_converter.register_structure_hook(datetime, lambda d, _: d)


@frozen(kw_only=True)
class PkgOptions:
Expand Down Expand Up @@ -60,62 +54,6 @@ class Pkg:
deps: list[PkgDep] = field(factory=list) # pkg_dep
logged_versions: list[PkgLoggedVersion] = field(factory=list) # pkg_version_log

@classmethod
def from_row_mapping(cls, connection: sa.Connection, row_mapping: sa.RowMapping) -> Self:
source_and_id = {'pkg_source': row_mapping['source'], 'pkg_id': row_mapping['id']}
return _db_pkg_converter.structure(
{
**row_mapping,
'options': connection.execute(
sa.select(pkg_db.pkg_options).filter_by(**source_and_id)
)
.mappings()
.one(),
'folders': connection.execute(
sa.select(pkg_db.pkg_folder.c.name).filter_by(**source_and_id)
)
.mappings()
.all(),
'deps': connection.execute(
sa.select(pkg_db.pkg_dep.c.id).filter_by(**source_and_id)
)
.mappings()
.all(),
'logged_versions': connection.execute(
sa.select(pkg_db.pkg_version_log)
.filter_by(**source_and_id)
.order_by(pkg_db.pkg_version_log.c.install_time.desc())
.limit(10)
)
.mappings()
.all(),
},
cls,
)

def insert(self, transaction: sa.Connection) -> None:
values = asdict(self)
source_and_id = {'pkg_source': values['source'], 'pkg_id': values['id']}

transaction.execute(sa.insert(pkg_db.pkg), [values])
transaction.execute(
sa.insert(pkg_db.pkg_folder), [{**f, **source_and_id} for f in values['folders']]
)
transaction.execute(
sa.insert(pkg_db.pkg_options), [{**values['options'], **source_and_id}]
)
if values['deps']:
transaction.execute(
sa.insert(pkg_db.pkg_dep), [{**d, **source_and_id} for d in values['deps']]
)
transaction.execute(
sa.insert(pkg_db.pkg_version_log).prefix_with('OR IGNORE'),
[{'version': values['version'], **source_and_id}],
)

def delete(self, transaction: sa.Connection) -> None:
transaction.execute(sa.delete(pkg_db.pkg).filter_by(source=self.source, id=self.id))

def to_defn(self) -> Defn:
return Defn(
source=self.source,
Expand Down

0 comments on commit 5f37bb3

Please sign in to comment.