resily
Database
Tables
(current)
Columns
Constraints
Relationships
Orphan Tables
Anomalies
Routines
copy_okr_nodes
Parameters
Name
Type
Mode
organization_id
bigint
IN
old_okr_term_id
bigint
IN
new_okr_term_id
bigint
IN
Definition
DECLARE old_node RECORD; new_node_id int8; mapping hstore DEFAULT ''; BEGIN FOR old_node IN SELECT okr_nodes.id, okr_nodes.created_at, okr_nodes.updated_at, okr_nodes.display_order, okr_nodes.disabled_at FROM okr_nodes INNER JOIN objectives ON objectives.okr_node_id = okr_nodes.id AND objectives.disabled_at IS NULL WHERE okr_nodes.okr_term_id = old_okr_term_id LOOP -- 新しい okr_nodes を作成する。この時点では path を作れないので空にする EXECUTE $SQL$ INSERT INTO okr_nodes ("path", "organization_id", "okr_term_id", "created_at", "updated_at", "display_order", "disabled_at") VALUES ('', $1, $2, $3, $4, $5, $6) RETURNING id; $SQL$ INTO new_node_id USING organization_id, new_okr_term_id, old_node.created_at, old_node.updated_at, old_node.display_order, old_node.disabled_at; -- どの okr_node をコピーして新しい okr_node を作ったかわかるように id のマッピングを作る mapping := mapping || hstore(old_node.id::text, new_node_id::text); END LOOP; -- 新旧の ID のマッピングから path を作成して更新する FOR old_node IN SELECT id, path, updated_at FROM okr_nodes WHERE okr_term_id = old_okr_term_id ORDER BY id LOOP DECLARE path_iterator text DEFAULT ''; paths text[] DEFAULT '{}'; BEGIN -- old_node.path を '.' で分割して配列に変換する。 -- その後、mappingと付け合わせて新しい ID に変換する。 -- ID の配列を paths として格納する。 FOREACH path_iterator IN ARRAY string_to_array(old_node.path::text, '.') LOOP paths := array_append(paths, mapping -> path_iterator); END LOOP; -- paths を '.' で結合して新しい okr_node を更新する EXECUTE $SQL$ UPDATE okr_nodes SET path = $1::ltree, updated_at = $2 WHERE id = $3; $SQL$ USING array_to_string(paths, '.'), old_node.updated_at, (mapping -> old_node.id::text)::int8; END; END LOOP; RETURN mapping; END;