aboutsummaryrefslogtreecommitdiff
path: root/src/hydrilla/proxy/state_impl
diff options
context:
space:
mode:
Diffstat (limited to 'src/hydrilla/proxy/state_impl')
-rw-r--r--src/hydrilla/proxy/state_impl/_operations/prune_orphans.py82
-rw-r--r--src/hydrilla/proxy/state_impl/base.py2
-rw-r--r--src/hydrilla/proxy/state_impl/concrete_state.py28
-rw-r--r--src/hydrilla/proxy/state_impl/items.py2
-rw-r--r--src/hydrilla/proxy/state_impl/repos.py2
5 files changed, 78 insertions, 38 deletions
diff --git a/src/hydrilla/proxy/state_impl/_operations/prune_orphans.py b/src/hydrilla/proxy/state_impl/_operations/prune_orphans.py
index 7123047..5eb8cf7 100644
--- a/src/hydrilla/proxy/state_impl/_operations/prune_orphans.py
+++ b/src/hydrilla/proxy/state_impl/_operations/prune_orphans.py
@@ -37,37 +37,52 @@ import sqlite3
from pathlib import Path
-_remove_item_versions_sqls = [
- '''
- CREATE TEMPORARY TABLE __removed_versions(
- item_version_id INTEGER PRIMARY KEY
- );
- ''', '''
- INSERT INTO
- __removed_versions
- SELECT
- iv.item_version_id
- FROM
- item_versions AS iv
- JOIN orphan_iterations AS oi USING (repo_iteration_id)
- WHERE
- iv.installed != 'I';
- ''', '''
- UPDATE
- mapping_statuses
- SET
- active_version_id = NULL
- WHERE
- active_version_id IN __removed_versions;
- ''', '''
- DELETE FROM
- item_versions
- WHERE
- item_version_id IN __removed_versions;
- ''', '''
- DROP TABLE __removed_versions;
- '''
-]
+def _remove_item_versions(cursor: sqlite3.Cursor, with_installed: bool) -> None:
+ cursor.execute(
+ '''
+ CREATE TEMPORARY TABLE __removed_versions(
+ item_version_id INTEGER PRIMARY KEY
+ );
+ '''
+ )
+
+ condition = "iv.active != 'R'" if with_installed else "iv.installed != 'I'"
+
+ cursor.execute(
+ f'''
+ INSERT INTO
+ __removed_versions
+ SELECT
+ iv.item_version_id
+ FROM
+ item_versions AS iv
+ JOIN orphan_iterations AS oi USING (repo_iteration_id)
+ WHERE
+ {condition};
+ '''
+ )
+
+ cursor.execute(
+ '''
+ UPDATE
+ mapping_statuses
+ SET
+ active_version_id = NULL
+ WHERE
+ active_version_id IN __removed_versions;
+ '''
+ )
+
+ cursor.execute(
+ '''
+ DELETE FROM
+ item_versions
+ WHERE
+ item_version_id IN __removed_versions;
+ '''
+ )
+
+ cursor.execute('DROP TABLE __removed_versions;')
_remove_items_sql = '''
WITH removed_items AS (
@@ -159,11 +174,10 @@ WHERE
repo_id IN removed_repos;
'''
-def prune_orphans(cursor: sqlite3.Cursor) -> None:
+def prune_orphans(cursor: sqlite3.Cursor, aggressive: bool = False) -> None:
assert cursor.connection.in_transaction
- for sql in _remove_item_versions_sqls:
- cursor.execute(sql)
+ _remove_item_versions(cursor, with_installed=aggressive)
cursor.execute(_remove_items_sql)
cursor.execute(_remove_files_sql)
cursor.execute(_forget_files_data_sql)
diff --git a/src/hydrilla/proxy/state_impl/base.py b/src/hydrilla/proxy/state_impl/base.py
index d603504..d99feab 100644
--- a/src/hydrilla/proxy/state_impl/base.py
+++ b/src/hydrilla/proxy/state_impl/base.py
@@ -227,7 +227,7 @@ class HaketiloStateWithFields(st.HaketiloState):
...
@abstractmethod
- def prune_orphans(self) -> None:
+ def soft_prune_orphan_items(self) -> None:
...
@abstractmethod
diff --git a/src/hydrilla/proxy/state_impl/concrete_state.py b/src/hydrilla/proxy/state_impl/concrete_state.py
index 04bb67f..d8706e8 100644
--- a/src/hydrilla/proxy/state_impl/concrete_state.py
+++ b/src/hydrilla/proxy/state_impl/concrete_state.py
@@ -146,7 +146,33 @@ class ConcreteHaketiloState(base.HaketiloStateWithFields):
self.rebuild_structures(rules=False)
- def prune_orphans(self) -> None:
+ def count_orphan_items(self) -> st.OrphanItemsStats:
+ with self.cursor() as cursor:
+ cursor.execute(
+ '''
+ SELECT
+ COALESCE(SUM(i.type = 'M'), 0),
+ COALESCE(SUM(i.type = 'R'), 0)
+ FROM
+ item_versions AS iv
+ JOIN items AS i USING (item_id)
+ JOIN orphan_iterations AS oi USING (repo_iteration_id)
+ WHERE
+ iv.active != 'R';
+ '''
+ )
+
+ (orphan_mappings, orphan_resources), = cursor.fetchall()
+
+ return st.OrphanItemsStats(orphan_mappings, orphan_resources)
+
+ def prune_orphan_items(self) -> None:
+ with self.cursor(transaction=True) as cursor:
+ _operations.prune_orphans(cursor, aggressive=True)
+
+ self.recompute_dependencies()
+
+ def soft_prune_orphan_items(self) -> None:
with self.cursor() as cursor:
assert self.connection.in_transaction
diff --git a/src/hydrilla/proxy/state_impl/items.py b/src/hydrilla/proxy/state_impl/items.py
index e9cabb5..d312db9 100644
--- a/src/hydrilla/proxy/state_impl/items.py
+++ b/src/hydrilla/proxy/state_impl/items.py
@@ -124,7 +124,7 @@ def _uninstall_version(ref: VersionRefVar) -> t.Optional[VersionRefVar]:
_set_installed_status(cursor, ref.id, 'N')
- ref.state.prune_orphans()
+ ref.state.soft_prune_orphan_items()
if active_status != 'N':
ref.state.recompute_dependencies()
diff --git a/src/hydrilla/proxy/state_impl/repos.py b/src/hydrilla/proxy/state_impl/repos.py
index 998548e..85117c8 100644
--- a/src/hydrilla/proxy/state_impl/repos.py
+++ b/src/hydrilla/proxy/state_impl/repos.py
@@ -194,7 +194,7 @@ class ConcreteRepoRef(st.RepoRef):
(self.id,)
)
- self.state.prune_orphans()
+ self.state.soft_prune_orphan_items()
self.state.recompute_dependencies()
def update(