moved sql function flush_deleted_places() to utils

This commit is contained in:
lujoh 2023-10-17 18:22:27 -04:00
parent e9efef9095
commit 06204dfcd8
3 changed files with 77 additions and 95 deletions

View File

@ -363,57 +363,3 @@ BEGIN
RETURN NULL; RETURN NULL;
END; END;
$$ LANGUAGE plpgsql; $$ LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION flush_deleted_places()
RETURNS INTEGER
AS $$
BEGIN
-- deleting large polygons can have a massive effect on the system - require manual intervention to let them through
INSERT INTO import_polygon_delete (osm_type, osm_id, class, type)
SELECT osm_type, osm_id, class, type FROM place_to_be_deleted WHERE deferred;
-- delete from place table
ALTER TABLE place DISABLE TRIGGER place_before_delete;
DELETE FROM place USING place_to_be_deleted
WHERE place.osm_type = place_to_be_deleted.osm_type
and place.osm_id = place_to_be_deleted.osm_id
and place.class = place_to_be_deleted.class
and place.type = place_to_be_deleted.type
and not deferred;
ALTER TABLE place ENABLE TRIGGER place_before_delete;
-- Mark for delete in the placex table
UPDATE placex SET indexed_status = 100 FROM place_to_be_deleted
WHERE placex.osm_type = 'N' and place_to_be_deleted.osm_type = 'N'
and placex.osm_id = place_to_be_deleted.osm_id
and placex.class = place_to_be_deleted.class
and placex.type = place_to_be_deleted.type
and not deferred;
UPDATE placex SET indexed_status = 100 FROM place_to_be_deleted
WHERE placex.osm_type = 'W' and place_to_be_deleted.osm_type = 'W'
and placex.osm_id = place_to_be_deleted.osm_id
and placex.class = place_to_be_deleted.class
and placex.type = place_to_be_deleted.type
and not deferred;
UPDATE placex SET indexed_status = 100 FROM place_to_be_deleted
WHERE placex.osm_type = 'R' and place_to_be_deleted.osm_type = 'R'
and placex.osm_id = place_to_be_deleted.osm_id
and placex.class = place_to_be_deleted.class
and placex.type = place_to_be_deleted.type
and not deferred;
-- Mark for delete in interpolations
UPDATE location_property_osmline SET indexed_status = 100 FROM place_to_be_deleted
WHERE place_to_be_deleted.osm_type = 'W'
and place_to_be_deleted.class = 'place'
and place_to_be_deleted.type = 'houses'
and location_property_osmline.osm_id = place_to_be_deleted.osm_id
and not deferred;
-- Clear todo list.
TRUNCATE TABLE place_to_be_deleted;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;

View File

@ -487,3 +487,56 @@ BEGIN
END; END;
$$ $$
LANGUAGE plpgsql; LANGUAGE plpgsql;
CREATE OR REPLACE FUNCTION flush_deleted_places()
RETURNS INTEGER
AS $$
BEGIN
-- deleting large polygons can have a massive effect on the system - require manual intervention to let them through
INSERT INTO import_polygon_delete (osm_type, osm_id, class, type)
SELECT osm_type, osm_id, class, type FROM place_to_be_deleted WHERE deferred;
-- delete from place table
ALTER TABLE place DISABLE TRIGGER place_before_delete;
DELETE FROM place USING place_to_be_deleted
WHERE place.osm_type = place_to_be_deleted.osm_type
and place.osm_id = place_to_be_deleted.osm_id
and place.class = place_to_be_deleted.class
and place.type = place_to_be_deleted.type
and not deferred;
ALTER TABLE place ENABLE TRIGGER place_before_delete;
-- Mark for delete in the placex table
UPDATE placex SET indexed_status = 100 FROM place_to_be_deleted
WHERE placex.osm_type = 'N' and place_to_be_deleted.osm_type = 'N'
and placex.osm_id = place_to_be_deleted.osm_id
and placex.class = place_to_be_deleted.class
and placex.type = place_to_be_deleted.type
and not deferred;
UPDATE placex SET indexed_status = 100 FROM place_to_be_deleted
WHERE placex.osm_type = 'W' and place_to_be_deleted.osm_type = 'W'
and placex.osm_id = place_to_be_deleted.osm_id
and placex.class = place_to_be_deleted.class
and placex.type = place_to_be_deleted.type
and not deferred;
UPDATE placex SET indexed_status = 100 FROM place_to_be_deleted
WHERE placex.osm_type = 'R' and place_to_be_deleted.osm_type = 'R'
and placex.osm_id = place_to_be_deleted.osm_id
and placex.class = place_to_be_deleted.class
and placex.type = place_to_be_deleted.type
and not deferred;
-- Mark for delete in interpolations
UPDATE location_property_osmline SET indexed_status = 100 FROM place_to_be_deleted
WHERE place_to_be_deleted.osm_type = 'W'
and place_to_be_deleted.class = 'place'
and place_to_be_deleted.type = 'houses'
and location_property_osmline.osm_id = place_to_be_deleted.osm_id
and not deferred;
-- Clear todo list.
TRUNCATE TABLE place_to_be_deleted;
RETURN NULL;
END;
$$ LANGUAGE plpgsql;

View File

@ -12,6 +12,7 @@ import pytest
from nominatim.errors import UsageError from nominatim.errors import UsageError
from nominatim.tools import admin from nominatim.tools import admin
from nominatim.tokenizer import factory from nominatim.tokenizer import factory
from nominatim.db.sql_preprocessor import SQLPreprocessor
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def create_placex_table(project_env, tokenizer_mock, temp_db_cursor, placex_table): def create_placex_table(project_env, tokenizer_mock, temp_db_cursor, placex_table):
@ -75,8 +76,8 @@ def test_analyse_indexing_with_osm_id(project_env, temp_db_cursor):
class TestAdminCleanDeleted: class TestAdminCleanDeleted:
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def setup_polygon_delete(self, project_env, table_factory, temp_db_cursor): def setup_polygon_delete(self, project_env, table_factory, place_table, osmline_table, temp_db_cursor, temp_db_conn, def_config, src_dir):
""" Set up import_polygon_delete table and simplified place_force_delete function """ Set up place_force_delete function and related tables
""" """
self.project_env = project_env self.project_env = project_env
self.temp_db_cursor = temp_db_cursor self.temp_db_cursor = temp_db_cursor
@ -88,51 +89,33 @@ class TestAdminCleanDeleted:
((100, 'N', 'boundary', 'administrative'), ((100, 'N', 'boundary', 'administrative'),
(145, 'N', 'boundary', 'administrative'), (145, 'N', 'boundary', 'administrative'),
(175, 'R', 'landcover', 'grass'))) (175, 'R', 'landcover', 'grass')))
temp_db_cursor.execute("""INSERT INTO placex (place_id, osm_id, osm_type, class, type, indexed_date, indexed_status)
VALUES(1, 100, 'N', 'boundary', 'administrative', current_date - INTERVAL '1 month', 1),
(2, 145, 'N', 'boundary', 'administrative', current_date - INTERVAL '1 month', 1),
(3, 175, 'R', 'landcover', 'grass', current_date - INTERVAL '1 month', 1)""")
# set up tables and triggers for utils function
table_factory('place_to_be_deleted', table_factory('place_to_be_deleted',
"""osm_id BIGINT, """osm_id BIGINT,
osm_type CHAR(1), osm_type CHAR(1),
class TEXT NOT NULL, class TEXT NOT NULL,
type TEXT NOT NULL, type TEXT NOT NULL,
deferred BOOLEAN""") deferred BOOLEAN""")
temp_db_cursor.execute("""INSERT INTO placex (place_id, osm_id, osm_type, class, type, indexed_date, indexed_status) table_factory('country_name', 'partition INT')
VALUES(1, 100, 'N', 'boundary', 'administrative', current_date - INTERVAL '1 month', 1), table_factory('import_polygon_error', """osm_id BIGINT,
(2, 145, 'N', 'boundary', 'administrative', current_date - INTERVAL '1 month', 1), osm_type CHAR(1),
(3, 175, 'R', 'landcover', 'grass', current_date - INTERVAL '1 month', 1)""") class TEXT NOT NULL,
temp_db_cursor.execute("""CREATE OR REPLACE FUNCTION flush_deleted_places() type TEXT NOT NULL""")
RETURNS INTEGER temp_db_cursor.execute("""CREATE OR REPLACE FUNCTION place_delete()
AS $$ RETURNS TRIGGER AS $$
BEGIN BEGIN RETURN NULL; END;
UPDATE placex p SET indexed_status = 100 FROM place_to_be_deleted d $$ LANGUAGE plpgsql;""")
WHERE p.osm_type = d.osm_type temp_db_cursor.execute("""CREATE TRIGGER place_before_delete BEFORE DELETE ON place
AND p.osm_id = d.osm_id FOR EACH ROW EXECUTE PROCEDURE place_delete();""")
AND p.class = d.class orig_sql = def_config.lib_dir.sql
AND p.type = d.type def_config.lib_dir.sql = src_dir / 'lib-sql'
AND NOT deferred; sqlproc = SQLPreprocessor(temp_db_conn, def_config)
TRUNCATE TABLE place_to_be_deleted; sqlproc.run_sql_file(temp_db_conn, 'functions/utils.sql')
RETURN NULL; def_config.lib_dir.sql = orig_sql
END;
$$
LANGUAGE plpgsql;
""")
temp_db_cursor.execute("""CREATE OR REPLACE FUNCTION place_force_delete(placeid BIGINT)
RETURNS BOOLEAN
AS $$
DECLARE
osmid BIGINT;
osmtype character(1);
pclass text;
ptype text;
BEGIN
SELECT osm_type, osm_id, class, type FROM placex WHERE place_id = placeid INTO osmtype, osmid, pclass, ptype;
DELETE FROM import_polygon_delete WHERE osm_type = osmtype AND osm_id = osmid AND class = pclass AND type = ptype;
INSERT INTO place_to_be_deleted (osm_type, osm_id, class, type, deferred)
VALUES(osmtype, osmid, pclass, ptype, false);
PERFORM flush_deleted_places();
RETURN TRUE;
END;
$$
LANGUAGE plpgsql;
""")
def test_admin_clean_deleted_no_records(self): def test_admin_clean_deleted_no_records(self):