pg_examiner 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/spec/schema_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe PGExaminer do
@@ -49,18 +51,18 @@ describe PGExaminer do
49
51
  c.should == c
50
52
 
51
53
  a.diff(a).should == {}
52
- a.diff(b).should == {schemas: {added: ['test_schema_b'], removed: ['test_schema_a']}}
53
- a.diff(c).should == {schemas: {removed: ['test_schema_a']}}
54
- b.diff(a).should == {schemas: {added: ['test_schema_a'], removed: ['test_schema_b']}}
54
+ a.diff(b).should == {"schemas" => {"added" => ['test_schema_b'], "removed" => ['test_schema_a']}}
55
+ a.diff(c).should == {"schemas" => {"removed" => ['test_schema_a']}}
56
+ b.diff(a).should == {"schemas" => {"added" => ['test_schema_a'], "removed" => ['test_schema_b']}}
55
57
  b.diff(b).should == {}
56
- b.diff(c).should == {schemas: {removed: ['test_schema_b']}}
57
- c.diff(a).should == {schemas: {added: ['test_schema_a']}}
58
- c.diff(b).should == {schemas: {added: ['test_schema_b']}}
58
+ b.diff(c).should == {"schemas" => {"removed" => ['test_schema_b']}}
59
+ c.diff(a).should == {"schemas" => {"added" => ['test_schema_a']}}
60
+ c.diff(b).should == {"schemas" => {"added" => ['test_schema_b']}}
59
61
  c.diff(c).should == {}
60
62
  end
61
63
 
62
64
  it "should be able to compare the contents of different schemas" do
63
- a = examine <<-SQL, :schema1
65
+ a = examine <<-SQL, "schema1"
64
66
  CREATE SCHEMA schema1;
65
67
  CREATE TABLE schema1.test_table (
66
68
  a integer,
@@ -68,7 +70,7 @@ describe PGExaminer do
68
70
  );
69
71
  SQL
70
72
 
71
- b = examine <<-SQL, :schema2
73
+ b = examine <<-SQL, "schema2"
72
74
  CREATE SCHEMA schema2;
73
75
  CREATE TABLE schema2.test_table (
74
76
  a integer,
@@ -76,7 +78,7 @@ describe PGExaminer do
76
78
  );
77
79
  SQL
78
80
 
79
- c = examine <<-SQL, :schema2
81
+ c = examine <<-SQL, "schema2"
80
82
  CREATE SCHEMA schema2;
81
83
  CREATE TABLE schema2.test_table_2 (
82
84
  a integer,
@@ -84,7 +86,7 @@ describe PGExaminer do
84
86
  );
85
87
  SQL
86
88
 
87
- d = examine <<-SQL, :schema2
89
+ d = examine <<-SQL, "schema2"
88
90
  CREATE SCHEMA schema2;
89
91
  SQL
90
92
 
@@ -93,7 +95,7 @@ describe PGExaminer do
93
95
  b.diff(a).should == {}
94
96
 
95
97
  a.should_not == c
96
- a.diff(c).should == {tables: {added: ['test_table_2'], removed: ['test_table']}}
97
- a.diff(d).should == {tables: {removed: ['test_table']}}
98
+ a.diff(c).should == {"tables" => {"added" => ['test_table_2'], "removed" => ['test_table']}}
99
+ a.diff(d).should == {"tables" => {"removed" => ['test_table']}}
98
100
  end
99
101
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe PGExaminer do
6
+ it "should be able to tell when a sequence exists" do
7
+ a = examine ""
8
+
9
+ b = examine <<-SQL
10
+ CREATE SEQUENCE my_sequence;
11
+ SQL
12
+
13
+ c = examine <<-SQL
14
+ CREATE SEQUENCE my_other_sequence;
15
+ SQL
16
+
17
+ a.diff(b).should == {"schemas"=>{"public"=>{"sequences"=>{"added"=>["my_sequence"]}}}}
18
+ a.diff(c).should == {"schemas"=>{"public"=>{"sequences"=>{"added"=>["my_other_sequence"]}}}}
19
+ b.diff(c).should == {"schemas"=>{"public"=>{"sequences"=>{"added"=>["my_other_sequence"], "removed"=>["my_sequence"]}}}}
20
+ end
21
+
22
+ it "should be able to tell when a table is associated with an index" do
23
+ a = examine <<-SQL
24
+ CREATE TABLE test_table (
25
+ id serial
26
+ )
27
+ SQL
28
+
29
+ b = examine <<-SQL
30
+ CREATE SEQUENCE test_table_id_seq;
31
+
32
+ CREATE TABLE test_table (
33
+ id integer NOT NULL default nextval('test_table_id_seq')
34
+ )
35
+ SQL
36
+
37
+ a.diff(b).should == {}
38
+
39
+ # TODO: Add concept of the column owning the sequence?
40
+ end
41
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'uri'
2
4
  require 'pg'
3
5
  require 'pry'
data/spec/table_spec.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
5
  describe PGExaminer do
@@ -21,7 +23,7 @@ describe PGExaminer do
21
23
  table.should be_an_instance_of PGExaminer::Result::Table
22
24
  table.columns.length.should == 2
23
25
 
24
- id, body = table.columns # Returned in proper ordering
26
+ body, id = table.columns # Returned in alphabetical ordering
25
27
 
26
28
  id.should be_an_instance_of PGExaminer::Result::Column
27
29
  id.name.should == 'id'
@@ -85,7 +87,7 @@ describe PGExaminer do
85
87
 
86
88
  a.should_not == b
87
89
 
88
- a.diff(b).should == {:schemas=>{"public"=>{:tables=>{:added=>["test_table_b"], :removed=>["test_table_a"]}}}}
90
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"added"=>["test_table_b"], "removed"=>["test_table_a"]}, "sequences"=>{"added"=>["test_table_b_id_seq"], "removed"=>["test_table_a_id_seq"]}}}}
89
91
  end
90
92
 
91
93
  it "should consider tables with current columns in the same order equivalent" do
@@ -136,9 +138,7 @@ describe PGExaminer do
136
138
  )
137
139
  SQL
138
140
 
139
- a.should_not == b
140
-
141
- a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{}}}}}}
141
+ a.should == b
142
142
  end
143
143
 
144
144
  it "should consider tables with columns of differing types not equivalent" do
@@ -163,8 +163,8 @@ describe PGExaminer do
163
163
  a.should_not == b
164
164
  a.should_not == c
165
165
 
166
- a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{"a"=>{:type=>{"int4"=>"text"}}}}}}}}
167
- a.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{"a"=>{:default=>{nil=>"5"}}}}}}}}
166
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"columns"=>{"a"=>{"type"=>{"int4"=>"text"}}}}}}}}
167
+ a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"columns"=>{"a"=>{"default"=>{nil=>"5"}}}}}}}}
168
168
  end
169
169
 
170
170
  it "should consider array types as different from scalar types" do
@@ -182,7 +182,7 @@ describe PGExaminer do
182
182
 
183
183
  a.should_not == b
184
184
 
185
- a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{"a"=>{:attndims=>{"0"=>"1"}, :type=>{"int4"=>"_int4"}}}}}}}}
185
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"columns"=>{"a"=>{"array dimensionality"=>{"0"=>"1"}, "type"=>{"int4"=>"_int4"}}}}}}}}
186
186
  end
187
187
 
188
188
  it "should consider the presence of not-null constraints" do
@@ -200,7 +200,7 @@ describe PGExaminer do
200
200
 
201
201
  a.should_not == b
202
202
 
203
- a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{"a"=>{:attnotnull=>{"f"=>"t"}}}}}}}}
203
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"columns"=>{"a"=>{"column is marked not-null"=>{"f"=>"t"}}}}}}}}
204
204
  end
205
205
 
206
206
  it "should consider the presence of type-specific data" do
@@ -218,7 +218,7 @@ describe PGExaminer do
218
218
 
219
219
  a.should_not == b
220
220
 
221
- a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{"a"=>{:atttypmod=>{"53"=>"54"}}}}}}}}
221
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"columns"=>{"a"=>{"datatype information (atttypmod)"=>{"53"=>"54"}}}}}}}}
222
222
  end
223
223
 
224
224
  it "should consider unlogged and temporary tables as different from permanent tables" do
@@ -244,9 +244,9 @@ describe PGExaminer do
244
244
  a.should_not == c
245
245
  b.should_not == c
246
246
 
247
- a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:relpersistence=>{"p"=>"u"}}}}}}
248
- a.diff(c).should == {:schemas=>{"public"=>{:tables=>{:removed=>["test_table"]}}}}
249
- b.diff(c).should == {:schemas=>{"public"=>{:tables=>{:removed=>["test_table"]}}}}
247
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"table type (relpersistence)"=>{"p"=>"u"}}}}}}
248
+ a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"removed"=>["test_table"]}}}}
249
+ b.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"removed"=>["test_table"]}}}}
250
250
  end
251
251
 
252
252
  it "should consider additional specified options when comparing tables" do
@@ -282,8 +282,8 @@ describe PGExaminer do
282
282
  b.should_not == c
283
283
  c.should == d
284
284
 
285
- a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:reloptions=>{nil=>"{fillfactor=90}"}}}}}}
286
- a.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:reloptions=>{nil=>"{fillfactor=70}"}}}}}}
287
- b.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:reloptions=>{"{fillfactor=90}"=>"{fillfactor=70}"}}}}}}
285
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"table options"=>{nil=>"{fillfactor=90}"}}}}}}
286
+ a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"table options"=>{nil=>"{fillfactor=70}"}}}}}}
287
+ b.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"table options"=>{"{fillfactor=90}"=>"{fillfactor=70}"}}}}}}
288
288
  end
289
289
  end
@@ -0,0 +1,310 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe PGExaminer do
6
+ it "should be able to differentiate between triggers by their names" do
7
+ a = examine <<-SQL
8
+ CREATE TABLE test_table (
9
+ a integer
10
+ );
11
+
12
+ CREATE FUNCTION func() RETURNS trigger AS $$
13
+ BEGIN
14
+ NEW.a = 56;
15
+ RETURN NEW;
16
+ END;
17
+ $$
18
+ LANGUAGE plpgsql;
19
+
20
+ CREATE TRIGGER trig BEFORE INSERT ON test_table FOR EACH ROW EXECUTE PROCEDURE func();
21
+ SQL
22
+
23
+ b = examine <<-SQL
24
+ CREATE TABLE test_table (
25
+ a integer
26
+ );
27
+
28
+ CREATE FUNCTION func() RETURNS trigger AS $$
29
+ BEGIN
30
+ NEW.a = 56;
31
+ RETURN NEW;
32
+ END;
33
+ $$
34
+ LANGUAGE plpgsql;
35
+
36
+ CREATE TRIGGER trig BEFORE INSERT ON test_table FOR EACH ROW EXECUTE PROCEDURE func();
37
+ SQL
38
+
39
+ c = examine <<-SQL
40
+ CREATE TABLE test_table (
41
+ a integer
42
+ );
43
+
44
+ CREATE FUNCTION func() RETURNS trigger AS $$
45
+ BEGIN
46
+ NEW.a = 56;
47
+ RETURN NEW;
48
+ END;
49
+ $$
50
+ LANGUAGE plpgsql;
51
+
52
+ CREATE TRIGGER trig2 BEFORE INSERT ON test_table FOR EACH ROW EXECUTE PROCEDURE func();
53
+ SQL
54
+
55
+ a.should == b
56
+ a.should_not == c
57
+ b.should_not == c
58
+
59
+ a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"triggers"=>{"added"=>["trig2"], "removed"=>["trig"]}}}}}}
60
+ b.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"triggers"=>{"added"=>["trig2"], "removed"=>["trig"]}}}}}}
61
+ end
62
+
63
+ it "should be able to differentiate between triggers by their parent tables" do
64
+ a = examine <<-SQL
65
+ CREATE TABLE test_table_a (
66
+ a integer
67
+ );
68
+
69
+ CREATE TABLE test_table_b (
70
+ a integer
71
+ );
72
+
73
+ CREATE FUNCTION func() RETURNS trigger AS $$
74
+ BEGIN
75
+ NEW.a = 56;
76
+ RETURN NEW;
77
+ END;
78
+ $$
79
+ LANGUAGE plpgsql;
80
+
81
+ CREATE TRIGGER trig BEFORE INSERT ON test_table_a FOR EACH ROW EXECUTE PROCEDURE func();
82
+ SQL
83
+
84
+ b = examine <<-SQL
85
+ CREATE TABLE test_table_a (
86
+ a integer
87
+ );
88
+
89
+ CREATE TABLE test_table_b (
90
+ a integer
91
+ );
92
+
93
+ CREATE FUNCTION func() RETURNS trigger AS $$
94
+ BEGIN
95
+ NEW.a = 56;
96
+ RETURN NEW;
97
+ END;
98
+ $$
99
+ LANGUAGE plpgsql;
100
+
101
+ CREATE TRIGGER trig BEFORE INSERT ON test_table_b FOR EACH ROW EXECUTE PROCEDURE func();
102
+ SQL
103
+
104
+ a.should_not == b
105
+
106
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table_a"=>{"triggers"=>{"removed"=>["trig"]}}, "test_table_b"=>{"triggers"=>{"added"=>["trig"]}}}}}}
107
+ end
108
+
109
+ it "should be able to differentiate between triggers by their associated functions" do
110
+ a = examine <<-SQL
111
+ CREATE TABLE test_table (
112
+ a integer
113
+ );
114
+
115
+ CREATE FUNCTION func1() RETURNS trigger AS $$
116
+ BEGIN
117
+ NEW.a = 56;
118
+ RETURN NEW;
119
+ END;
120
+ $$
121
+ LANGUAGE plpgsql;
122
+
123
+ CREATE FUNCTION func2() RETURNS trigger AS $$
124
+ BEGIN
125
+ NEW.a = 56;
126
+ RETURN NEW;
127
+ END;
128
+ $$
129
+ LANGUAGE plpgsql;
130
+
131
+ CREATE TRIGGER trig BEFORE INSERT ON test_table FOR EACH ROW EXECUTE PROCEDURE func1();
132
+ SQL
133
+
134
+ b = examine <<-SQL
135
+ CREATE TABLE test_table (
136
+ a integer
137
+ );
138
+
139
+ CREATE FUNCTION func1() RETURNS trigger AS $$
140
+ BEGIN
141
+ NEW.a = 56;
142
+ RETURN NEW;
143
+ END;
144
+ $$
145
+ LANGUAGE plpgsql;
146
+
147
+ CREATE FUNCTION func2() RETURNS trigger AS $$
148
+ BEGIN
149
+ NEW.a = 56;
150
+ RETURN NEW;
151
+ END;
152
+ $$
153
+ LANGUAGE plpgsql;
154
+
155
+ CREATE TRIGGER trig BEFORE INSERT ON test_table FOR EACH ROW EXECUTE PROCEDURE func2();
156
+ SQL
157
+
158
+ a.should_not == b
159
+
160
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"triggers"=>{"trig"=>{"function"=>{"func1"=>"func2"}}}}}}}}
161
+ end
162
+
163
+ it "should be able to differentiate between triggers by their firing conditions" do
164
+ a = examine <<-SQL
165
+ CREATE TABLE test_table (
166
+ a integer
167
+ );
168
+
169
+ CREATE FUNCTION func() RETURNS trigger AS $$
170
+ BEGIN
171
+ NEW.a = 56;
172
+ RETURN NEW;
173
+ END;
174
+ $$
175
+ LANGUAGE plpgsql;
176
+
177
+ CREATE TRIGGER trig BEFORE INSERT ON test_table FOR EACH ROW EXECUTE PROCEDURE func();
178
+ SQL
179
+
180
+ b = examine <<-SQL
181
+ CREATE TABLE test_table (
182
+ a integer
183
+ );
184
+
185
+ CREATE FUNCTION func() RETURNS trigger AS $$
186
+ BEGIN
187
+ NEW.a = 56;
188
+ RETURN NEW;
189
+ END;
190
+ $$
191
+ LANGUAGE plpgsql;
192
+
193
+ CREATE TRIGGER trig BEFORE UPDATE ON test_table FOR EACH ROW EXECUTE PROCEDURE func();
194
+ SQL
195
+
196
+ c = examine <<-SQL
197
+ CREATE TABLE test_table (
198
+ a integer
199
+ );
200
+
201
+ CREATE FUNCTION func() RETURNS trigger AS $$
202
+ BEGIN
203
+ NEW.a = 56;
204
+ RETURN NEW;
205
+ END;
206
+ $$
207
+ LANGUAGE plpgsql;
208
+
209
+ CREATE TRIGGER trig BEFORE DELETE ON test_table FOR EACH ROW EXECUTE PROCEDURE func();
210
+ SQL
211
+
212
+ a.should_not == b
213
+ a.should_not == c
214
+ b.should_not == c
215
+
216
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"triggers"=>{"trig"=>{"trigger firing conditions (tgtype)"=>{"7"=>"19"}}}}}}}}
217
+ end
218
+
219
+ it "should be able to differentiate between normal triggers and constraint triggers" do
220
+ a = examine <<-SQL
221
+ CREATE TABLE test_table (
222
+ a integer
223
+ );
224
+
225
+ CREATE FUNCTION func() RETURNS trigger AS $$
226
+ BEGIN
227
+ NEW.a = 56;
228
+ RETURN NEW;
229
+ END;
230
+ $$
231
+ LANGUAGE plpgsql;
232
+
233
+ CREATE TRIGGER trig AFTER INSERT ON test_table FOR EACH ROW EXECUTE PROCEDURE func();
234
+ SQL
235
+
236
+ b = examine <<-SQL
237
+ CREATE TABLE test_table (
238
+ a integer
239
+ );
240
+
241
+ CREATE FUNCTION func() RETURNS trigger AS $$
242
+ BEGIN
243
+ NEW.a = 56;
244
+ RETURN NEW;
245
+ END;
246
+ $$
247
+ LANGUAGE plpgsql;
248
+
249
+ CREATE CONSTRAINT TRIGGER trig AFTER INSERT ON test_table FOR EACH ROW EXECUTE PROCEDURE func();
250
+ SQL
251
+
252
+ a.should_not == b
253
+
254
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"added"=>["trig"]}}}}}}
255
+ end
256
+
257
+ it "should be able to differentiate between deferrable and non-deferrable constraint triggers" do
258
+ a = examine <<-SQL
259
+ CREATE TABLE test_table (
260
+ a integer
261
+ );
262
+
263
+ CREATE FUNCTION func() RETURNS trigger AS $$
264
+ BEGIN
265
+ NEW.a = 56;
266
+ RETURN NEW;
267
+ END;
268
+ $$
269
+ LANGUAGE plpgsql;
270
+
271
+ CREATE CONSTRAINT TRIGGER trig AFTER INSERT ON test_table FOR EACH ROW EXECUTE PROCEDURE func();
272
+ SQL
273
+
274
+ b = examine <<-SQL
275
+ CREATE TABLE test_table (
276
+ a integer
277
+ );
278
+
279
+ CREATE FUNCTION func() RETURNS trigger AS $$
280
+ BEGIN
281
+ NEW.a = 56;
282
+ RETURN NEW;
283
+ END;
284
+ $$
285
+ LANGUAGE plpgsql;
286
+
287
+ CREATE CONSTRAINT TRIGGER trig AFTER INSERT ON test_table DEFERRABLE FOR EACH ROW EXECUTE PROCEDURE func();
288
+ SQL
289
+
290
+ c = examine <<-SQL
291
+ CREATE TABLE test_table (
292
+ a integer
293
+ );
294
+
295
+ CREATE FUNCTION func() RETURNS trigger AS $$
296
+ BEGIN
297
+ NEW.a = 56;
298
+ RETURN NEW;
299
+ END;
300
+ $$
301
+ LANGUAGE plpgsql;
302
+
303
+ CREATE CONSTRAINT TRIGGER trig AFTER INSERT ON test_table DEFERRABLE INITIALLY DEFERRED FOR EACH ROW EXECUTE PROCEDURE func();
304
+ SQL
305
+
306
+ a.diff(b).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"trig"=>{"constraint definition"=>{"TRIGGER"=>"TRIGGER DEFERRABLE"}}}}}}}}
307
+ a.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"trig"=>{"constraint definition"=>{"TRIGGER"=>"TRIGGER DEFERRABLE INITIALLY DEFERRED"}}}}}}}}
308
+ b.diff(c).should == {"schemas"=>{"public"=>{"tables"=>{"test_table"=>{"constraints"=>{"trig"=>{"constraint definition"=>{"TRIGGER DEFERRABLE"=>"TRIGGER DEFERRABLE INITIALLY DEFERRED"}}}}}}}}
309
+ end
310
+ end