Skip to content

Commit 8c20cc1

Browse files
committed
Added in-memory sorting to foreignkey.go
Former-commit-id: 10bf89d
1 parent 2d60b3e commit 8c20cc1

2 files changed

Lines changed: 77 additions & 25 deletions

File tree

foreignkey.go

Lines changed: 76 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,68 @@
11
package main
22

3+
import "sort"
34
import "fmt"
45
import "database/sql"
56
import "github.com/joncrlsn/pgutil"
67

7-
// ForeignKeySchema holds a channel streaming foreign key data from one of the databases as well as
8+
// ==================================
9+
// ForeignKeyRows definition
10+
// ==================================
11+
type ForeignKeyRows []map[string]string
12+
13+
func (slice ForeignKeyRows) Len() int {
14+
return len(slice)
15+
}
16+
17+
func (slice ForeignKeyRows) Less(i, j int) bool {
18+
//fmt.Printf("--Less %s:%s with %s:%s", slice[i]["table_name"], slice[i]["column_name"], slice[j]["table_name"], slice[j]["column_name"])
19+
if slice[i]["table_name"] == slice[j]["table_name"] {
20+
return slice[i]["constraint_def"] < slice[j]["constraint_def"]
21+
}
22+
return slice[i]["table_name"] < slice[j]["table_name"]
23+
}
24+
25+
func (slice ForeignKeyRows) Swap(i, j int) {
26+
//fmt.Printf("--Swapping %d/%s:%s with %d/%s:%s \n", i, slice[i]["table_name"], slice[i]["index_name"], j, slice[j]["table_name"], slice[j]["index_name"])
27+
slice[i], slice[j] = slice[j], slice[i]
28+
}
29+
30+
// ==================================
31+
// ForeignKeySchema definition
32+
// (implements Schema -- defined in pgdiff.go)
33+
// ==================================
34+
35+
// ForeignKeySchema holds a slice of rows from one of the databases as well as
836
// a reference to the current row of data we're viewing.
9-
//
10-
// ForeignKeySchema implements the Schema interface defined in pgdiff.go
1137
type ForeignKeySchema struct {
12-
channel chan map[string]string
13-
row map[string]string
38+
rows ForeignKeyRows
39+
rowNum int
1440
done bool
1541
}
1642

43+
// get returns the value from the current row for the given key
44+
func (c *ForeignKeySchema) get(key string) string {
45+
if c.rowNum >= len(c.rows) {
46+
return ""
47+
}
48+
return c.rows[c.rowNum][key]
49+
}
50+
51+
// get returns the current row for the given key
52+
func (c *ForeignKeySchema) getRow() map[string]string {
53+
if c.rowNum >= len(c.rows) {
54+
return make(map[string]string)
55+
}
56+
return c.rows[c.rowNum]
57+
}
58+
1759
// NextRow reads from the channel and tells you if there are (probably) more or not
1860
func (c *ForeignKeySchema) NextRow() bool {
19-
c.row = <-c.channel
20-
if len(c.row) == 0 {
21-
c.done = true
22-
}
23-
return !c.done
61+
if c.rowNum >= len(c.rows)-1 {
62+
c.done = true
63+
}
64+
c.rowNum = c.rowNum + 1
65+
return !c.done
2466
}
2567

2668
// Compare tells you, in one pass, whether or not the first row matches, is less than, or greater than the second row
@@ -31,28 +73,28 @@ func (c *ForeignKeySchema) Compare(obj interface{}) int {
3173
return +999
3274
}
3375

34-
//fmt.Printf("Comparing %s with %s", c.row["table_name"], c2.row["table_name"])
35-
val := _compareString(c.row["table_name"], c2.row["table_name"])
76+
//fmt.Printf("Comparing %s with %s", c.get("table_name"), c2.get("table_name"))
77+
val := _compareString(c.get("table_name"), c2.get("table_name"))
3678
if val != 0 {
3779
return val
3880
}
3981

40-
val = _compareString(c.row["constraint_def"], c2.row["constraint_def"])
82+
val = _compareString(c.get("constraint_def"), c2.get("constraint_def"))
4183
return val
4284
}
4385

4486
// Add returns SQL to add the foreign key
45-
func (c ForeignKeySchema) Add() {
46-
fmt.Printf("ALTER TABLE %s ADD CONSTRAINT %s %s;\n", c.row["table_name"], c.row["constraint_name"], c.row["constraint_def"])
87+
func (c *ForeignKeySchema) Add() {
88+
fmt.Printf("ALTER TABLE %s ADD CONSTRAINT %s %s;\n", c.get("table_name"), c.get("fk_name"), c.get("constraint_def"))
4789
}
4890

4991
// Drop returns SQL to drop the foreign key
5092
func (c ForeignKeySchema) Drop() {
51-
fmt.Printf("ALTER TABLE %s DROP CONSTRAINT %s; -- %s\n", c.row["table_name"], c.row["constraint_name"], c.row["constraint_def"])
93+
fmt.Printf("ALTER TABLE %s DROP CONSTRAINT %s; -- %s\n", c.get("table_name"), c.get("fk_name"), c.get("constraint_def"))
5294
}
5395

5496
// Change handles the case where the table and foreign key name, but the details do not
55-
func (c ForeignKeySchema) Change(obj interface{}) {
97+
func (c *ForeignKeySchema) Change(obj interface{}) {
5698
c2, ok := obj.(*ForeignKeySchema)
5799
if !ok {
58100
fmt.Println("Error!!!, change needs a ForeignKeySchema instance", c2)
@@ -65,22 +107,31 @@ func (c ForeignKeySchema) Change(obj interface{}) {
65107
*/
66108
func compareForeignKeys(conn1 *sql.DB, conn2 *sql.DB) {
67109
sql := `
68-
SELECT c.conname AS constraint_name
69-
, c.contype AS constraint_type
110+
SELECT c.conname AS fk_name
70111
, cl.relname AS table_name
71112
, pg_catalog.pg_get_constraintdef(c.oid, true) as constraint_def
72113
FROM pg_catalog.pg_constraint c
73114
INNER JOIN pg_class AS cl ON (c.conrelid = cl.oid)
74-
WHERE c.contype = 'f'
75-
ORDER BY cl.relname::varchar, pg_catalog.pg_get_constraintdef(c.oid, true) COLLATE "C" ASC;
115+
WHERE c.contype = 'f';
76116
`
77-
78117
rowChan1, _ := pgutil.QueryStrings(conn1, sql)
79118
rowChan2, _ := pgutil.QueryStrings(conn2, sql)
80119

81-
// We have to explicitly type this as Schema for some reason
82-
var schema1 Schema = &ForeignKeySchema{channel: rowChan1}
83-
var schema2 Schema = &ForeignKeySchema{channel: rowChan2}
120+
rows1 := make(ForeignKeyRows, 0)
121+
for row := range rowChan1 {
122+
rows1 = append(rows1, row)
123+
}
124+
sort.Sort(rows1)
125+
126+
rows2 := make(ForeignKeyRows, 0)
127+
for row := range rowChan2 {
128+
rows2 = append(rows2, row)
129+
}
130+
sort.Sort(rows2)
131+
132+
// We have to explicitly type this as Schema here for some unknown reason
133+
var schema1 Schema = &ForeignKeySchema{rows: rows1, rowNum: -1}
134+
var schema2 Schema = &ForeignKeySchema{rows: rows2, rowNum: -1}
84135

85136
// Compare the columns
86137
doDiff(schema1, schema2)

index.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ func (c *IndexSchema) Compare(obj interface{}) int {
7171
c2, ok := obj.(*IndexSchema)
7272
if !ok {
7373
fmt.Println("Error!!!, change needs a IndexSchema instance", c2)
74+
return +999
7475
}
7576

7677
if len(c.get("table_name")) == 0 || len(c.get("index_name")) == 0 {

0 commit comments

Comments
 (0)