From 367ea85057368047a50ae98a3510e0113eadd744 Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Thu, 25 Aug 2022 16:37:53 +0200 Subject: [proxy] make it possible to uninstall a package This commit also brings some more refactoring under state_impl/. --- .../proxy/state_impl/_operations/prune_orphans.py | 145 +++++++++++++++++++++ 1 file changed, 145 insertions(+) create mode 100644 src/hydrilla/proxy/state_impl/_operations/prune_orphans.py (limited to 'src/hydrilla/proxy/state_impl/_operations/prune_orphans.py') diff --git a/src/hydrilla/proxy/state_impl/_operations/prune_orphans.py b/src/hydrilla/proxy/state_impl/_operations/prune_orphans.py new file mode 100644 index 0000000..f4ebd52 --- /dev/null +++ b/src/hydrilla/proxy/state_impl/_operations/prune_orphans.py @@ -0,0 +1,145 @@ +# SPDX-License-Identifier: GPL-3.0-or-later + +# Haketilo proxy data and configuration (removal of packages that are not used). +# +# This file is part of Hydrilla&Haketilo. +# +# Copyright (C) 2022 Wojtek Kosior +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . +# +# +# I, Wojtek Kosior, thereby promise not to sue for violation of this +# file's license. Although I request that you do not make use this code +# in a proprietary program, I am not going to enforce this in court. + +""" +.... +""" + +# Enable using with Python 3.7. +from __future__ import annotations + +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; + ''' +] + +_remove_items_sql = ''' +WITH removed_items AS ( + SELECT + i.item_id + FROM + items AS i + LEFT JOIN item_versions AS iv USING (item_id) + LEFT JOIN mapping_statuses AS ms USING (item_id) + WHERE + iv.item_version_id IS NULL AND + (i.type = 'R' OR ms.enabled = 'N') +) +DELETE FROM + items +WHERE + item_id IN removed_items; +''' + +_remove_files_sql = ''' +WITH removed_files AS ( + SELECT + f.file_id + FROM + files AS f + LEFT JOIN file_uses AS fu USING (file_id) + WHERE + fu.file_use_id IS NULL +) +DELETE FROM + files +WHERE + file_id IN removed_files; +''' + +_remove_repo_iterations_sql = ''' +WITH removed_iterations AS ( + SELECT + oi.repo_iteration_id + FROM + orphan_iterations AS oi + LEFT JOIN item_versions AS iv USING (repo_iteration_id) + WHERE + iv.item_version_id IS NULL +) +DELETE FROM + repo_iterations +WHERE + repo_iteration_id IN removed_iterations; +''' + +_remove_repos_sql = ''' +WITH removed_repos AS ( + SELECT + r.repo_id + FROM + repos AS r + LEFT JOIN repo_iterations AS ri USING (repo_id) + WHERE + r.deleted AND ri.repo_iteration_id IS NULL AND r.repo_id != 1 +) +DELETE FROM + repos +WHERE + repo_id IN removed_repos; +''' + +def prune_orphans(cursor: sqlite3.Cursor) -> None: + assert cursor.connection.in_transaction + + for sql in _remove_item_versions_sqls: + cursor.execute(sql) + cursor.execute(_remove_items_sql) + cursor.execute(_remove_files_sql) + cursor.execute(_remove_repo_iterations_sql) + cursor.execute(_remove_repos_sql) -- cgit v1.2.3