From 699c949d8ec1260ca12dfbfa05c404be7395c9cc Mon Sep 17 00:00:00 2001 From: Wojtek Kosior Date: Sat, 3 Sep 2022 17:41:16 +0200 Subject: [proxy] fix a bug that caused mappings to be marked as required even after they stopped being required --- .../_operations/recompute_dependencies.py | 97 ++++++++++++++++++++-- 1 file changed, 90 insertions(+), 7 deletions(-) (limited to 'src/hydrilla/proxy/state_impl/_operations') diff --git a/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py b/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py index 9419f91..7539e29 100644 --- a/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py +++ b/src/hydrilla/proxy/state_impl/_operations/recompute_dependencies.py @@ -88,11 +88,79 @@ def _get_current_required_state( # 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' + # The mappings to make exception for are passed by their item_id's. First, + # we compute a set of their corresponding item_version_id's. + with base.temporary_ids_tables( + cursor = cursor, + tables = [ + ('__work_ids_0', unlocked_required_mappings), + ('__work_ids_1', []), + ('__unlocked_ids', []) + ] ): + cursor.execute( + ''' + INSERT INTO + __work_ids_1 + SELECT + item_version_id + FROM + item_versions + WHERE + item_id IN __work_ids_0; + ''' + ) + + # Recursively update the our unlocked ids collection with all mapping + # version ids that are required by mapping versions already referenced + # there. + work_tab = '__work_ids_1' + next_tab = '__work_ids_0' + + while True: + cursor.execute(f'SELECT COUNT(*) FROM {work_tab};') + + (count,), = cursor.fetchall() + + if count == 0: + break + + cursor.execute(f'DELETE FROM {next_tab};') + + cursor.execute( + f''' + INSERT INTO + {next_tab} + SELECT + item_version_id + FROM + item_versions AS iv + JOIN items AS i + USING (item_id) + JOIN mapping_statuses AS ms + USING (item_id) + JOIN resolved_required_mappings AS rrm + ON iv.item_version_id = rrm.required_mapping_id + WHERE + ms.enabled != 'E' AND + rrm.requiring_mapping_id IN {work_tab} AND + rrm.requiring_mapping_id NOT IN __unlocked_ids; + ''' + ) + + cursor.execute( + f''' + INSERT OR IGNORE INTO + __unlocked_ids + SELECT + id + FROM + {work_tab}; + ''' + ) + + work_tab, next_tab = next_tab, work_tab + # Describe all required mappings using requirement objects. cursor.execute( ''' @@ -102,8 +170,8 @@ def _get_current_required_state( item_versions_extra AS ive JOIN items AS i USING (item_id) WHERE - i.type = 'M' AND - item_id NOT IN __unlocked_ids AND + i.type = 'M' AND + ive.item_version_id NOT IN __unlocked_ids AND ive.active = 'R'; ''', ) @@ -138,7 +206,8 @@ def _get_current_required_state( JOIN items AS i_m ON iv_m.item_id = i_m.item_id WHERE - i_m.item_id NOT IN __unlocked_ids AND iv_m.active = 'R'; + iv_m.item_version_id NOT IN __unlocked_ids AND + iv_m.active = 'R'; ''', ) @@ -250,6 +319,8 @@ def _recompute_dependencies_no_state_update_no_pull_files( cursor.execute('DELETE FROM payloads;') + cursor.execute('DELETE FROM resolved_required_mappings;') + for choice in mapping_choices.values(): mapping_ver_id = mappings_to_ids[choice.info] @@ -294,6 +365,18 @@ def _recompute_dependencies_no_state_update_no_pull_files( ('R' if choice.required else 'A', mapping_ver_id) ) + for depended_mapping_info in choice.mapping_dependencies: + cursor.execute( + ''' + INSERT INTO resolved_required_mappings( + requiring_mapping_id, + required_mapping_id + ) + VALUES (?, ?); + ''', + (mapping_ver_id, mappings_to_ids[depended_mapping_info]) + ) + for num, (pattern, payload) in enumerate(choice.payloads.items()): cursor.execute( ''' -- cgit v1.2.3