From c86f5471aa1ea550c05cec98735e40ade870f9be Mon Sep 17 00:00:00 2001 From: Chad Burt Date: Sun, 17 Nov 2024 17:29:08 -0800 Subject: [PATCH] Update sourceLayer on data library derived layers when updating --- packages/api/migrations/committed/000343.sql | 132 +++++++ packages/api/schema.sql | 376 ++++++++++++++++--- 2 files changed, 462 insertions(+), 46 deletions(-) create mode 100644 packages/api/migrations/committed/000343.sql diff --git a/packages/api/migrations/committed/000343.sql b/packages/api/migrations/committed/000343.sql new file mode 100644 index 00000000..d7509f99 --- /dev/null +++ b/packages/api/migrations/committed/000343.sql @@ -0,0 +1,132 @@ +--! Previous: sha1:88ea156673a7d82b63e484ab0d633bddc174a5e0 +--! Hash: sha1:7b3014cc9d2637d62f0fee1b2ea18fb6d5266dc1 + +-- Enter migration here +CREATE OR REPLACE FUNCTION public.replace_data_source(data_layer_id integer, data_source_id integer, source_layer text, bounds numeric[], gl_styles jsonb) RETURNS void + LANGUAGE plpgsql SECURITY DEFINER + AS $$ + declare + old_source_id integer; + old_source_type text; + old_metadata_is_dynamic boolean; + dl_template_id text; + begin + -- first, determine if a related table_of_contents_item has + -- data_library_template_id set. If so, we need to update the + -- related Toc items that have copied_from_data_library_template_id + -- matching. + + select data_library_template_id into dl_template_id from table_of_contents_items where table_of_contents_items.data_layer_id = replace_data_source.data_layer_id and data_library_template_id is not null limit 1; + + if dl_template_id is null then + raise exception 'fuck you %', dl_template_id; + end if; + + select data_layers.data_source_id into old_source_id from data_layers where id = replace_data_source.data_layer_id; + select type into old_source_type from data_sources where id = old_source_id; + select metadata is null and (old_source_type = 'arcgis-vector' or old_source_type = 'arcgis-dynamic-mapserver') into old_metadata_is_dynamic from table_of_contents_items where table_of_contents_items.data_layer_id = replace_data_source.data_layer_id limit 1; + insert into archived_data_sources ( + data_source_id, + data_layer_id, + version, + mapbox_gl_style, + changelog, + source_layer, + bounds, + sublayer, + sublayer_type, + dynamic_metadata, + project_id + ) values ( + old_source_id, + replace_data_source.data_layer_id, + ( + select + coalesce(max(version), 0) + 1 + from + archived_data_sources + where archived_data_sources.data_layer_id = replace_data_source.data_layer_id + ), + ( + select + mapbox_gl_styles + from + data_layers + where id = replace_data_source.data_layer_id + ), + (select changelog from data_sources where id = replace_data_source.data_source_id), + (select data_layers.source_layer from data_layers where data_layers.id = replace_data_source.data_layer_id), + (select table_of_contents_items.bounds from table_of_contents_items where table_of_contents_items.data_layer_id = replace_data_source.data_layer_id and table_of_contents_items.bounds is not null limit 1), + (select sublayer from data_layers where id = data_layer_id), + (select sublayer_type from data_layers where id = data_layer_id), + old_metadata_is_dynamic, + (select project_id from data_sources where id = replace_data_source.data_source_id) + ); + + if dl_template_id is not null then + update + data_sources + set data_library_template_id = dl_template_id + where + id = replace_data_source.data_source_id or + id = any(( + select + data_layers.data_source_id + from + data_layers + where + id = any ( + select + table_of_contents_items.data_layer_id + from + table_of_contents_items + where + copied_from_data_library_template_id = dl_template_id or + data_library_template_id = dl_template_id + ) + )) or id = any (( + select + data_layers.data_source_id + from + data_layers + where + id = replace_data_source.data_layer_id + )); + end if; + + update + data_layers + set + data_source_id = replace_data_source.data_source_id, + source_layer = replace_data_source.source_layer, + mapbox_gl_styles = coalesce( + gl_styles, data_layers.mapbox_gl_styles + ), + sublayer = null + where + id = replace_data_source.data_layer_id; + + if dl_template_id is not null then + update + data_layers + set + data_source_id = replace_data_source.data_source_id, + source_layer = replace_data_source.source_layer + where + id = any ( + select table_of_contents_items.data_layer_id from table_of_contents_items where copied_from_data_library_template_id = dl_template_id + ); + end if; + + update + table_of_contents_items + set bounds = replace_data_source.bounds + where + table_of_contents_items.data_layer_id = replace_data_source.data_layer_id or ( + case + when dl_template_id is not null then copied_from_data_library_template_id = dl_template_id + else false + end + ); + end; + $$; diff --git a/packages/api/schema.sql b/packages/api/schema.sql index 04a17b98..14912521 100644 --- a/packages/api/schema.sql +++ b/packages/api/schema.sql @@ -2923,12 +2923,12 @@ CREATE TABLE public.archived_data_sources ( sprite_ids integer[] GENERATED ALWAYS AS (public.extract_sprite_ids((mapbox_gl_style)::text)) STORED, changelog text, source_layer text, + project_id integer NOT NULL, bounds numeric[], created_at timestamp with time zone DEFAULT now(), sublayer text, sublayer_type public.sublayer_type, - dynamic_metadata boolean DEFAULT false NOT NULL, - project_id integer NOT NULL + dynamic_metadata boolean DEFAULT false NOT NULL ); @@ -5286,6 +5286,7 @@ CREATE TABLE public.table_of_contents_items ( translated_props jsonb DEFAULT '{}'::jsonb NOT NULL, fts_simple tsvector GENERATED ALWAYS AS (public.toc_to_tsvector('simple'::text, title, metadata, translated_props)) STORED, fts_en tsvector GENERATED ALWAYS AS (public.toc_to_tsvector('english'::text, title, metadata, translated_props)) STORED, + fts_es tsvector GENERATED ALWAYS AS (public.toc_to_tsvector('spanish'::text, title, metadata, translated_props)) STORED, fts_pt tsvector GENERATED ALWAYS AS (public.toc_to_tsvector('portuguese'::text, title, metadata, translated_props)) STORED, fts_ar tsvector GENERATED ALWAYS AS (public.toc_to_tsvector('arabic'::text, title, metadata, translated_props)) STORED, fts_da tsvector GENERATED ALWAYS AS (public.toc_to_tsvector('danish'::text, title, metadata, translated_props)) STORED, @@ -5299,7 +5300,6 @@ CREATE TABLE public.table_of_contents_items ( fts_ro tsvector GENERATED ALWAYS AS (public.toc_to_tsvector('romanian'::text, title, metadata, translated_props)) STORED, fts_ru tsvector GENERATED ALWAYS AS (public.toc_to_tsvector('russian'::text, title, metadata, translated_props)) STORED, fts_sv tsvector GENERATED ALWAYS AS (public.toc_to_tsvector('swedish'::text, title, metadata, translated_props)) STORED, - fts_es tsvector GENERATED ALWAYS AS (public.toc_to_tsvector('spanish'::text, title, metadata, translated_props)) STORED, data_source_type text, original_source_upload_available boolean DEFAULT false NOT NULL, data_library_template_id text, @@ -6136,6 +6136,22 @@ CREATE FUNCTION public.copy_table_of_contents_item(item_id integer, copy_data_so $$; +-- +-- Name: copy_table_of_contents_item_recursive(integer, boolean, boolean, integer); Type: FUNCTION; Schema: public; Owner: - +-- + +CREATE FUNCTION public.copy_table_of_contents_item_recursive(item_id integer, copy_data_source boolean, append_copy_to_name boolean, project_id integer) RETURNS integer + LANGUAGE plpgsql SECURITY DEFINER + AS $$ + declare + copy_id int; + child record; + begin + copy_id := copy_table_of_contents_item(item_id, copy_data_source, append_copy_to_name, project_id); + end; + $$; + + -- -- Name: copy_table_of_contents_item_recursive(integer, boolean, boolean, integer, public.ltree, text); Type: FUNCTION; Schema: public; Owner: - -- @@ -8194,9 +8210,9 @@ CREATE TABLE public.data_sources ( was_converted_from_esri_feature_layer boolean DEFAULT false NOT NULL, created_by integer, changelog text, + raster_representative_colors jsonb GENERATED ALWAYS AS (public.get_representative_colors(geostats)) STORED, raster_offset real GENERATED ALWAYS AS (public.get_first_band_offset(geostats)) STORED, raster_scale real GENERATED ALWAYS AS (public.get_first_band_scale(geostats)) STORED, - raster_representative_colors jsonb GENERATED ALWAYS AS (public.get_representative_colors(geostats)) STORED, data_library_template_id text, CONSTRAINT data_sources_buffer_check CHECK (((buffer >= 0) AND (buffer <= 512))), CONSTRAINT data_sources_tile_size_check CHECK (((tile_size = 128) OR (tile_size = 256) OR (tile_size = 512))) @@ -10254,7 +10270,7 @@ COMMENT ON FUNCTION public.get_sprite_data_for_screenshot(bookmark public.map_bo CREATE FUNCTION public.get_supported_languages() RETURNS jsonb LANGUAGE sql IMMUTABLE AS $$ - select '{"simple": "simple", "english": "EN", "spanish": "es", "portuguese": "pt", "arabic": "ar", "danish": "da", "dutch": "nl", "french": "fr", "german": "de", "indonesian": "id", "italian": "it", "lithuanian": "lt", "norwegian": "no", "romanian": "ro", "russian": "ru", "swedish": "sv"}'::jsonb; + select '{"simple": "simple", "english": "en", "spanish": "es", "portuguese": "pt", "arabic": "ar", "danish": "da", "dutch": "nl", "french": "fr", "german": "de", "greek": "el", "indonesian": "id", "italian": "it", "lithuanian": "lt", "norwegian": "no", "romanian": "ro", "russian": "ru", "swedish": "sv"}'::jsonb; $$; @@ -10329,23 +10345,6 @@ CREATE FUNCTION public.has_session() RETURNS boolean COMMENT ON FUNCTION public.has_session() IS '@omit'; --- --- Name: id_lookup_get_key(integer); Type: FUNCTION; Schema: public; Owner: - --- - -CREATE FUNCTION public.id_lookup_get_key(key integer) RETURNS integer - LANGUAGE plpgsql - AS $$ - begin - if lookup is null then - raise exception 'lookup is null'; - else - return (lookup->key)::int; - end if; - end; - $$; - - -- -- Name: id_lookup_get_key(jsonb, integer); Type: FUNCTION; Schema: public; Owner: - -- @@ -14468,7 +14467,8 @@ CREATE FUNCTION public.replace_data_source(data_layer_id integer, data_source_id update data_layers set - data_source_id = replace_data_source.data_source_id + data_source_id = replace_data_source.data_source_id, + source_layer = replace_data_source.source_layer where id = any ( select table_of_contents_items.data_layer_id from table_of_contents_items where copied_from_data_library_template_id = dl_template_id @@ -14670,25 +14670,309 @@ CREATE FUNCTION public.search_overlays(lang text, query text, "projectId" intege LANGUAGE plpgsql STABLE SECURITY DEFINER AS $$ declare - q tsquery := websearch_to_tsquery('english'::regconfig, query); + supported_languages jsonb := get_supported_languages(); + config regconfig; + q tsquery := websearch_to_tsquery(config, query); begin + select key::regconfig into config from jsonb_each_text(get_supported_languages()) where value = lower(lang); IF position(' ' in query) <= 0 THEN - q := to_tsquery('english'::regconfig, query || ':*'); + q := to_tsquery(config, query || ':*'); + end if; + if config is null then + q = plainto_tsquery('simple', query); + IF position(' ' in query) <= 0 THEN + q := to_tsquery('simple', query || ':*'); + end if; + -- use the simple index + return query select + id, + stable_id, + ts_headline('simple', title, q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline('simple', jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_simple @@ q + limit + coalesce("limit", 10); + elsif config = 'english'::regconfig then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_en @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'es' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_es @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'pt' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline('portuguese', jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_pt @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'ar' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline('arabic', jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_ar @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'da' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_da @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'nl' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_nl @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'fr' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_fr @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'de' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_de @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'el' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_el @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'id' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_id @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'it' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_it @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'lt' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_lt @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'no' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_no @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'ro' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_ro @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'ru' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_ru @@ q + limit + coalesce("limit", 10); + elsif lower(lang) = 'sv' then + return query select + id, + stable_id, + ts_headline(config, coalesce( + translated_props->lang->>'title'::text, title + ), q, 'StartSel=<<<, StopSel=>>>') as title_headline, + ts_headline(config, jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, + is_folder + from + table_of_contents_items + where + project_id = "projectId" and + is_draft = draft and + fts_sv @@ q + limit + coalesce("limit", 10); + else + raise exception 'Unsupported language: %', lang; end if; - return query select - id, - stable_id, - ts_headline('english', title, q, 'StartSel=<<<, StopSel=>>>') as title_headline, - ts_headline('english', jsonb_array_to_string(collect_prosemirror_text_nodes(metadata)), q, 'MaxFragments=10, MaxWords=7, MinWords=3, StartSel=<<<, StopSel=>>>') as metadata_headline, - is_folder - from - table_of_contents_items - where - project_id = "projectId" and - is_draft = draft and - fts_en @@ q - limit - coalesce("limit", 10); end; $$; @@ -25971,6 +26255,13 @@ GRANT ALL ON FUNCTION public.copy_sketch_toc_item_recursive_for_forum(parent_id REVOKE ALL ON FUNCTION public.copy_table_of_contents_item(item_id integer, copy_data_source boolean, append_copy_to_name boolean, "projectId" integer, lpath public.ltree, "parentStableId" text) FROM PUBLIC; +-- +-- Name: FUNCTION copy_table_of_contents_item_recursive(item_id integer, copy_data_source boolean, append_copy_to_name boolean, project_id integer); Type: ACL; Schema: public; Owner: - +-- + +REVOKE ALL ON FUNCTION public.copy_table_of_contents_item_recursive(item_id integer, copy_data_source boolean, append_copy_to_name boolean, project_id integer) FROM PUBLIC; + + -- -- Name: FUNCTION copy_table_of_contents_item_recursive(item_id integer, copy_data_source boolean, append_copy_to_name boolean, project_id integer, lpath public.ltree, parent_stable_id text); Type: ACL; Schema: public; Owner: - -- @@ -28162,13 +28453,6 @@ REVOKE ALL ON FUNCTION public.hmac(bytea, bytea, text) FROM PUBLIC; REVOKE ALL ON FUNCTION public.hmac(text, text, text) FROM PUBLIC; --- --- Name: FUNCTION id_lookup_get_key(key integer); Type: ACL; Schema: public; Owner: - --- - -REVOKE ALL ON FUNCTION public.id_lookup_get_key(key integer) FROM PUBLIC; - - -- -- Name: FUNCTION id_lookup_get_key(lookup jsonb, key integer); Type: ACL; Schema: public; Owner: - --