pg_examiner 0.4.3 → 0.4.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/pg_examiner/base.rb +9 -0
- data/lib/pg_examiner/result/constraint.rb +89 -2
- data/lib/pg_examiner/result.rb +5 -3
- data/lib/pg_examiner/version.rb +1 -1
- data/spec/constraint_spec.rb +254 -96
- data/spec/index_spec.rb +4 -4
- data/spec/trigger_spec.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a2625b44e3b5e213a77252e0e4f75c8e1c3cba77
|
4
|
+
data.tar.gz: 131e5074c7e82abe966e780788039a7cca9a9c1e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7fe244030e4b2facf9f7dce11dcf322594f26a046ce4d3833d68b9f0d3a46e09d5514c87aaf03cd15e95a59550a4f5f7fc8ecae80eaa13006a6587ae0b291348
|
7
|
+
data.tar.gz: 5ea6584418fe201c4fd06f7c2aff2811036998e933467267ad7f8f212356236c5d269894d31d8f98fc7e13d8faf0ae82746e1277b73b195fea93d50fad7bfb24
|
data/lib/pg_examiner/base.rb
CHANGED
@@ -70,5 +70,14 @@ module PGExaminer
|
|
70
70
|
def ==(other)
|
71
71
|
self.class == other.class && diff(other) == {}
|
72
72
|
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
ARRAY_REGEX = /\A\{(.*)\}\z/
|
77
|
+
def extract_array(value)
|
78
|
+
without_brackets = value[ARRAY_REGEX, 1]
|
79
|
+
raise "Invalid array value: #{value.inspect}" unless without_brackets
|
80
|
+
without_brackets.split(',')
|
81
|
+
end
|
73
82
|
end
|
74
83
|
end
|
@@ -5,10 +5,97 @@ module PGExaminer
|
|
5
5
|
class Constraint < Item
|
6
6
|
def diffable_attrs
|
7
7
|
{
|
8
|
-
"name"
|
9
|
-
"
|
8
|
+
"name" => "name",
|
9
|
+
"contype" => "constraint type",
|
10
|
+
"condeferrable" => "constraint is deferrable",
|
11
|
+
"condeferred" => "constraint is initially deferred",
|
12
|
+
"convalidated" => "constraint is validated",
|
13
|
+
"connoinherit" => "constraint is not inheritable",
|
14
|
+
"check_def" => "check constraint definition",
|
10
15
|
}
|
11
16
|
end
|
17
|
+
|
18
|
+
def diffable_methods
|
19
|
+
{
|
20
|
+
"type" => "type",
|
21
|
+
"index" => "index",
|
22
|
+
"foreign_table_name" => "table referenced by foreign key",
|
23
|
+
"constrained_columns" => "local constrained columns",
|
24
|
+
"foreign_constrained_columns" => "foreign constrained columns",
|
25
|
+
"foreign_key_update_action" => "foreign key on update action",
|
26
|
+
"foreign_key_delete_action" => "foreign key on delete action",
|
27
|
+
"foreign_key_match_type" => "foreign key match type",
|
28
|
+
}
|
29
|
+
end
|
30
|
+
|
31
|
+
def type
|
32
|
+
@type ||= result.pg_type.find{|t| t['oid'] == row['contypid']}['name'] if row['contypid'] != '0'
|
33
|
+
end
|
34
|
+
|
35
|
+
def index
|
36
|
+
@index ||= result.pg_index.find{|i| i['indexrelid'] == row['conindid']}['name'] if row['conindid'] != '0'
|
37
|
+
end
|
38
|
+
|
39
|
+
def foreign_table_name
|
40
|
+
if ft = foreign_table
|
41
|
+
this_schema_name = parent.parent.name
|
42
|
+
that_schema_name = ft.parent.name
|
43
|
+
|
44
|
+
relative_schema =
|
45
|
+
if this_schema_name == that_schema_name
|
46
|
+
"(same schema)"
|
47
|
+
else
|
48
|
+
"#{that_schema_name} schema"
|
49
|
+
end
|
50
|
+
|
51
|
+
[relative_schema, ft.name]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def foreign_table
|
56
|
+
if row['confrelid'] != '0'
|
57
|
+
@foreign_table ||= begin
|
58
|
+
# Look up the table, which may be outside our own schema.
|
59
|
+
table_row = result.pg_class.find { |c| c['relkind'] == 'r' && c['oid'] == row['confrelid'] }
|
60
|
+
schema = result.schemas.find { |s| s.oid == table_row['relnamespace'] }
|
61
|
+
schema.tables.find { |t| t.name == table_row['name'] }
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def constrained_columns
|
67
|
+
@constrained_columns ||= extract_array(row['conkey']).map{|n| parent.columns.find{|c| c.row['attnum'] == n}.name} if row['conkey']
|
68
|
+
end
|
69
|
+
|
70
|
+
def foreign_constrained_columns
|
71
|
+
@foreign_constrained_columns ||= extract_array(row['confkey']).map{|n| foreign_table.columns.find{|c| c.row['attnum'] == n}.name} if row['confkey']
|
72
|
+
end
|
73
|
+
|
74
|
+
FOREIGN_KEY_ACTIONS = {
|
75
|
+
"a" => "no action",
|
76
|
+
"r" => "restrict",
|
77
|
+
"c" => "cascade",
|
78
|
+
"n" => "set null",
|
79
|
+
"d" => "set default",
|
80
|
+
}.freeze
|
81
|
+
|
82
|
+
def foreign_key_update_action
|
83
|
+
FOREIGN_KEY_ACTIONS.fetch(row['confupdtype']) if row['confupdtype'] != ' '
|
84
|
+
end
|
85
|
+
|
86
|
+
def foreign_key_delete_action
|
87
|
+
FOREIGN_KEY_ACTIONS.fetch(row['confdeltype']) if row['confdeltype'] != ' '
|
88
|
+
end
|
89
|
+
|
90
|
+
FOREIGN_KEY_MATCH_TYPES = {
|
91
|
+
"f" => "full",
|
92
|
+
"p" => "partial",
|
93
|
+
"s" => "simple",
|
94
|
+
}.freeze
|
95
|
+
|
96
|
+
def foreign_key_match_type
|
97
|
+
FOREIGN_KEY_MATCH_TYPES.fetch(row['confmatchtype']) if row['confmatchtype'] != ' '
|
98
|
+
end
|
12
99
|
end
|
13
100
|
end
|
14
101
|
end
|
data/lib/pg_examiner/result.rb
CHANGED
@@ -83,7 +83,7 @@ module PGExaminer
|
|
83
83
|
SQL
|
84
84
|
|
85
85
|
@pg_index = load_table @pg_class.map{|ns| ns['oid']}, <<-SQL
|
86
|
-
SELECT c.relname AS name, i.indrelid, i.indkey, indisunique, indisprimary,
|
86
|
+
SELECT i.indexrelid, c.relname AS name, i.indrelid, i.indkey, indisunique, indisprimary,
|
87
87
|
pg_get_expr(i.indpred, i.indrelid) AS filter,
|
88
88
|
pg_get_expr(i.indexprs, i.indrelid) AS expression
|
89
89
|
FROM pg_index i
|
@@ -92,8 +92,10 @@ module PGExaminer
|
|
92
92
|
SQL
|
93
93
|
|
94
94
|
@pg_constraint = load_table @pg_class.map{|ns| ns['oid']}, <<-SQL
|
95
|
-
SELECT oid, conname AS name, conrelid,
|
96
|
-
|
95
|
+
SELECT oid, conname AS name, conrelid, contype,
|
96
|
+
condeferrable, condeferred, convalidated,
|
97
|
+
contypid, conindid, confrelid, confupdtype, confdeltype, confmatchtype,
|
98
|
+
connoinherit, conkey, confkey, pg_get_expr(conbin, conrelid) AS check_def
|
97
99
|
FROM pg_constraint c
|
98
100
|
WHERE conrelid IN (?)
|
99
101
|
SQL
|
data/lib/pg_examiner/version.rb
CHANGED
data/spec/constraint_spec.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
require 'spec_helper'
|
4
4
|
|
5
5
|
describe PGExaminer do
|
6
|
-
it "should consider constraints when determining table equivalency" do
|
6
|
+
it "should consider check constraints when determining table equivalency" do
|
7
7
|
a = examine <<-SQL
|
8
8
|
CREATE TABLE test_table (
|
9
9
|
a integer,
|
@@ -45,95 +45,52 @@ describe PGExaminer do
|
|
45
45
|
);
|
46
46
|
SQL
|
47
47
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
48
|
+
g = examine <<-SQL
|
49
|
+
CREATE TABLE test_table (
|
50
|
+
a integer,
|
51
|
+
CONSTRAINT con CHECK (a < 0)
|
52
|
+
);
|
53
|
+
SQL
|
54
|
+
|
55
|
+
a.diff(b).should be_empty
|
56
|
+
a.diff(c).should be_empty
|
57
|
+
b.diff(c).should be_empty
|
55
58
|
|
56
59
|
a.diff(d).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"added"=>["con_two"], "removed"=>["con"]}}}}}}
|
57
60
|
a.diff(e).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"added"=>["test_table_a_check"], "removed"=>["con"]}}}}}}
|
58
61
|
a.diff(f).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"removed"=>["con"]}}}}}}
|
62
|
+
a.diff(g).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"con"=>{"check constraint definition"=>{"(a > 0)"=>"(a < 0)"}}}}}}}}
|
59
63
|
e.diff(f).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"removed"=>["test_table_a_check"]}}}}}}
|
60
64
|
end
|
61
65
|
|
62
|
-
it "should consider
|
66
|
+
it "should consider the tables each constraint is on" do
|
63
67
|
a = examine <<-SQL
|
64
|
-
CREATE TABLE
|
65
|
-
|
66
|
-
|
68
|
+
CREATE TABLE test_table_1 (
|
69
|
+
a integer,
|
70
|
+
CONSTRAINT con CHECK (a > 0)
|
67
71
|
);
|
68
72
|
|
69
|
-
CREATE TABLE
|
70
|
-
|
73
|
+
CREATE TABLE test_table_2 (
|
74
|
+
a integer
|
71
75
|
);
|
72
76
|
SQL
|
73
77
|
|
74
78
|
b = examine <<-SQL
|
75
|
-
CREATE TABLE
|
76
|
-
|
77
|
-
int2 integer UNIQUE
|
78
|
-
);
|
79
|
-
|
80
|
-
CREATE TABLE child (
|
81
|
-
parent_id integer,
|
82
|
-
FOREIGN KEY (parent_id) REFERENCES parent
|
83
|
-
);
|
84
|
-
SQL
|
85
|
-
|
86
|
-
c = examine <<-SQL
|
87
|
-
CREATE TABLE parent (
|
88
|
-
int1 integer PRIMARY KEY,
|
89
|
-
int2 integer UNIQUE
|
90
|
-
);
|
91
|
-
|
92
|
-
CREATE TABLE child (
|
93
|
-
parent_id integer,
|
94
|
-
FOREIGN KEY (parent_id) REFERENCES parent (int2)
|
95
|
-
);
|
96
|
-
SQL
|
97
|
-
|
98
|
-
d = examine <<-SQL
|
99
|
-
CREATE TABLE parent (
|
100
|
-
int1 integer PRIMARY KEY,
|
101
|
-
int2 integer UNIQUE
|
102
|
-
);
|
103
|
-
|
104
|
-
CREATE TABLE child (
|
105
|
-
parent_id integer,
|
106
|
-
FOREIGN KEY (parent_id) REFERENCES parent ON UPDATE CASCADE
|
107
|
-
);
|
108
|
-
SQL
|
109
|
-
|
110
|
-
e = examine <<-SQL
|
111
|
-
CREATE TABLE parent (
|
112
|
-
int1 integer PRIMARY KEY,
|
113
|
-
int2 integer UNIQUE
|
79
|
+
CREATE TABLE test_table_1 (
|
80
|
+
a integer
|
114
81
|
);
|
115
82
|
|
116
|
-
CREATE TABLE
|
117
|
-
|
118
|
-
|
83
|
+
CREATE TABLE test_table_2 (
|
84
|
+
a integer,
|
85
|
+
CONSTRAINT con CHECK (a > 0)
|
119
86
|
);
|
120
87
|
SQL
|
121
88
|
|
122
|
-
a.
|
123
|
-
a.
|
124
|
-
b.should_not == c
|
125
|
-
b.should_not == d
|
126
|
-
b.should_not == e
|
127
|
-
d.should_not == e
|
128
|
-
|
129
|
-
a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"constraint definition"=>{"FOREIGN KEY (parent_id) REFERENCES parent(int1)"=>"FOREIGN KEY (parent_id) REFERENCES parent(int2)"}}}}}}}}
|
130
|
-
b.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"constraint definition"=>{"FOREIGN KEY (parent_id) REFERENCES parent(int1)"=>"FOREIGN KEY (parent_id) REFERENCES parent(int2)"}}}}}}}}
|
131
|
-
b.diff(d).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"constraint definition"=>{"FOREIGN KEY (parent_id) REFERENCES parent(int1)"=>"FOREIGN KEY (parent_id) REFERENCES parent(int1) ON UPDATE CASCADE"}}}}}}}}
|
132
|
-
b.diff(e).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"constraint definition"=>{"FOREIGN KEY (parent_id) REFERENCES parent(int1)"=>"FOREIGN KEY (parent_id) REFERENCES parent(int1) ON DELETE CASCADE"}}}}}}}}
|
133
|
-
d.diff(e).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"constraint definition"=>{"FOREIGN KEY (parent_id) REFERENCES parent(int1) ON UPDATE CASCADE"=>"FOREIGN KEY (parent_id) REFERENCES parent(int1) ON DELETE CASCADE"}}}}}}}}
|
89
|
+
a.should_not == b
|
90
|
+
a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table_1"=>{"constraints"=>{"removed"=>["con"]}}, "test_table_2"=>{"constraints"=>{"added"=>["con"]}}}}}}
|
134
91
|
end
|
135
92
|
|
136
|
-
it "should consider
|
93
|
+
it "should consider constraint validation when determining table equivalency" do
|
137
94
|
a = examine <<-SQL
|
138
95
|
CREATE TABLE test_table (
|
139
96
|
a integer,
|
@@ -161,34 +118,235 @@ describe PGExaminer do
|
|
161
118
|
a.should_not == c
|
162
119
|
b.should == c
|
163
120
|
|
164
|
-
a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"con"=>{"constraint
|
165
|
-
a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"con"=>{"constraint
|
121
|
+
a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"con"=>{"constraint is validated"=>{"f"=>"t"}}}}}}}}
|
122
|
+
a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"con"=>{"constraint is validated"=>{"f"=>"t"}}}}}}}}
|
166
123
|
end
|
167
124
|
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
125
|
+
describe "when considering foreign keys" do
|
126
|
+
it "should consider their presence" do
|
127
|
+
a = examine <<-SQL
|
128
|
+
CREATE TABLE parent (
|
129
|
+
int1 integer PRIMARY KEY
|
130
|
+
);
|
131
|
+
|
132
|
+
CREATE TABLE child (
|
133
|
+
parent_id integer
|
134
|
+
);
|
135
|
+
SQL
|
136
|
+
|
137
|
+
b = examine <<-SQL
|
138
|
+
CREATE TABLE parent (
|
139
|
+
int1 integer PRIMARY KEY
|
140
|
+
);
|
141
|
+
|
142
|
+
CREATE TABLE child (
|
143
|
+
parent_id integer REFERENCES parent
|
144
|
+
);
|
145
|
+
SQL
|
146
|
+
|
147
|
+
a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"added"=>["child_parent_id_fkey"]}}}}}}
|
148
|
+
end
|
149
|
+
|
150
|
+
it "should consider the remote columns of foreign keys when differentiating between schemas" do
|
151
|
+
a = examine <<-SQL
|
152
|
+
CREATE TABLE parent (
|
153
|
+
int1 integer PRIMARY KEY,
|
154
|
+
int2 integer UNIQUE
|
155
|
+
);
|
156
|
+
|
157
|
+
CREATE TABLE child (
|
158
|
+
parent_id integer REFERENCES parent
|
159
|
+
);
|
160
|
+
SQL
|
161
|
+
|
162
|
+
b = examine <<-SQL
|
163
|
+
CREATE TABLE parent (
|
164
|
+
int1 integer PRIMARY KEY,
|
165
|
+
int2 integer UNIQUE
|
166
|
+
);
|
167
|
+
|
168
|
+
CREATE TABLE child (
|
169
|
+
parent_id integer,
|
170
|
+
FOREIGN KEY (parent_id) REFERENCES parent (int1)
|
171
|
+
);
|
172
|
+
SQL
|
173
|
+
|
174
|
+
c = examine <<-SQL
|
175
|
+
CREATE TABLE parent (
|
176
|
+
int1 integer PRIMARY KEY,
|
177
|
+
int2 integer UNIQUE
|
178
|
+
);
|
179
|
+
|
180
|
+
CREATE TABLE child (
|
181
|
+
parent_id integer,
|
182
|
+
FOREIGN KEY (parent_id) REFERENCES parent (int2)
|
183
|
+
);
|
184
|
+
SQL
|
185
|
+
|
186
|
+
a.should == b
|
187
|
+
a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"index"=>{"parent_pkey"=>"parent_int2_key"}, "foreign constrained columns"=>{["int1"]=>["int2"]}}}}}}}}
|
188
|
+
b.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"index"=>{"parent_pkey"=>"parent_int2_key"}, "foreign constrained columns"=>{["int1"]=>["int2"]}}}}}}}}
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should consider the local columns of the foreign keys" do
|
192
|
+
a = examine <<-SQL
|
193
|
+
CREATE TABLE parent (
|
194
|
+
int1 integer PRIMARY KEY
|
195
|
+
);
|
196
|
+
|
197
|
+
CREATE TABLE child (
|
198
|
+
parent_id1 integer,
|
199
|
+
parent_id2 integer,
|
200
|
+
CONSTRAINT fkey FOREIGN KEY (parent_id1) REFERENCES parent
|
201
|
+
);
|
202
|
+
SQL
|
203
|
+
|
204
|
+
b = examine <<-SQL
|
205
|
+
CREATE TABLE parent (
|
206
|
+
int1 integer PRIMARY KEY
|
207
|
+
);
|
208
|
+
|
209
|
+
CREATE TABLE child (
|
210
|
+
parent_id1 integer,
|
211
|
+
parent_id2 integer,
|
212
|
+
CONSTRAINT fkey FOREIGN KEY (parent_id2) REFERENCES parent
|
213
|
+
);
|
214
|
+
SQL
|
215
|
+
|
216
|
+
a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"fkey"=>{"local constrained columns"=>{["parent_id1"]=>["parent_id2"]}}}}}}}}
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should consider on update/delete actions" do
|
220
|
+
a = examine <<-SQL
|
221
|
+
CREATE TABLE parent (
|
222
|
+
int1 integer PRIMARY KEY
|
223
|
+
);
|
224
|
+
|
225
|
+
CREATE TABLE child (
|
226
|
+
parent_id integer,
|
227
|
+
FOREIGN KEY (parent_id) REFERENCES parent
|
228
|
+
);
|
229
|
+
SQL
|
230
|
+
|
231
|
+
b = examine <<-SQL
|
232
|
+
CREATE TABLE parent (
|
233
|
+
int1 integer PRIMARY KEY
|
234
|
+
);
|
235
|
+
|
236
|
+
CREATE TABLE child (
|
237
|
+
parent_id integer,
|
238
|
+
FOREIGN KEY (parent_id) REFERENCES parent ON UPDATE CASCADE
|
239
|
+
);
|
240
|
+
SQL
|
241
|
+
|
242
|
+
c = examine <<-SQL
|
243
|
+
CREATE TABLE parent (
|
244
|
+
int1 integer PRIMARY KEY
|
245
|
+
);
|
246
|
+
|
247
|
+
CREATE TABLE child (
|
248
|
+
parent_id integer,
|
249
|
+
FOREIGN KEY (parent_id) REFERENCES parent ON DELETE CASCADE
|
250
|
+
);
|
251
|
+
SQL
|
252
|
+
|
253
|
+
a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"foreign key on update action"=>{"no action"=>"cascade"}}}}}}}}
|
254
|
+
a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"foreign key on delete action"=>{"no action"=>"cascade"}}}}}}}}
|
255
|
+
b.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"foreign key on update action"=>{"cascade"=>"no action"}, "foreign key on delete action"=>{"no action"=>"cascade"}}}}}}}}
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should consider match simple/full" do
|
259
|
+
a = examine <<-SQL
|
260
|
+
CREATE TABLE parent (
|
261
|
+
int1 integer PRIMARY KEY
|
262
|
+
);
|
263
|
+
|
264
|
+
CREATE TABLE child (
|
265
|
+
parent_id integer,
|
266
|
+
FOREIGN KEY (parent_id) REFERENCES parent
|
267
|
+
);
|
268
|
+
SQL
|
269
|
+
|
270
|
+
b = examine <<-SQL
|
271
|
+
CREATE TABLE parent (
|
272
|
+
int1 integer PRIMARY KEY
|
273
|
+
);
|
274
|
+
|
275
|
+
CREATE TABLE child (
|
276
|
+
parent_id integer,
|
277
|
+
FOREIGN KEY (parent_id) REFERENCES parent MATCH SIMPLE
|
278
|
+
);
|
279
|
+
SQL
|
280
|
+
|
281
|
+
c = examine <<-SQL
|
282
|
+
CREATE TABLE parent (
|
283
|
+
int1 integer PRIMARY KEY
|
284
|
+
);
|
285
|
+
|
286
|
+
CREATE TABLE child (
|
287
|
+
parent_id integer,
|
288
|
+
FOREIGN KEY (parent_id) REFERENCES parent MATCH FULL
|
289
|
+
);
|
290
|
+
SQL
|
291
|
+
|
292
|
+
a.diff(b).should == {}
|
293
|
+
a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"foreign key match type"=>{"simple"=>"full"}}}}}}}}
|
294
|
+
b.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"foreign key match type"=>{"simple"=>"full"}}}}}}}}
|
295
|
+
end
|
296
|
+
|
297
|
+
describe "when comparing two schemas" do
|
298
|
+
it "should understand that tables will point to tables in their own schema" do
|
299
|
+
a = examine <<-SQL, "schema1"
|
300
|
+
CREATE SCHEMA schema1;
|
301
|
+
CREATE TABLE schema1.parent (int1 integer PRIMARY KEY);
|
302
|
+
CREATE TABLE schema1.child (parent_id integer REFERENCES schema1.parent);
|
303
|
+
SQL
|
304
|
+
|
305
|
+
b = examine <<-SQL, "schema2"
|
306
|
+
CREATE SCHEMA schema2;
|
307
|
+
CREATE TABLE schema2.parent (int1 integer PRIMARY KEY);
|
308
|
+
CREATE TABLE schema2.child (parent_id integer REFERENCES schema2.parent);
|
309
|
+
SQL
|
310
|
+
|
311
|
+
c = examine <<-SQL, "schema2"
|
312
|
+
CREATE SCHEMA schema1;
|
313
|
+
CREATE TABLE schema1.parent (int1 integer PRIMARY KEY);
|
314
|
+
|
315
|
+
CREATE SCHEMA schema2;
|
316
|
+
CREATE TABLE schema2.parent (int1 integer PRIMARY KEY);
|
317
|
+
CREATE TABLE schema2.child (parent_id integer REFERENCES schema1.parent);
|
318
|
+
SQL
|
319
|
+
|
320
|
+
a.should == b
|
321
|
+
b.diff(c).should == {"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"table referenced by foreign key"=>{["(same schema)", "parent"]=>["schema1 schema", "parent"]}}}}}}
|
322
|
+
end
|
323
|
+
|
324
|
+
it "should understand when tables point to a table in public" do
|
325
|
+
a = examine <<-SQL, "schema1"
|
326
|
+
CREATE TABLE parent (int1 integer PRIMARY KEY);
|
327
|
+
CREATE SCHEMA schema1;
|
328
|
+
CREATE TABLE schema1.parent (int1 integer PRIMARY KEY);
|
329
|
+
CREATE TABLE schema1.child (parent_id integer REFERENCES parent);
|
330
|
+
SQL
|
331
|
+
|
332
|
+
b = examine <<-SQL, "schema2"
|
333
|
+
CREATE TABLE parent (int1 integer PRIMARY KEY);
|
334
|
+
CREATE SCHEMA schema2;
|
335
|
+
CREATE TABLE schema2.parent (int1 integer PRIMARY KEY);
|
336
|
+
CREATE TABLE schema2.child (parent_id integer REFERENCES parent);
|
337
|
+
SQL
|
338
|
+
|
339
|
+
c = examine <<-SQL, "schema1"
|
340
|
+
CREATE TABLE parent (int1 integer PRIMARY KEY);
|
341
|
+
|
342
|
+
CREATE SCHEMA schema1;
|
343
|
+
CREATE TABLE schema1.parent (int1 integer PRIMARY KEY);
|
344
|
+
CREATE TABLE schema1.child (parent_id integer REFERENCES schema1.parent);
|
345
|
+
SQL
|
346
|
+
|
347
|
+
a.should == b
|
348
|
+
b.diff(c).should == {"tables"=>{"child"=>{"constraints"=>{"child_parent_id_fkey"=>{"table referenced by foreign key"=>{["public schema", "parent"]=>["(same schema)", "parent"]}}}}}}
|
349
|
+
end
|
350
|
+
end
|
193
351
|
end
|
194
352
|
end
|
data/spec/index_spec.rb
CHANGED
@@ -297,9 +297,9 @@ describe PGExaminer do
|
|
297
297
|
d.should == d2
|
298
298
|
e.should == e2
|
299
299
|
|
300
|
-
a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"test_table_a_key"=>{"constraint
|
301
|
-
a.diff(d).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"test_table_a_key"=>{"constraint
|
302
|
-
c.diff(e).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"test_table_a_key"=>{"constraint
|
303
|
-
d.diff(e).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"test_table_a_key"=>{"constraint
|
300
|
+
a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"test_table_a_key"=>{"constraint is deferrable"=>{"f"=>"t"}}}}}}}}
|
301
|
+
a.diff(d).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"test_table_a_key"=>{"constraint is deferrable"=>{"f"=>"t"}}}}}}}}
|
302
|
+
c.diff(e).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"test_table_a_key"=>{"constraint is initially deferred"=>{"f"=>"t"}}}}}}}}
|
303
|
+
d.diff(e).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"test_table_a_key"=>{"constraint is initially deferred"=>{"f"=>"t"}}}}}}}}
|
304
304
|
end
|
305
305
|
end
|
data/spec/trigger_spec.rb
CHANGED
@@ -303,8 +303,8 @@ describe PGExaminer do
|
|
303
303
|
CREATE CONSTRAINT TRIGGER trig AFTER INSERT ON test_table DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE func();
|
304
304
|
SQL
|
305
305
|
|
306
|
-
a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"trig"=>{"constraint
|
307
|
-
a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"trig"=>{"constraint
|
308
|
-
b.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"trig"=>{"constraint
|
306
|
+
a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"trig"=>{"constraint is deferrable"=>{"f"=>"t"}}}}}}}}
|
307
|
+
a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"trig"=>{"constraint is deferrable"=>{"f"=>"t"}, "constraint is initially deferred"=>{"f"=>"t"}}}}}}}}
|
308
|
+
b.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"trig"=>{"constraint is initially deferred"=>{"f"=>"t"}}}}}}}}
|
309
309
|
end
|
310
310
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_examiner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Chris Hanks
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pg
|