aboutsummaryrefslogtreecommitdiff
path: root/src/hydrilla/proxy/state_impl/_operations
diff options
context:
space:
mode:
authorWojtek Kosior <koszko@koszko.org>2022-08-25 16:37:53 +0200
committerWojtek Kosior <koszko@koszko.org>2022-09-28 12:54:54 +0200
commit367ea85057368047a50ae98a3510e0113eadd744 (patch)
tree5aecfd3a2e44377e9d331ca77346666ca193006c /src/hydrilla/proxy/state_impl/_operations
parentc1f6a379b3a85303f487e1b366e96d9db90cd4e3 (diff)
downloadhaketilo-hydrilla-367ea85057368047a50ae98a3510e0113eadd744.tar.gz
haketilo-hydrilla-367ea85057368047a50ae98a3510e0113eadd744.zip
[proxy] make it possible to uninstall a package
This commit also brings some more refactoring under state_impl/.
Diffstat (limited to 'src/hydrilla/proxy/state_impl/_operations')
-rw-r--r--src/hydrilla/proxy/state_impl/_operations/__init__.py2
-rw-r--r--src/hydrilla/proxy/state_impl/_operations/load_packages.py13
-rw-r--r--src/hydrilla/proxy/state_impl/_operations/prune_orphans.py (renamed from src/hydrilla/proxy/state_impl/_operations/prune_packages.py)12
-rw-r--r--src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py58
4 files changed, 66 insertions, 19 deletions
diff --git a/src/hydrilla/proxy/state_impl/_operations/__init__.py b/src/hydrilla/proxy/state_impl/_operations/__init__.py
index ff34b0b..359e2f5 100644
--- a/src/hydrilla/proxy/state_impl/_operations/__init__.py
+++ b/src/hydrilla/proxy/state_impl/_operations/__init__.py
@@ -4,7 +4,7 @@
#
# Available under the terms of Creative Commons Zero v1.0 Universal.
-from .prune_packages import prune_packages
+from .prune_orphans import prune_orphans
from .pull_missing_files import pull_missing_files
from .load_packages import _load_packages_no_state_update
from .recompute_dependencies import _recompute_dependencies_no_state_update
diff --git a/src/hydrilla/proxy/state_impl/_operations/load_packages.py b/src/hydrilla/proxy/state_impl/_operations/load_packages.py
index 107e8d6..f8fddfa 100644
--- a/src/hydrilla/proxy/state_impl/_operations/load_packages.py
+++ b/src/hydrilla/proxy/state_impl/_operations/load_packages.py
@@ -45,7 +45,7 @@ from .... import item_infos
from ... import state
from .recompute_dependencies import _recompute_dependencies_no_state_update, \
FileResolver
-from .prune_packages import prune_packages
+from .prune_orphans import prune_orphans
def make_repo_iteration(cursor: sqlite3.Cursor, repo_id: int) -> int:
cursor.execute(
@@ -401,11 +401,16 @@ def _load_packages_no_state_update(
repo_id = repo_id
)
- prune_packages(cursor)
+ if repo_id != 1:
+ # In case of local semirepo (repo_id = 1) all packages from previous
+ # iteration are already orphans and can be assumed to be in a pruned
+ # state no matter what.
+ prune_orphans(cursor)
_recompute_dependencies_no_state_update(
- cursor = cursor,
- semirepo_file_resolver = MalcontentFileResolver(malcontent_path)
+ cursor = cursor,
+ unlocked_required_mappings = [],
+ semirepo_file_resolver = MalcontentFileResolver(malcontent_path)
)
return repo_iteration_id
diff --git a/src/hydrilla/proxy/state_impl/_operations/prune_packages.py b/src/hydrilla/proxy/state_impl/_operations/prune_orphans.py
index 6f4b3e7..f4ebd52 100644
--- a/src/hydrilla/proxy/state_impl/_operations/prune_packages.py
+++ b/src/hydrilla/proxy/state_impl/_operations/prune_orphans.py
@@ -38,12 +38,12 @@ from pathlib import Path
_remove_item_versions_sqls = [
'''
- CREATE TEMPORARY TABLE removed_versions(
+ CREATE TEMPORARY TABLE __removed_versions(
item_version_id INTEGER PRIMARY KEY
);
''', '''
INSERT INTO
- removed_versions
+ __removed_versions
SELECT
iv.item_version_id
FROM
@@ -57,14 +57,14 @@ _remove_item_versions_sqls = [
SET
active_version_id = NULL
WHERE
- active_version_id IN removed_versions;
+ active_version_id IN __removed_versions;
''', '''
DELETE FROM
item_versions
WHERE
- item_version_id IN removed_versions;
+ item_version_id IN __removed_versions;
''', '''
- DROP TABLE removed_versions;
+ DROP TABLE __removed_versions;
'''
]
@@ -134,7 +134,7 @@ WHERE
repo_id IN removed_repos;
'''
-def prune_packages(cursor: sqlite3.Cursor) -> None:
+def prune_orphans(cursor: sqlite3.Cursor) -> None:
assert cursor.connection.in_transaction
for sql in _remove_item_versions_sqls:
diff --git a/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py b/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py
index d4c4d45..327a195 100644
--- a/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py
+++ b/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py
@@ -36,6 +36,7 @@ import typing as t
from .... import item_infos
from ... import simple_dependency_satisfying as sds
+from .. import base
from .pull_missing_files import pull_missing_files, FileResolver, \
DummyFileResolver
@@ -73,6 +74,41 @@ def _get_infos_of_type(cursor: sqlite3.Cursor, info_type: t.Type[AnyInfoVar],) \
return result
+def _get_current_required_state(
+ cursor: sqlite3.Cursor,
+ unlocked_required_mappings: t.Sequence[int]
+) -> list[sds.MappingRequirement]:
+ # For mappings explicitly enabled by the user (+ all mappings they
+ # recursively depend on) let's make sure that their exact same versions will
+ # be enabled after the change. Make exception for mappings specified by the
+ # caller.
+ with base.temporary_ids_table(
+ cursor = cursor,
+ ids = unlocked_required_mappings,
+ table_name = '__unlocked_ids'
+ ):
+ cursor.execute(
+ '''
+ SELECT
+ definition, repo, repo_iteration
+ FROM
+ item_versions_extra
+ WHERE
+ item_id NOT IN __unlocked_ids AND active = 'R';
+ ''',
+ )
+
+ rows = cursor.fetchall()
+
+ requirements: list[sds.MappingRequirement] = []
+
+ for definition, repo, iteration in rows:
+ info = item_infos.MappingInfo.load(definition, repo, iteration)
+ req = sds.MappingVersionRequirement(info.identifier, info)
+ requirements.append(req)
+
+ return requirements
+
def _mark_version_installed(cursor: sqlite3.Cursor, version_id: int) -> None:
cursor.execute(
'''
@@ -87,8 +123,8 @@ def _mark_version_installed(cursor: sqlite3.Cursor, version_id: int) -> None:
)
def _recompute_dependencies_no_state_update_no_pull_files(
- cursor: sqlite3.Cursor,
- extra_requirements: t.Iterable[sds.MappingRequirement]
+ cursor: sqlite3.Cursor,
+ unlocked_required_mappings: base.NoLockArg = [],
) -> None:
cursor.execute('DELETE FROM payloads;')
@@ -98,7 +134,13 @@ def _recompute_dependencies_no_state_update_no_pull_files(
resources_to_ids = dict((info, id) for id, info in ids_to_resources.items())
mappings_to_ids = dict((info, id) for id, info in ids_to_mappings.items())
- requirements = [*extra_requirements]
+ if unlocked_required_mappings == 'all_mappings_unlocked':
+ requirements = []
+ else:
+ requirements = _get_current_required_state(
+ cursor = cursor,
+ unlocked_required_mappings = unlocked_required_mappings
+ )
cursor.execute(
'''
@@ -276,13 +318,13 @@ def _recompute_dependencies_no_state_update_no_pull_files(
def _recompute_dependencies_no_state_update(
- cursor: sqlite3.Cursor,
- extra_requirements: t.Iterable[sds.MappingRequirement] = (),
- semirepo_file_resolver: FileResolver = DummyFileResolver()
+ cursor: sqlite3.Cursor,
+ unlocked_required_mappings: base.NoLockArg = [],
+ semirepo_file_resolver: FileResolver = DummyFileResolver()
) -> None:
_recompute_dependencies_no_state_update_no_pull_files(
- cursor,
- extra_requirements
+ cursor = cursor,
+ unlocked_required_mappings = unlocked_required_mappings
)
pull_missing_files(cursor, semirepo_file_resolver)