Skip to content

Commit b6be288

Browse files
committed
Must sort ACL list for comparison
1 parent 90b1ee7 commit b6be288

File tree

5 files changed

+313
-67
lines changed

5 files changed

+313
-67
lines changed

Acl.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Data.List
1212
import Debug.Trace
1313

1414
cvtacl :: String -> [Acl]
15-
cvtacl x = if (null x) then [] else map toAcl ((read ("[" ++ (tail . init) x ++ "]")) :: [String])
15+
cvtacl x = if (null x) then [] else sort $ map toAcl ((read ("[" ++ (tail . init) x ++ "]")) :: [String])
1616

1717
instance Comparable Acl where
1818
objCmp a b =

PgSchemaDiff.hs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
11
{-# LANGUAGE FlexibleInstances, QuasiQuotes #-}
22

3-
import Sqlcmds
43
import Database.HDBC
54
import Database.HDBC.PostgreSQL
65
import System.Environment
76
import Acl
87
import Proc
98
import View
9+
-- import Table
10+
-- import UDT
1011
import Trigger
1112
import Util
1213
import Str
1314

15+
16+
schemaList = [str|
17+
SELECT n.nspname AS "Name"
18+
-- ,pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
19+
FROM pg_catalog.pg_namespace n
20+
WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
21+
ORDER BY 1;
22+
|]
23+
1424
initialize args = do
1525
let conns1 = head args
1626
let conns2 = (head . tail) args
@@ -46,8 +56,10 @@ main = do
4656
"procs" -> initialize ag >>= compareProcs >>= mapM print
4757
"views" -> initialize ag >>= compareViews >>= mapM print
4858
"triggers" -> initialize ag >>= compareTriggers >>= mapM print
59+
-- "tables" -> initialize ag >>= compareTables >>= mapM print
60+
-- "types" -> initialize ag >>= compareTypes >>= mapM print
4961
otherwise -> mapM putStr [ [str|
50-
The valid comparisons are: procs, views
62+
The valid comparisons are: procs, views, triggers, tables, types
5163

5264
The arguments are:
5365
comparisonType orangeConnectionString blueConnectionString schema1 schema2

Sqlcmds.hs

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,73 +5,9 @@ module Sqlcmds where
55
import Str(str)
66

77

8-
schemaList = [str|
9-
SELECT n.nspname AS "Name"
10-
-- ,pg_catalog.pg_get_userbyid(n.nspowner) AS "Owner"
11-
FROM pg_catalog.pg_namespace n
12-
WHERE n.nspname !~ '^pg_' AND n.nspname <> 'information_schema'
13-
ORDER BY 1;
14-
|]
15-
168
-- -----------------------------------------------------------------------------------------------------
179
-- ----------------------------------------------------------------------------------------------------
1810

19-
tblList = [str|
20-
SELECT n.nspname AS "Schema", c.relname AS "Name", d.description AS "Comment",
21-
relacl AS "ACLs"
22-
FROM pg_catalog.pg_namespace n
23-
JOIN pg_catalog.pg_class c ON c.relnamespace = n.oid
24-
LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0)
25-
-- LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class')
26-
-- LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog')
27-
WHERE n.nspname IN ('account','document')
28-
AND c.relkind = 'r'
29-
AND n.nspname !~ '^pg_'
30-
AND n.nspname <> 'information_schema'
31-
ORDER BY 1, 2
32-
|]
33-
34-
tblColumns = [str|
35-
SELECT * FROM (SELECT n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) AS attnotnull,a.atttypmod,a.attlen,row_number() OVER (PARTITION BY a.attrelid ORDER BY a.attnum) AS attnum, pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,dsc.description,t.typbasetype,t.typtype FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid) JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid) JOIN pg_catalog.pg_type t ON (a.atttypid = t.oid) LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) LEFT JOIN pg_catalog.pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class') LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog')
36-
WHERE a.attnum > 0 AND NOT a.attisdropped AND n.nspname LIKE 'account' AND c.relname LIKE 'user_table') c WHERE true ORDER BY nspname,c.relname,attnum
37-
|]
38-
39-
40-
tblIndices2 = [str|
41-
SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME, CASE i.indisclustered WHEN true THEN 1 ELSE CASE am.amname WHEN 'hash' THEN 2 ELSE 3 END END AS TYPE, (i.keys).n AS ORDINAL_POSITION, pg_catalog.pg_get_indexdef(ci.oid, (i.keys).n, false) AS COLUMN_NAME, CASE am.amcanorder WHEN true THEN CASE i.indoption[(i.keys).n - 1] & 1 WHEN 1 THEN 'D' ELSE 'A' END ELSE NULL END AS ASC_OR_DESC, ci.reltuples AS CARDINALITY, ci.relpages AS PAGES, pg_catalog.pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION FROM pg_catalog.pg_class ct JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) JOIN (SELECT i.indexrelid, i.indrelid, i.indoption, i.indisunique, i.indisclustered,
42-
i.indpred, i.indexprs, information_schema._pg_expandarray(i.indkey) AS keys FROM pg_catalog.pg_index i) i ON (ct.oid = i.indrelid) JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) JOIN pg_catalog.pg_am am ON (ci.relam = am.oid) WHERE true AND n.nspname = 'account' AND ct.relname = 'user_table' ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION
43-
|]
44-
45-
tblIndices = [str|
46-
select ind.indisclustered, ind.indexrelid, ind.indisprimary, cls.relname from pg_catalog.pg_index ind, pg_catalog.pg_class tab, pg_catalog.pg_namespace sch, pg_catalog.pg_class cls where ind.indrelid = tab.oid and cls.oid = ind.indexrelid and tab.relnamespace = sch.oid and tab.relname = $1 and sch.nspname = $2
47-
|]
48-
49-
tblConstraints = [str|
50-
SELECT cons.conname, cons.conkey
51-
FROM pg_catalog.pg_constraint cons, pg_catalog.pg_class tab, pg_catalog.pg_namespace sch
52-
WHERE cons.contype = 'u' and cons.conrelid = tab.oid and tab.relnamespace = sch.oid
53-
AND tab.relname = $1 and sch.nspname = $2
54-
|]
55-
56-
tblKeysx = [str|
57-
SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, ct.relname AS TABLE_NAME, a.attname AS COLUMN_NAME, (i.keys).n AS KEY_SEQ, ci.relname AS PK_NAME FROM pg_catalog.pg_class ct JOIN pg_catalog.pg_attribute a ON (ct.oid = a.attrelid) JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) JOIN (SELECT i.indexrelid, i.indrelid, i.indisprimary, information_schema._pg_expandarray(i.indkey) AS keys FROM pg_catalog.pg_index i) i ON (a.attnum = (i.keys).x AND a.attrelid = i.indrelid) JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) WHERE true AND n.nspname = 'account' AND ct.relname = 'user_table' AND i.indisprimary ORDER BY table_name, pk_name, key_seq
58-
|]
59-
60-
tblKeys = [str|
61-
SELECT NULL::text AS PKTABLE_CAT, pkn.nspname AS PKTABLE_SCHEM, pkc.relname AS PKTABLE_NAME, pka.attname AS PKCOLUMN_NAME, NULL::text AS FKTABLE_CAT, fkn.nspname AS FKTABLE_SCHEM, fkc.relname AS FKTABLE_NAME, fka.attname AS FKCOLUMN_NAME, pos.n AS KEY_SEQ, CASE con.confupdtype WHEN 'c' THEN 0 WHEN 'n' THEN 2 WHEN 'd' THEN 4 WHEN 'r' THEN 1 WHEN 'a' THEN 3 ELSE NULL END AS UPDATE_RULE, CASE con.confdeltype WHEN 'c' THEN 0 WHEN 'n' THEN 2 WHEN 'd' THEN 4 WHEN 'r' THEN 1 WHEN 'a' THEN 3 ELSE NULL END AS DELETE_RULE, con.conname AS FK_NAME, pkic.relname AS PK_NAME, CASE WHEN con.condeferrable AND con.condeferred THEN 5 WHEN con.condeferrable THEN 6 ELSE 7 END AS DEFERRABILITY FROM pg_catalog.pg_namespace pkn, pg_catalog.pg_class pkc, pg_catalog.pg_attribute pka, pg_catalog.pg_namespace fkn, pg_catalog.pg_class fkc, pg_catalog.pg_attribute fka,
62-
pg_catalog.pg_constraint con, pg_catalog.generate_series(1, 32) pos(n), pg_catalog.pg_depend dep, pg_catalog.pg_class pkic WHERE pkn.oid = pkc.relnamespace AND pkc.oid = pka.attrelid AND pka.attnum = con.confkey[pos.n] AND con.confrelid = pkc.oid AND fkn.oid = fkc.relnamespace AND fkc.oid = fka.attrelid AND fka.attnum = con.conkey[pos.n] AND con.conrelid = fkc.oid AND con.contype = 'f' AND con.oid = dep.objid AND pkic.oid = dep.refobjid AND pkic.relkind = 'i' AND dep.classid = 'pg_constraint'::regclass::oid AND dep.refclassid = 'pg_class'::regclass::oid AND fkn.nspname = 'account' AND fkc.relname = 'user_table' ORDER BY pkn.nspname,pkc.relname,pos.n
63-
|]
64-
65-
66-
typeList = [str|
67-
SELECT typname FROM pg_catalog.pg_type WHERE oid = $1
68-
69-
SELECT typinput='array_in'::regproc, typtype FROM pg_catalog.pg_type WHERE typname = $1
70-
71-
select t.oid, t.typname, s.nspname from pg_type t, pg_namespace s where t.typnamespace = s.oid
72-
select t.typname as udtname, ct.typname as datatype, a.atttypmod as len, t.oid, a.attname as name from pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, pg_catalog.pg_type ct, pg_catalog.pg_namespace sch where t.typtype = 'c' and t.typnamespace = sch.oid and t.typrelid = c.oid and sch.nspname = $1 and c.relkind = 'c' and c.oid = a.attrelid and a.atttypid = ct.oid order by t.typname, a.attnum
73-
74-
|]
7511

7612
stuff = [str|
7713
SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, c.relname AS TABLE_NAME,

Table.hs

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
{-# LANGUAGE QuasiQuotes, FlexibleInstances #-}
2+
3+
module View where
4+
5+
import Str(str)
6+
import Acl
7+
import Util
8+
import Console
9+
import Diff
10+
11+
tblList = [str|
12+
SELECT n.nspname AS "Schema", c.relname AS "Name", d.description AS "Comment",
13+
relacl AS "ACLs"
14+
FROM pg_catalog.pg_namespace n
15+
JOIN pg_catalog.pg_class c ON c.relnamespace = n.oid
16+
LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0)
17+
-- LEFT JOIN pg_catalog.pg_class dc ON (d.classoid=dc.oid AND dc.relname='pg_class')
18+
-- LEFT JOIN pg_catalog.pg_namespace dn ON (dn.oid=dc.relnamespace AND dn.nspname='pg_catalog')
19+
WHERE n.nspname IN ('account','document')
20+
AND c.relkind = 'r'
21+
AND n.nspname !~ '^pg_'
22+
AND n.nspname <> 'information_schema'
23+
ORDER BY 1, 2
24+
|]
25+
26+
tblColumns = [str|
27+
SELECT * FROM (SELECT n.nspname,c.relname,a.attname,a.atttypid,a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) AS attnotnull,a.atttypmod,a.attlen,row_number() OVER (PARTITION BY a.attrelid ORDER BY a.attnum) AS attnum, pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,dsc.description,t.typbasetype,t.typtype FROM pg_catalog.pg_namespace n JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid) JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid) JOIN pg_catalog.pg_type t ON (a.atttypid = t.oid) LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum) LEFT JOIN pg_catalog.pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid) LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class') LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog')
28+
WHERE a.attnum > 0 AND NOT a.attisdropped AND n.nspname LIKE 'account' AND c.relname LIKE 'user_table') c WHERE true ORDER BY nspname,c.relname,attnum
29+
|]
30+
31+
32+
33+
tblIndices2 = [str|
34+
SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, ct.relname AS TABLE_NAME, NOT i.indisunique AS NON_UNIQUE, NULL AS INDEX_QUALIFIER, ci.relname AS INDEX_NAME, CASE i.indisclustered WHEN true THEN 1 ELSE CASE am.amname WHEN 'hash' THEN 2 ELSE 3 END END AS TYPE, (i.keys).n AS ORDINAL_POSITION, pg_catalog.pg_get_indexdef(ci.oid, (i.keys).n, false) AS COLUMN_NAME, CASE am.amcanorder WHEN true THEN CASE i.indoption[(i.keys).n - 1] & 1 WHEN 1 THEN 'D' ELSE 'A' END ELSE NULL END AS ASC_OR_DESC, ci.reltuples AS CARDINALITY, ci.relpages AS PAGES, pg_catalog.pg_get_expr(i.indpred, i.indrelid) AS FILTER_CONDITION FROM pg_catalog.pg_class ct JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) JOIN (SELECT i.indexrelid, i.indrelid, i.indoption, i.indisunique, i.indisclustered,
35+
i.indpred, i.indexprs, information_schema._pg_expandarray(i.indkey) AS keys FROM pg_catalog.pg_index i) i ON (ct.oid = i.indrelid) JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) JOIN pg_catalog.pg_am am ON (ci.relam = am.oid) WHERE true AND n.nspname = 'account' AND ct.relname = 'user_table' ORDER BY NON_UNIQUE, TYPE, INDEX_NAME, ORDINAL_POSITION
36+
|]
37+
38+
tblIndices = [str|
39+
select ind.indisclustered, ind.indexrelid, ind.indisprimary, cls.relname from pg_catalog.pg_index ind, pg_catalog.pg_class tab, pg_catalog.pg_namespace sch, pg_catalog.pg_class cls where ind.indrelid = tab.oid and cls.oid = ind.indexrelid and tab.relnamespace = sch.oid and tab.relname = $1 and sch.nspname = $2
40+
|]
41+
42+
tblConstraints = [str|
43+
SELECT cons.conname, cons.conkey
44+
FROM pg_catalog.pg_constraint cons, pg_catalog.pg_class tab, pg_catalog.pg_namespace sch
45+
WHERE cons.contype = 'u' and cons.conrelid = tab.oid and tab.relnamespace = sch.oid
46+
AND tab.relname = $1 and sch.nspname = $2
47+
|]
48+
49+
tblKeysx = [str|
50+
SELECT NULL AS TABLE_CAT, n.nspname AS TABLE_SCHEM, ct.relname AS TABLE_NAME, a.attname AS COLUMN_NAME, (i.keys).n AS KEY_SEQ, ci.relname AS PK_NAME FROM pg_catalog.pg_class ct JOIN pg_catalog.pg_attribute a ON (ct.oid = a.attrelid) JOIN pg_catalog.pg_namespace n ON (ct.relnamespace = n.oid) JOIN (SELECT i.indexrelid, i.indrelid, i.indisprimary, information_schema._pg_expandarray(i.indkey) AS keys FROM pg_catalog.pg_index i) i ON (a.attnum = (i.keys).x AND a.attrelid = i.indrelid) JOIN pg_catalog.pg_class ci ON (ci.oid = i.indexrelid) WHERE true AND n.nspname = 'account' AND ct.relname = 'user_table' AND i.indisprimary ORDER BY table_name, pk_name, key_seq
51+
|]
52+
53+
tblKeys = [str|
54+
SELECT NULL::text AS PKTABLE_CAT, pkn.nspname AS PKTABLE_SCHEM, pkc.relname AS PKTABLE_NAME, pka.attname AS PKCOLUMN_NAME, NULL::text AS FKTABLE_CAT, fkn.nspname AS FKTABLE_SCHEM, fkc.relname AS FKTABLE_NAME, fka.attname AS FKCOLUMN_NAME, pos.n AS KEY_SEQ, CASE con.confupdtype WHEN 'c' THEN 0 WHEN 'n' THEN 2 WHEN 'd' THEN 4 WHEN 'r' THEN 1 WHEN 'a' THEN 3 ELSE NULL END AS UPDATE_RULE, CASE con.confdeltype WHEN 'c' THEN 0 WHEN 'n' THEN 2 WHEN 'd' THEN 4 WHEN 'r' THEN 1 WHEN 'a' THEN 3 ELSE NULL END AS DELETE_RULE, con.conname AS FK_NAME, pkic.relname AS PK_NAME, CASE WHEN con.condeferrable AND con.condeferred THEN 5 WHEN con.condeferrable THEN 6 ELSE 7 END AS DEFERRABILITY FROM pg_catalog.pg_namespace pkn, pg_catalog.pg_class pkc, pg_catalog.pg_attribute pka, pg_catalog.pg_namespace fkn, pg_catalog.pg_class fkc, pg_catalog.pg_attribute fka,
55+
pg_catalog.pg_constraint con, pg_catalog.generate_series(1, 32) pos(n), pg_catalog.pg_depend dep, pg_catalog.pg_class pkic WHERE pkn.oid = pkc.relnamespace AND pkc.oid = pka.attrelid AND pka.attnum = con.confkey[pos.n] AND con.confrelid = pkc.oid AND fkn.oid = fkc.relnamespace AND fkc.oid = fka.attrelid AND fka.attnum = con.conkey[pos.n] AND con.conrelid = fkc.oid AND con.contype = 'f' AND con.oid = dep.objid AND pkic.oid = dep.refobjid AND pkic.relkind = 'i' AND dep.classid = 'pg_constraint'::regclass::oid AND dep.refclassid = 'pg_class'::regclass::oid AND fkn.nspname = 'account' AND fkc.relname = 'user_table' ORDER BY pkn.nspname,pkc.relname,pos.n
56+
|]
57+
58+
59+
{-
60+
viewList = [str|
61+
SELECT n.nspname AS "Schema", c.relname AS "Name", -- d.description AS "Comment",
62+
pg_get_viewdef(c.oid) AS definition,
63+
relacl AS "ACLs"
64+
FROM pg_catalog.pg_namespace n
65+
JOIN pg_catalog.pg_class c ON c.relnamespace = n.oid
66+
LEFT JOIN pg_catalog.pg_description d ON (c.oid = d.objoid AND d.objsubid = 0)
67+
WHERE n.nspname IN (select * from unnest(current_schemas(false)))
68+
AND c.relkind = 'v'
69+
AND n.nspname !~ '^pg_'
70+
AND n.nspname <> 'information_schema'
71+
ORDER BY 1, 2
72+
|]
73+
74+
viewColumns = [str|
75+
SELECT n.nspname as "Schema",c.relname AS "View",a.attname AS "Column",a.atttypid AS "Type",
76+
a.attnotnull OR (t.typtype = 'd' AND t.typnotnull) AS attnotnull,
77+
a.atttypmod,a.attlen,row_number() OVER (PARTITION BY a.attrelid ORDER BY a.attnum) AS attnum,
78+
pg_catalog.pg_get_expr(def.adbin, def.adrelid) AS adsrc,
79+
dsc.description,t.typbasetype,t.typtype
80+
FROM pg_catalog.pg_namespace n
81+
JOIN pg_catalog.pg_class c ON (c.relnamespace = n.oid)
82+
JOIN pg_catalog.pg_attribute a ON (a.attrelid=c.oid)
83+
JOIN pg_catalog.pg_type t ON (a.atttypid = t.oid)
84+
LEFT JOIN pg_catalog.pg_attrdef def ON (a.attrelid=def.adrelid AND a.attnum = def.adnum)
85+
LEFT JOIN pg_catalog.pg_description dsc ON (c.oid=dsc.objoid AND a.attnum = dsc.objsubid)
86+
LEFT JOIN pg_catalog.pg_class dc ON (dc.oid=dsc.classoid AND dc.relname='pg_class')
87+
LEFT JOIN pg_catalog.pg_namespace dn ON (dc.relnamespace=dn.oid AND dn.nspname='pg_catalog')
88+
WHERE a.attnum > 0 AND NOT a.attisdropped
89+
AND n.nspname IN (select * from unnest(current_schemas(false)))
90+
ORDER BY 1,2,3
91+
|]
92+
93+
viewTriggers = [str|
94+
SELECT n.nspname as "Schema", c.relname AS "View", t.tgname AS "Name", t.tgenabled = 'O' AS enabled,
95+
-- pg_get_triggerdef(trig.oid) as source
96+
concat (np.nspname, '.', p.proname) AS procedure
97+
FROM pg_catalog.pg_trigger t
98+
JOIN pg_catalog.pg_class c ON t.tgrelid = c.oid
99+
JOIN pg_catalog.pg_namespace n ON c.relnamespace = n.oid
100+
JOIN pg_catalog.pg_proc p ON t.tgfoid = p.oid
101+
JOIN pg_catalog.pg_namespace np ON p.pronamespace = np.oid
102+
WHERE t.tgconstraint = 0 AND n.nspname IN (select * from unnest(current_schemas(false)))
103+
ORDER BY 1,2,3
104+
|]
105+
106+
viewRules = [str|
107+
SELECT n.nspname as "Schema", c.relname AS "View", r.rulename AS "Name", pg_get_ruledef(r.oid) AS definition
108+
FROM pg_rewrite r
109+
JOIN pg_class c ON c.oid = r.ev_class
110+
JOIN pg_namespace n ON c.relnamespace = n.oid
111+
WHERE n.nspname IN (select * from unnest(current_schemas(false))) AND c.relkind = 'v'
112+
ORDER BY 1,2,3
113+
|]
114+
-}
115+
116+
data DbView = DbView { schema :: String, name :: String, definition :: String, acl :: [Acl] }
117+
deriving(Show)
118+
mkdbv (a:b:c:d:_) = DbView a b c (cvtacl d)
119+
120+
instance Show (Comparison DbView) where
121+
show (Equal x) = concat [sok, showView x, treset]
122+
show (LeftOnly a) = concat [azure, [charLeftArrow]," ", showView a, treset]
123+
show (RightOnly a) = concat [peach, [charRightArrow], " ", showView a, treset]
124+
show (Unequal a b) = concat [nok, showView a, treset,
125+
-- if (acl a /= acl b) then concat[ setAttr bold, "\n acls: " , treset, map show $ dbCompare a b] else "",
126+
showAclDiffs (acl a) (acl b),
127+
if (compareIgnoringWhiteSpace (definition a) (definition b)) then ""
128+
else concat [setAttr bold,"\n definition differences: \n", treset, concatMap show $ diff (definition a) (definition b)]
129+
]
130+
131+
instance Comparable DbView where
132+
objCmp a b =
133+
if (acl a == acl b && compareIgnoringWhiteSpace (definition a) (definition b)) then Equal a
134+
else Unequal a b
135+
136+
compareViews (get1, get2) = do
137+
aa <- get1 viewList
138+
-- aac <- get1 viewColumns
139+
-- aat <- get1 viewTriggers
140+
-- aar <- get1 viewRules
141+
142+
bb <- get2 viewList
143+
-- bbc <- get2 viewColumns
144+
-- bbt <- get2 viewTriggers
145+
-- bbr <- get2 viewRules
146+
147+
let a = map (mkdbv . (map gs)) aa
148+
let b = map (mkdbv . (map gs)) bb
149+
150+
let cc = dbCompare a b
151+
let cnt = dcount iseq cc
152+
putStr $ if (fst cnt > 0) then sok ++ (show $ fst cnt) ++ " matches, " else ""
153+
putStrLn $ if (snd cnt > 0) then concat [setColor dullRed,show $ snd cnt," differences"] else concat [sok,"no differences"]
154+
putStr $ treset
155+
return $ filter (not . iseq) cc
156+
157+
showView x = (schema x) ++ "." ++ (name x)
158+
159+
instance Ord DbView where
160+
compare a b = let hd p = map ($ p) [schema, name] in compare (hd a) (hd b)
161+
162+
instance Eq DbView where
163+
(==) a b = EQ == compare a b

0 commit comments

Comments
 (0)