AddAssetFmecaSyncFunctionsMigration
| Database |
Schema |
Description |
| Transaction |
ampc |
Add functions for Asset Fmeca sync. |
SQL Statements
DROP FUNCTION IF EXISTS ampc.asset_fmecas_starting_at_asset;
CREATE FUNCTION ampc.asset_fmecas_starting_at_asset(starting_asset_id bigint, starting_record_type ampc.asset_record_type[]) RETURNS TABLE (id bigint)
LANGUAGE SQL
AS $BODY$
WITH ids AS
(
SELECT
fmeca.asset_fmeca_id
FROM
ampc.asset asset
JOIN ampc.asset_fmeca fmeca ON asset.asset_id = fmeca.asset_id
WHERE
asset.asset_id = $1 AND
asset.record_type = ANY($2) AND
fmeca.asset_fmeca_id > 0
)
SELECT * FROM ids
UNION ALL
SELECT fmeca.asset_fmeca_id FROM ids JOIN ampc.asset_fmeca fmeca ON (ids.asset_fmeca_id * -1) = fmeca.asset_fmeca_id;
$BODY$;
DROP FUNCTION IF EXISTS ampc.asset_fmecas_starting_at_asset_fmeca;
CREATE FUNCTION ampc.asset_fmecas_starting_at_asset_fmeca(asset_fmeca_id bigint) RETURNS TABLE (id bigint)
LANGUAGE SQL
AS $BODY$
WITH ids AS
(
SELECT
fmeca.asset_fmeca_id
FROM
ampc.asset_fmeca fmeca
WHERE
fmeca.asset_fmeca_id = $1 AND
fmeca.asset_fmeca_id > 0
)
SELECT * FROM ids
UNION ALL
SELECT fmeca.asset_fmeca_id FROM ids JOIN ampc.asset_fmeca fmeca ON (ids.asset_fmeca_id * -1) = fmeca.asset_fmeca_id;
$BODY$;
DROP FUNCTION IF EXISTS ampc.asset_fmecas_starting_at_asset_ic;
CREATE FUNCTION ampc.asset_fmecas_starting_at_asset_ic(starting_asset_id bigint, starting_record_type ampc.asset_record_type[]) RETURNS TABLE (id bigint)
LANGUAGE SQL
AS $BODY$
WITH ids AS
(
SELECT
fmeca.asset_fmeca_id
FROM
ampc.asset asset
JOIN ampc.asset_tree tree ON tree.path_parent_asset_id = asset.asset_id
JOIN ampc.asset casset ON tree.asset_id = casset.asset_id
JOIN ampc.asset_fmeca fmeca ON casset.asset_id = fmeca.asset_id
WHERE
asset.asset_id = $1 AND
asset.record_type = ANY($2) AND
asset.nearest_regular_asset_id = casset.nearest_regular_asset_id AND
fmeca.asset_fmeca_id > 0
)
SELECT * FROM ids
UNION ALL
SELECT fmeca.asset_fmeca_id FROM ids JOIN ampc.asset_fmeca fmeca ON (ids.asset_fmeca_id * -1) = fmeca.asset_fmeca_id;
$BODY$;
DROP FUNCTION IF EXISTS ampc.asset_fmecas_starting_at_component;
CREATE FUNCTION ampc.asset_fmecas_starting_at_component(starting_component_id bigint, starting_record_type ampc.asset_component_record_type[]) RETURNS TABLE (id bigint)
LANGUAGE SQL
AS $BODY$
WITH ids AS
(
SELECT
fmeca.asset_fmeca_id
FROM
ampc.asset_component ac
JOIN ampc.asset_fmeca fmeca ON ac.asset_component_id = fmeca.asset_component_id
WHERE
ac.asset_component_id = $1 AND
ac.record_type = ANY($2) AND
fmeca.asset_fmeca_id > 0
)
SELECT * FROM ids
UNION ALL
SELECT fmeca.asset_fmeca_id FROM ids JOIN ampc.asset_fmeca fmeca ON (ids.asset_fmeca_id * -1) = fmeca.asset_fmeca_id;
$BODY$;
DROP FUNCTION IF EXISTS ampc.asset_fmecas_starting_at_component_ic;
CREATE FUNCTION ampc.asset_fmecas_starting_at_component_ic(starting_component_id bigint, starting_record_type ampc.asset_component_record_type[]) RETURNS TABLE (id bigint)
LANGUAGE SQL
AS $BODY$
WITH ids AS
(
SELECT
fmeca.asset_fmeca_id
FROM
ampc.asset_component ac
JOIN ampc.asset_component_tree tree ON ac.asset_component_id = tree.path_parent_asset_component_id
JOIN ampc.asset_component component ON tree.asset_component_id = component.asset_component_id
JOIN ampc.asset_fmeca fmeca ON component.asset_component_id = fmeca.asset_component_id
WHERE
ac.asset_component_id = $1 AND
ac.record_type = ANY($2) AND
fmeca.asset_fmeca_id > 0
)
SELECT * FROM ids
UNION ALL
SELECT fmeca.asset_fmeca_id FROM ids JOIN ampc.asset_fmeca fmeca ON (ids.asset_fmeca_id * -1) = fmeca.asset_fmeca_id;
$BODY$;
DROP FUNCTION IF EXISTS ampc.asset_fmeca_tree_load_filter;
CREATE FUNCTION ampc.asset_fmeca_tree_load_filter(starting_entity_id bigint, starting_entity_type system.entity_type, include_children boolean)
RETURNS TABLE (id bigint)
LANGUAGE plpgsql AS
$BODY$
DECLARE
starting_entity_id ALIAS FOR $1;
starting_entity_type ALIAS FOR $2;
include_children ALIAS FOR $3;
BEGIN
IF starting_entity_type = 'RegularAsset' THEN
IF include_children THEN
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_asset_ic(starting_entity_id, ARRAY['Regular']::ampc.asset_record_type[]);
ELSE
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_asset(starting_entity_id, ARRAY['Regular']::ampc.asset_record_type[]);
END IF;
ELSEIF starting_entity_type = 'InPlaceAsset' THEN
IF include_children THEN
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_asset_ic(starting_entity_id, ARRAY['InPlace']::ampc.asset_record_type[]);
ELSE
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_asset(starting_entity_id, ARRAY['InPlace']::ampc.asset_record_type[]);
END IF;
ELSEIF starting_entity_type = 'PlaceholderAsset' THEN
IF include_children THEN
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_asset_ic(starting_entity_id, ARRAY['EmptyPlaceholder', 'LinkedPlaceholder']::ampc.asset_record_type[]);
ELSE
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_asset(starting_entity_id, ARRAY['EmptyPlaceholder', 'LinkedPlaceholder']::ampc.asset_record_type[]);
END IF;
ELSEIF starting_entity_type = 'PlaceholderAssetComponent' THEN
IF include_children THEN
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_component_ic(starting_entity_id, ARRAY['EmptyPlaceholder', 'LinkedPlaceholder']::ampc.asset_component_record_type[]);
ELSE
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_component(starting_entity_id, ARRAY['EmptyPlaceholder', 'LinkedPlaceholder']::ampc.asset_component_record_type[]);
END IF;
ELSEIF starting_entity_type = 'RegularAssetComponent' THEN
IF include_children THEN
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_component_ic(starting_entity_id, ARRAY['Regular']::ampc.asset_component_record_type[]);
ELSE
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_component(starting_entity_id, ARRAY['Regular']::ampc.asset_component_record_type[]);
END IF;
ELSEIF starting_entity_type = 'AssetFmeca' THEN
RETURN QUERY SELECT * FROM ampc.asset_fmecas_starting_at_asset_fmeca(starting_entity_id);
ELSE
RAISE EXCEPTION 'Incorrect starting_entity_type: %', starting_entity_type;
END IF;
END;
$BODY$;
CREATE OR REPLACE FUNCTION ampc.asset_fmeca_path(asset_fmeca_id bigint)
RETURNS TABLE
(
entity_type system.entity_type,
record_type text,
entity_id bigint,
entity_code text,
type_order int,
tree_level int,
path_order bigint
)
AS $$
WITH fmeca AS
(
SELECT
3 AS type_order,
f.linked_to_entity_type AS entity_type,
CASE WHEN c.asset_component_id IS NULL THEN a.record_type::TEXT ELSE c.record_type::TEXT END AS record_type,
f.asset_fmeca_id AS entity_id,
'' AS entity_code,
1 AS tree_level,
CASE WHEN f.asset_component_id IS NOT NULL THEN 'Component' ELSE 'Type' END AS parent_entity_type,
CASE WHEN f.asset_component_id IS NOT NULL THEN f.asset_component_id ELSE f.asset_id END AS parent_entity_id
FROM
ampc.asset_fmeca f
JOIN ampc.asset a ON a.asset_id = f.asset_id
LEFT JOIN ampc.asset_component c ON c.asset_component_id = f.asset_component_id
WHERE
f.asset_fmeca_id = $1
LIMIT 1
),
components AS
(
SELECT * FROM fmeca
UNION ALL
SELECT
2 AS type_order,
ampc.asset_component_record_type_entity(ac.record_type) AS entity_type,
ac.record_type::text,
t.path_parent_asset_component_id AS entity_id,
ac.code AS entity_code,
t.path_parent_asset_component_tree_level AS tree_level,
CASE WHEN ac.parent_component_id IS NOT NULL THEN 'Component' ELSE 'Type' END AS parent_entity_type,
CASE WHEN ac.parent_component_id IS NOT NULL THEN ac.parent_component_id ELSE ac.asset_id END AS parent_entity_id
FROM
ampc.asset_component_tree t
JOIN ampc.asset_component ac ON t.path_parent_asset_component_id = ac.asset_component_id
WHERE
t.asset_component_id =
(
SELECT
CASE WHEN parent_entity_type = 'Component' THEN parent_entity_id ELSE NULL END
FROM
fmeca LIMIT 1
)
),
assets AS
(
SELECT * FROM components
UNION ALL
SELECT
1 AS type_order,
ampc.asset_record_type_entity(a.record_type) AS entity_type,
a.record_type::text,
t.path_parent_asset_id AS entity_id,
a.code AS entity_code,
t.path_parent_asset_tree_level AS tree_level,
null AS parent_entity_type,
null AS parent_entity_id
FROM
ampc.asset_tree t
JOIN ampc.asset a ON t.path_parent_asset_id = a.asset_id
WHERE
t.asset_id =
(
SELECT CASE WHEN (SELECT parent_entity_type FROM fmeca LIMIT 1) = 'Component' THEN
(
SELECT
asset_id
FROM
ampc.asset_component
WHERE
asset_component_id =
(
SELECT
entity_id
FROM
components
WHERE
(entity_type = 'RegularAssetComponent'::system.entity_type OR entity_type = 'PlaceholderAssetComponent'::system.entity_type) AND
tree_level = 1
LIMIT 1
)
)
ELSE
(
SELECT parent_entity_id FROM fmeca LIMIT 1
) END
)
)
SELECT
entity_type,
record_type,
entity_id,
entity_code,
type_order,
tree_level,
row_number() OVER (ORDER BY type_order, tree_level) AS path_order
FROM
assets
ORDER BY
type_order,
tree_level;
$$ LANGUAGE sql;
DROP FUNCTION IF EXISTS ampc.asset_fmeca_function_remapping;
CREATE FUNCTION ampc.asset_fmeca_function_remapping(assetFmecaIds bigint[])
RETURNS TABLE
(
asset_fmeca_id bigint,
target_asset_function_id bigint
)
AS $$
SELECT
af.asset_fmeca_id,
link_target.asset_function_id AS target_asset_function_id
FROM
unnest($1) i
JOIN ampc.asset_fmeca af ON i = af.asset_fmeca_id
JOIN ampc.asset_type_fmeca atf ON af.inherited_from_id = atf.asset_type_fmeca_id
JOIN ampc.asset_type_fmeca parent_fmeca ON atf.asset_type_fmeca_id = parent_fmeca.asset_type_fmeca_id
JOIN ampc.asset_type pfmeca_type ON parent_fmeca.asset_type_id = pfmeca_type.asset_type_id
JOIN ampc.asset_type_function target_function ON atf.asset_type_function_id = target_function.asset_type_function_id
JOIN ampc.asset_type tfunction_type ON target_function.asset_type_id = tfunction_type.asset_type_id
JOIN ampc.asset_fmeca inh_parent_fmeca ON af.asset_fmeca_id = inh_parent_fmeca.asset_fmeca_id
JOIN ampc.asset inh_parent_asset ON inh_parent_fmeca.asset_id = inh_parent_asset.asset_id
JOIN LATERAL (
SELECT
entity_type AS target_boundary_type,
entity_id AS target_boundary_id
FROM
ampc.asset_fmeca_path(af.asset_fmeca_id)
WHERE
entity_type = 'RegularAsset' OR
entity_type = 'PlaceholderAsset' OR
entity_type = 'PlaceholderAssetComponent'
ORDER BY path_order DESC
LIMIT 1
) inh_fmeca_path ON true
JOIN LATERAL (
SELECT
f.asset_function_id,
f.inherited_from_id,
f.asset_component_id,
f.asset_id,
a.nearest_regular_asset_id
FROM
ampc.asset_function f
JOIN ampc.asset a ON f.asset_id = a.asset_id
WHERE
f.inherited_from_id = target_function.asset_type_function_id AND
a.nearest_regular_asset_id = inh_parent_asset.nearest_regular_asset_id
) link_target ON true
WHERE
link_target.asset_function_id > 0 AND
CASE
WHEN target_boundary_type = 'PlaceholderAssetComponent' AND (SELECT EXISTS(SELECT * FROM ampc.asset_component WHERE asset_component_id = target_boundary_id AND linked_on_type_side = false AND linked_to_asset_type_id = pfmeca_type.nearest_regular_asset_type_id)) THEN
link_target.asset_component_id = ANY(SELECT asset_component_id FROM ampc.asset_component_tree WHERE path_parent_asset_component_id = target_boundary_id) AND
target_boundary_id = (SELECT entity_id FROM ampc.asset_fmeca_path(i) WHERE entity_type = 'PlaceholderAssetComponent' ORDER BY path_order DESC LIMIT 1)
--We don't really know how asset placeholders will work yet
--WHEN target_boundary_type = 'PlaceholderAsset' AND (SELECT EXISTS(SELECT * FROM ampc.asset WHERE asset_id = target_boundary_id AND linked_to_asset_type_id = pfmeca_type.nearest_regular_asset_type_id)) THEN
-- link_target.asset_type_id = ANY(SELECT asset_type_id FROM ampc.asset_type_tree WHERE path_parent_asset_type_id = target_boundary_id) --AND
ELSE
link_target.nearest_regular_asset_id = inh_parent_asset.nearest_regular_asset_id
END;
$$ LANGUAGE sql;