diff --git a/migrations/000.492.sql b/migrations/000.492.sql new file mode 100644 index 0000000..d6ff6cf --- /dev/null +++ b/migrations/000.492.sql @@ -0,0 +1,168 @@ +-- Add support for category url slugs that are not based on the displayed category name +-- And let Japan have Japanese category names, but English category urls. + +-- 1. Add category_texts.display_name, default null +ALTER TABLE category_texts ADD COLUMN IF NOT EXISTS display_name TEXT; +COMMENT ON COLUMN category_texts.display_name IS 'Optional display name for the category. If null, the name column will be used. +Intended use is for non western languages with characters that our getsafexmlpath() function is not able to create websafe slugs from'; +COMMENT ON COLUMN category_texts.name IS 'The url slug is created from this column'; + +-- 2. Populate display_name for Japanese. (which already has English in name, and Japanese in wallpaper_name) +UPDATE category_texts SET display_name = wallpaper_name where locale_id = (select id from locales where value = 'ja_JP'); + +-- 3. Adjust views +-- v_esales_categorytree_i18n_unmaterialized.name = COALESCE(category_texts.display_name, category_texts.name) +CREATE OR REPLACE VIEW v_esales_categorytree_i18n_unmaterialized AS +SELECT main.id, + main.parent_id, + main.locale_id, + main.locale, + COALESCE(main.display_name, main.name) AS name, + main.path, + main.is_leaf, + main.depth, + main.child_count, + main.lft, + main.rgt + FROM ( SELECT c.id, + ( SELECT s.id + FROM categories s + WHERE s.lft < c.lft AND s.rgt > c.rgt + ORDER BY (s.rgt - c.rgt) + LIMIT 1) AS parent_id, + c.locale_id, + c.locale, + c.name, + c.display_name, + ( SELECT lower(array_to_string(array_agg(main_1.parent_name), '/'::text)) AS path + FROM ( SELECT node.id, + ( SELECT category_texts.name + FROM category_texts + WHERE category_texts.locale_id = c.locale_id AND category_texts.category_id = parent.id) AS parent_name + FROM categories node, + categories parent + WHERE node.lft >= parent.lft AND node.lft <= parent.rgt AND node.id = c.id + ORDER BY parent.lft) main_1 + GROUP BY main_1.id) AS path, + CASE c.rgt - c.lft + WHEN 1 THEN 1 + ELSE 0 + END AS is_leaf, + ( SELECT count(*) - 1 + FROM categories node, + categories parent + WHERE node.lft >= parent.lft AND node.lft <= parent.rgt AND node.id = c.id) AS depth, + ( SELECT count(*) - 1 + FROM categories c1 + WHERE c1.lft >= c.lft AND c1.lft <= c.rgt) AS child_count, + c.lft, + c.rgt + FROM ( SELECT c_1.id, + s.id AS locale_id, + s.value AS locale, + lower(s_t.name::text) AS name, + s_t.display_name, + c_1.rgt, + c_1.lft + FROM locales s + JOIN category_texts s_t ON s.id = s_t.locale_id + JOIN categories c_1 ON s_t.category_id = c_1.id + ORDER BY s.id, c_1.lft) c) main; + +-- v_product_categories.name = COALESCE(category_texts.display_name, category_texts.name) +CREATE OR REPLACE VIEW v_product_categories AS +SELECT DISTINCT tree.id, + tree.locale_id, + getsafexmlpath(tree.path::character varying, 2) AS path, + COALESCE(category_texts.display_name::varchar(255), category_texts.name) AS name, + product_category.product_id +FROM product_category + JOIN categories ON product_category.category_id = categories.id + JOIN categories hidden_category ON hidden_category.name::text = 'hidden'::text + JOIN v_esales_categorytree_i18n_unmaterialized tree ON (tree.lft < categories.lft AND tree.rgt > categories.rgt OR categories.id = tree.id) AND tree.id <> 1 AND (tree.lft < hidden_category.lft OR tree.lft > hidden_category.rgt) + JOIN category_texts ON tree.id = category_texts.category_id AND tree.locale_id = category_texts.locale_id; + +-- +-- Materialized view "public.v_esales_categorytree_i18n" +-- First we are force to drop unrelated view v_analytics_product_categories, otherwise we get: +-- ERROR: cannot drop materialized view v_esales_categorytree_i18n because other objects depend on it +-- DETAIL: view v_analytics_product_categories depends on materialized view v_esales_categorytree_i18n +DROP VIEW IF EXISTS v_analytics_product_categories; + +-- Now we update the materialized view query. Same changes as in the unmaterialized view. +DROP MATERIALIZED VIEW IF EXISTS v_esales_categorytree_i18n; +CREATE MATERIALIZED VIEW v_esales_categorytree_i18n AS +SELECT main.id, + main.parent_id, + main.locale_id, + main.locale, + COALESCE(main.display_name, main.name) AS name, + main.path, + main.is_leaf, + main.depth, + main.child_count, + main.lft, + main.rgt +FROM ( SELECT c.id, + ( SELECT s.id + FROM categories s + WHERE s.lft < c.lft AND s.rgt > c.rgt + ORDER BY (s.rgt - c.rgt) + LIMIT 1) AS parent_id, + c.locale_id, + c.locale, + c.name, + c.display_name, + ( SELECT lower(array_to_string(array_agg(main_1.parent_name), '/'::text)) AS path + FROM ( SELECT node.id, + ( SELECT category_texts.name + FROM category_texts + WHERE category_texts.locale_id = c.locale_id AND category_texts.category_id = parent.id) AS parent_name + FROM categories node, + categories parent + WHERE node.lft >= parent.lft AND node.lft <= parent.rgt AND node.id = c.id + ORDER BY parent.lft) main_1 + GROUP BY main_1.id) AS path, + CASE c.rgt - c.lft + WHEN 1 THEN 1 + ELSE 0 + END AS is_leaf, + ( SELECT count(*) - 1 + FROM categories node, + categories parent + WHERE node.lft >= parent.lft AND node.lft <= parent.rgt AND node.id = c.id) AS depth, + ( SELECT count(*) - 1 + FROM categories c1 + WHERE c1.lft >= c.lft AND c1.lft <= c.rgt) AS child_count, + c.lft, + c.rgt + FROM ( SELECT c_1.id, + s.id AS locale_id, + s.value AS locale, + lower(s_t.name::text) AS name, + s_t.display_name, + c_1.rgt, + c_1.lft + FROM locales s + JOIN category_texts s_t ON s.id = s_t.locale_id + JOIN categories c_1 ON s_t.category_id = c_1.id + ORDER BY s.id, c_1.lft) c) main; + +-- Now recreate the v_analytics_product_categories view. Exactly the same as before +CREATE VIEW v_analytics_product_categories AS +SELECT DISTINCT tree.id AS category_id, + getsafexmlpath(tree.path::character varying, 2) AS category_path, + category_texts.name AS category_name, + product_category.product_id, + GREATEST(product_category.inserted, category_texts.updated) AS last_updated +FROM product_category + JOIN categories ON product_category.category_id = categories.id + JOIN categories hidden_category ON hidden_category.name::text = 'hidden'::text + JOIN v_esales_categorytree_i18n tree ON (tree.lft < categories.lft AND tree.rgt > categories.rgt OR categories.id = tree.id) AND tree.id <> 1 AND (tree.lft < hidden_category.lft OR tree.lft > hidden_category.rgt) + JOIN category_texts ON tree.id = category_texts.category_id AND tree.locale_id = category_texts.locale_id +WHERE tree.locale_id = 3; +grant select on v_analytics_product_categories to datastudio; +grant select on v_analytics_product_categories to funnel; + +-- Recreate index as before +CREATE UNIQUE INDEX v_esales_categorytree_i18n_id_locale_id ON v_esales_categorytree_i18n USING btree (id, locale_id);