Skip to content

Commit 5e7dfb1

Browse files
committed
index.go adds both PKs and UNIQUE constraints
1 parent 39cb7e8 commit 5e7dfb1

3 files changed

Lines changed: 69 additions & 21 deletions

File tree

index.go

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package main
22

33
import "fmt"
4+
import "strings"
45
import "database/sql"
56
import "github.com/joncrlsn/pgutil"
67

@@ -43,6 +44,7 @@ func (c *IndexSchema) Compare(obj interface{}) int {
4344

4445
// Add generates SQL to add the constraint/index
4546
func (c IndexSchema) Add() {
47+
fmt.Println("--\n--Add\n--")
4648

4749
// Assertion
4850
if c.row["index_def"] == "null" {
@@ -51,34 +53,38 @@ func (c IndexSchema) Add() {
5153
}
5254

5355
// Create the index
54-
fmt.Println(c.row["index_def"])
55-
//fmt.Println("--", c.row["constraint_def"])
56-
56+
fmt.Printf("%s;\n", c.row["index_def"])
57+
5758
if c.row["constraint_def"] != "null" {
5859
// Create the constraint using the index we just created
5960
if c.row["pk"] == "true" {
6061
// Add primary key using the index
61-
fmt.Printf("ALTER TABLE IF EXISTS ONLY %s ADD CONSTRAINT %s PRIMARY KEY USING INDEX %s;\n", c.row["table_name"], c.row["index_name"], c.row["index_name"])
62+
fmt.Printf("ALTER TABLE ONLY %s ADD CONSTRAINT %s PRIMARY KEY USING INDEX %s;\n", c.row["table_name"], c.row["index_name"], c.row["index_name"])
6263
} else if c.row["uq"] == "true" {
6364
// Add unique constraint using the index
64-
fmt.Printf("ALTER TABLE IF EXISTS ONLY %s ADD CONSTRAINT %s UNIQUE USING INDEX %s;\n", c.row["table_name"], c.row["index_name"], c.row["index_name"])
65+
fmt.Printf("ALTER TABLE ONLY %s ADD CONSTRAINT %s UNIQUE USING INDEX %s;\n", c.row["table_name"], c.row["index_name"], c.row["index_name"])
6566
}
6667
}
6768
}
6869

6970
// Drop generates SQL to drop the index and/or the constraint related to it
7071
func (c IndexSchema) Drop() {
72+
fmt.Println("--\n--Drop\n--")
7173
if c.row["constraint_def"] != "null" {
72-
fmt.Printf("ALTER TABLE IF EXISTS ONLY %s DROP CONSTRAINT IF EXISTS %s; -- %s\n", c.row["table_name"], c.row["index_name"], c.row["constraint_def"])
74+
fmt.Println("-- Warning, this may drop foreign keys pointing at this column. Make sure you re-run the FOREIGN_KEY diff after running this SQL.")
75+
//fmt.Printf("ALTER TABLE ONLY %s DROP CONSTRAINT IF EXISTS %s CASCADE; -- %s\n", c.row["table_name"], c.row["index_name"], c.row["constraint_def"])
76+
fmt.Printf("ALTER TABLE ONLY %s DROP CONSTRAINT IF EXISTS %s CASCADE;\n", c.row["table_name"], c.row["index_name"])
7377
}
74-
fmt.Printf("DROP INDEX IF EXISTS %s; -- %s \n", c.row["index_name"], c.row["index_def"])
78+
// The second line has no index_def
79+
//fmt.Printf("DROP INDEX IF EXISTS %s; -- %s \n", c.row["index_name"], c.row["index_def"])
80+
fmt.Printf("DROP INDEX IF EXISTS %s;\n", c.row["index_name"])
7581
}
7682

7783
// Change handles the case where the table and index name match, but the details do not
7884
func (c IndexSchema) Change(obj interface{}) {
7985
c2, ok := obj.(*IndexSchema)
8086
if !ok {
81-
fmt.Println("Error!!!, change needs an IndexSchema instance", c2)
87+
fmt.Println("-- Error!!!, change needs an IndexSchema instance", c2)
8288
}
8389
// Table and constraint name matches... We need to make sure the details match
8490

@@ -93,7 +99,9 @@ func (c IndexSchema) Change(obj interface{}) {
9399
}
94100

95101
if c.row["constraint_def"] != c2.row["constraint_def"] {
102+
fmt.Println("--\n--CHANGE: constraint defs different\n--")
96103
// c1.constraint and c2.constraint are just different
104+
fmt.Printf("-- Different defs:\n-- %s\n-- %s\n", c.row["constraint_def"], c2.row["constraint_def"])
97105
if c.row["constraint_def"] == "null" {
98106
// c1.constraint does not exist, c2.constraint does, so
99107
// Drop constraint
@@ -116,23 +124,28 @@ func (c IndexSchema) Change(obj interface{}) {
116124
} else {
117125
// Drop the c2 index, create a copy of the c1 index
118126
fmt.Printf("DROP INDEX IF EXISTS %s; -- %s \n", c2.row["index_name"], c2.row["index_def"])
119-
120127
}
121-
fmt.Printf("ALTER TABLE %s ADD CONSTRAINT %s %s;\n", c.row["table_name"], c.row["constraint_name"], c.row["constraint_def"])
128+
// WIP
129+
//fmt.Printf("ALTER TABLE %s ADD CONSTRAINT %s %s;\n", c.row["table_name"], c.row["index_name"], c.row["constraint_def"])
122130

123131
} else if c.row["index_def"] != c2.row["index_def"] {
124132
// The constraints match
125133
}
126134

127135
} else if c.row["index_def"] != c2.row["index_def"] {
128-
// Remember, if we are here, then the two constraint_defs match (both may be empty)
129-
// The indexes do not match, but the constraints do
130-
131-
// Drop the index (and maybe the constraint) so we can recreate the index
132-
c.Drop()
133-
134-
// Recreate the index (and a constraint if specified)
135-
c.Add()
136+
if !strings.HasPrefix(c.row["index_def"], c2.row["index_def"]) &&
137+
!strings.HasPrefix(c2.row["index_def"], c.row["index_def"]) {
138+
fmt.Println("--\n--Change index defs different\n--")
139+
// Remember, if we are here, then the two constraint_defs match (both may be empty)
140+
// The indexes do not match, but the constraints do
141+
fmt.Printf("--CHANGE: Different index defs:\n-- %s\n-- %s\n", c.row["index_def"], c2.row["index_def"])
142+
143+
// Drop the index (and maybe the constraint) so we can recreate the index
144+
c.Drop()
145+
146+
// Recreate the index (and a constraint if specified)
147+
c.Add()
148+
}
136149
}
137150

138151
}
@@ -157,7 +170,7 @@ JOIN pg_catalog.pg_class AS c2 ON (c2.oid = i.indexrelid)
157170
LEFT JOIN pg_catalog.pg_constraint con
158171
ON (con.conrelid = i.indrelid AND con.conindid = i.indexrelid AND con.contype IN ('p','u','x'))
159172
WHERE c.relname NOT LIKE 'pg_%'
160-
--AND c.relname = 't_org'
173+
AND c.relname = 't_org'
161174
ORDER BY c.relname, c2.relname;
162175
`
163176

pgdiff.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import "fmt"
4-
54
import "log"
65
import "flag"
76
import "os"
@@ -61,8 +60,9 @@ func main() {
6160
compareSequences(conn1, conn2)
6261
compareTables(conn1, conn2)
6362
compareColumns(conn1, conn2)
64-
compareIndexes(conn1, conn2)
63+
compareIndexes(conn1, conn2) // includes PK and Unique indexes
6564
compareForeignKeys(conn1, conn2)
65+
compareRoles(conn1, conn2)
6666
} else if schemaType == "SEQUENCE" {
6767
compareSequences(conn1, conn2)
6868
} else if schemaType == "TABLE" {
@@ -73,6 +73,8 @@ func main() {
7373
compareIndexes(conn1, conn2)
7474
} else if schemaType == "FOREIGN_KEY" {
7575
compareForeignKeys(conn1, conn2)
76+
} else if schemaType == "ROLE" {
77+
compareRoles(conn1, conn2)
7678
} else {
7779
fmt.Println("Not yet handled:", schemaType)
7880
}

pgdiff.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
3+
USER1=c42
4+
PASS1=c422006
5+
HOST1=localhost
6+
NAME1=prd-cpc
7+
OPT1="sslmode=disable"
8+
9+
USER2=c42
10+
PASS2=c422006
11+
HOST2=localhost
12+
NAME2=cp_staging
13+
OPT2="sslmode=disable"
14+
15+
function rundiff() {
16+
local TYPE=$1
17+
echo "Generating diff for $TYPE..."
18+
pgdiff -U1 $USER1 -pw1 $PASS1 -h1 $HOST1 -d1 $NAME1 -o1 "$OPT1" -U2 $USER2 -pw2 $PASS2 -h2 $HOST2 -d2 $NAME2 -o2 $OPT2 $TYPE > "${TYPE}.sql"
19+
echo -n "Press Enter to review the generated output: "; read x
20+
vi "${TYPE}.sql"
21+
echo -n "Do you wish to run this against ${NAME2}? [yN]: "; read x
22+
if [[ $x =~ y ]]; then
23+
pgrun -U $USER2 -pw $PASS2 -h $HOST2 -d $NAME2 -o $OPT2 -f "${TYPE}.sql"
24+
fi
25+
}
26+
27+
rundiff SEQUENCE
28+
rundiff TABLE
29+
rundiff COLUMN
30+
rundiff INDEX
31+
rundiff FOREIGN_KEY
32+
#rundiff ROLE
33+

0 commit comments

Comments
 (0)