]> git.evergreen-ils.org Git - Evergreen.git/blob - Open-ILS/src/sql/Pg/upgrade/0526.schema.upgrade-dep-tracking.sql
LP#1835085: stamp DB update
[Evergreen.git] / Open-ILS / src / sql / Pg / upgrade / 0526.schema.upgrade-dep-tracking.sql
1 -- DROP objects that might have existed from a prior run of 0526
2 -- Yes this is ironic.
3 DROP TABLE IF EXISTS config.db_patch_dependencies;
4 ALTER TABLE config.upgrade_log DROP COLUMN applied_to;
5 DROP FUNCTION evergreen.upgrade_list_applied_deprecates(TEXT);
6 DROP FUNCTION evergreen.upgrade_list_applied_supersedes(TEXT);
7
8 BEGIN;
9
10 INSERT INTO config.upgrade_log (version) VALUES ('0526'); --miker
11
12 CREATE TABLE config.db_patch_dependencies (
13   db_patch      TEXT PRIMARY KEY,
14   supersedes    TEXT[],
15   deprecates    TEXT[]
16 );
17
18 CREATE OR REPLACE FUNCTION evergreen.array_overlap_check (/* field */) RETURNS TRIGGER AS $$
19 DECLARE
20     fld     TEXT;
21     cnt     INT;
22 BEGIN
23     fld := TG_ARGV[1];
24     EXECUTE 'SELECT COUNT(*) FROM '|| TG_TABLE_SCHEMA ||'.'|| TG_TABLE_NAME ||' WHERE '|| fld ||' && ($1).'|| fld INTO cnt USING NEW;
25     IF cnt > 0 THEN
26         RAISE EXCEPTION 'Cannot insert duplicate array into field % of table %', fld, TG_TABLE_SCHEMA ||'.'|| TG_TABLE_NAME;
27     END IF;
28     RETURN NEW;
29 END;
30 $$ LANGUAGE PLPGSQL;
31
32 CREATE TRIGGER no_overlapping_sups
33     BEFORE INSERT OR UPDATE ON config.db_patch_dependencies
34     FOR EACH ROW EXECUTE PROCEDURE evergreen.array_overlap_check ('supersedes');
35
36 CREATE TRIGGER no_overlapping_deps
37     BEFORE INSERT OR UPDATE ON config.db_patch_dependencies
38     FOR EACH ROW EXECUTE PROCEDURE evergreen.array_overlap_check ('deprecates');
39
40 ALTER TABLE config.upgrade_log
41     ADD COLUMN applied_to TEXT;
42
43 -- Provide a named type for patching functions
44 CREATE TYPE evergreen.patch AS (patch TEXT);
45
46 -- List applied db patches that are deprecated by (and block the application of) my_db_patch
47 CREATE OR REPLACE FUNCTION evergreen.upgrade_list_applied_deprecates ( my_db_patch TEXT ) RETURNS SETOF evergreen.patch AS $$
48     SELECT  DISTINCT l.version
49       FROM  config.upgrade_log l
50             JOIN config.db_patch_dependencies d ON (l.version::TEXT[] && d.deprecates)
51       WHERE d.db_patch = $1
52 $$ LANGUAGE SQL;
53
54 -- List applied db patches that are superseded by (and block the application of) my_db_patch
55 CREATE OR REPLACE FUNCTION evergreen.upgrade_list_applied_supersedes ( my_db_patch TEXT ) RETURNS SETOF evergreen.patch AS $$
56     SELECT  DISTINCT l.version
57       FROM  config.upgrade_log l
58             JOIN config.db_patch_dependencies d ON (l.version::TEXT[] && d.supersedes)
59       WHERE d.db_patch = $1
60 $$ LANGUAGE SQL;
61
62 -- List applied db patches that deprecates (and block the application of) my_db_patch
63 CREATE OR REPLACE FUNCTION evergreen.upgrade_list_applied_deprecated ( my_db_patch TEXT ) RETURNS TEXT AS $$
64     SELECT  db_patch
65       FROM  config.db_patch_dependencies
66       WHERE ARRAY[$1]::TEXT[] && deprecates
67 $$ LANGUAGE SQL;
68
69 -- List applied db patches that supersedes (and block the application of) my_db_patch
70 CREATE OR REPLACE FUNCTION evergreen.upgrade_list_applied_superseded ( my_db_patch TEXT ) RETURNS TEXT AS $$
71     SELECT  db_patch
72       FROM  config.db_patch_dependencies
73       WHERE ARRAY[$1]::TEXT[] && supersedes
74 $$ LANGUAGE SQL;
75
76 -- Make sure that no deprecated or superseded db patches are currently applied
77 CREATE OR REPLACE FUNCTION evergreen.upgrade_verify_no_dep_conflicts ( my_db_patch TEXT ) RETURNS BOOL AS $$
78     SELECT  COUNT(*) = 0
79       FROM  (SELECT * FROM evergreen.upgrade_list_applied_deprecates( $1 )
80                 UNION
81              SELECT * FROM evergreen.upgrade_list_applied_supersedes( $1 )
82                 UNION
83              SELECT * FROM evergreen.upgrade_list_applied_deprecated( $1 )
84                 UNION
85              SELECT * FROM evergreen.upgrade_list_applied_superseded( $1 ))x
86 $$ LANGUAGE SQL;
87
88 -- Raise an exception if there are, in fact, dep/sup confilct
89 CREATE OR REPLACE FUNCTION evergreen.upgrade_deps_block_check ( my_db_patch TEXT, my_applied_to TEXT ) RETURNS BOOL AS $$
90 DECLARE 
91     deprecates TEXT;
92     supersedes TEXT;
93 BEGIN
94     IF NOT evergreen.upgrade_verify_no_dep_conflicts( my_db_patch ) THEN
95         SELECT  STRING_AGG(patch, ', ') INTO deprecates FROM evergreen.upgrade_list_applied_deprecates(my_db_patch);
96         SELECT  STRING_AGG(patch, ', ') INTO supersedes FROM evergreen.upgrade_list_applied_supersedes(my_db_patch);
97         RAISE EXCEPTION '
98 Upgrade script % can not be applied:
99   applied deprecated scripts %
100   applied superseded scripts %
101   deprecated by %
102   superseded by %',
103             my_db_patch,
104             ARRAY_AGG(evergreen.upgrade_list_applied_deprecates(my_db_patch)),
105             ARRAY_AGG(evergreen.upgrade_list_applied_supersedes(my_db_patch)),
106             evergreen.upgrade_list_applied_deprecated(my_db_patch),
107             evergreen.upgrade_list_applied_superseded(my_db_patch);
108     END IF;
109
110     INSERT INTO config.upgrade_log (version, applied_to) VALUES (my_db_patch, my_applied_to);
111     RETURN TRUE;
112 END;
113 $$ LANGUAGE PLPGSQL;
114
115 COMMIT;