pg_examiner 0.2.0 → 0.3.0
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 +7 -7
- data/lib/pg_examiner/base.rb +72 -0
- data/lib/pg_examiner/result/column.rb +8 -8
- data/lib/pg_examiner/result/constraint.rb +4 -2
- data/lib/pg_examiner/result/extension.rb +19 -6
- data/lib/pg_examiner/result/function.rb +8 -9
- data/lib/pg_examiner/result/index.rb +8 -7
- data/lib/pg_examiner/result/{base.rb → item.rb} +1 -6
- data/lib/pg_examiner/result/language.rb +4 -2
- data/lib/pg_examiner/result/schema.rb +4 -8
- data/lib/pg_examiner/result/table.rb +8 -10
- data/lib/pg_examiner/result/trigger.rb +8 -7
- data/lib/pg_examiner/result.rb +17 -22
- data/lib/pg_examiner/version.rb +1 -1
- data/spec/constraint_spec.rb +41 -0
- data/spec/extension_spec.rb +9 -6
- data/spec/function_spec.rb +17 -0
- data/spec/index_spec.rb +51 -34
- data/spec/schema_spec.rb +56 -0
- data/spec/spec_helper.rb +2 -0
- data/spec/table_spec.rb +64 -43
- metadata +63 -51
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
|
-
---
|
2
|
-
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
5
|
-
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 81a303d82801100e755a80fbf08ac0b6b9d0f254
|
4
|
+
data.tar.gz: 0dc95a111058c548e1281a1b0694d0d97d170537
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bcace5f639bc93c559f2ae2ab802f741a858c0a79d5071a3ba94d88b06cd26cc9f2ce3f4816d2ab6a4c3450408a706ae2b11c64821ba5fe39543be26a247c8dd
|
7
|
+
data.tar.gz: 0606ea636a20e128179ec6ee679ec0b6e9445a2cf4e5ca620095f3fc52a9f3a57dd7d4c44bf69d949f87c57f67555f8e2b5a010cad532c8e83ca5cebce02a65f
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module PGExaminer
|
2
|
+
class Base
|
3
|
+
def diffable_lists
|
4
|
+
[]
|
5
|
+
end
|
6
|
+
|
7
|
+
def diffable_attrs
|
8
|
+
[]
|
9
|
+
end
|
10
|
+
|
11
|
+
def diffable_methods
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
|
15
|
+
def diff(other)
|
16
|
+
raise "Can't diff a #{self.class} and a #{other.class}" unless self.class == other.class
|
17
|
+
|
18
|
+
r = {}
|
19
|
+
|
20
|
+
diffable_attrs.each do |attr|
|
21
|
+
this = @row.fetch(attr.to_s)
|
22
|
+
that = other.row.fetch(attr.to_s)
|
23
|
+
|
24
|
+
unless this == that
|
25
|
+
r[attr] = {this => that}
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
diffable_methods.each do |attr|
|
30
|
+
this = send(attr)
|
31
|
+
that = other.send(attr)
|
32
|
+
|
33
|
+
unless this == that
|
34
|
+
r[attr] = {this => that}
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
diffable_lists.each do |attr|
|
39
|
+
these = send(attr)
|
40
|
+
those = other.send(attr)
|
41
|
+
these_names = these.map(&:name)
|
42
|
+
those_names = those.map(&:name)
|
43
|
+
|
44
|
+
if these_names == those_names
|
45
|
+
result = these.zip(those).each_with_object({}) do |(this, that), hash|
|
46
|
+
if (result = this.diff(that)).any?
|
47
|
+
hash[this.name] = result
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
if result.any?
|
52
|
+
r[attr] = result
|
53
|
+
end
|
54
|
+
else
|
55
|
+
added = those_names - these_names
|
56
|
+
removed = these_names - those_names
|
57
|
+
|
58
|
+
h = {}
|
59
|
+
h[:added] = added if added.any?
|
60
|
+
h[:removed] = removed if removed.any?
|
61
|
+
r[attr] = h
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
r
|
66
|
+
end
|
67
|
+
|
68
|
+
def ==(other)
|
69
|
+
self.class == other.class && diff(other) == {}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -1,7 +1,13 @@
|
|
1
1
|
module PGExaminer
|
2
2
|
class Result
|
3
|
-
class Column <
|
4
|
-
|
3
|
+
class Column < Item
|
4
|
+
def diffable_methods
|
5
|
+
[:type, :default]
|
6
|
+
end
|
7
|
+
|
8
|
+
def diffable_attrs
|
9
|
+
[:name, :attndims, :attnotnull, :atttypmod]
|
10
|
+
end
|
5
11
|
|
6
12
|
def type
|
7
13
|
@type ||= result.pg_type.find{|t| t['oid'] == row['atttypid']}['name']
|
@@ -16,12 +22,6 @@ module PGExaminer
|
|
16
22
|
@default = result.pg_attrdef.find{|d| d['adrelid'] == row['attrelid']}['default'] if row['atthasdef'] == 't'
|
17
23
|
end
|
18
24
|
end
|
19
|
-
|
20
|
-
def ==(other)
|
21
|
-
super &&
|
22
|
-
type == other.type &&
|
23
|
-
default == other.default
|
24
|
-
end
|
25
25
|
end
|
26
26
|
end
|
27
27
|
end
|
@@ -1,15 +1,28 @@
|
|
1
1
|
module PGExaminer
|
2
2
|
class Result
|
3
|
-
class Extension <
|
4
|
-
|
3
|
+
class Extension < Item
|
4
|
+
def diffable_attrs
|
5
|
+
[:name, :extversion]
|
6
|
+
end
|
7
|
+
|
8
|
+
def diffable_methods
|
9
|
+
[:schema_name]
|
10
|
+
end
|
5
11
|
|
6
12
|
def schema
|
7
|
-
|
13
|
+
# Extensions installed in system schemas won't be returned, so @schema
|
14
|
+
# will be nil in that case.
|
15
|
+
|
16
|
+
if @schema_calculated
|
17
|
+
@schema
|
18
|
+
else
|
19
|
+
@schema_calculated = true
|
20
|
+
@schema = result.schemas.find{|s| s.oid == row['extnamespace']}
|
21
|
+
end
|
8
22
|
end
|
9
23
|
|
10
|
-
def
|
11
|
-
|
12
|
-
(schema && schema.name) == (other.schema && other.schema.name)
|
24
|
+
def schema_name
|
25
|
+
schema && schema.name
|
13
26
|
end
|
14
27
|
end
|
15
28
|
end
|
@@ -1,7 +1,13 @@
|
|
1
1
|
module PGExaminer
|
2
2
|
class Result
|
3
|
-
class Function <
|
4
|
-
|
3
|
+
class Function < Item
|
4
|
+
def diffable_attrs
|
5
|
+
[:name, :proargmodes, :definition]
|
6
|
+
end
|
7
|
+
|
8
|
+
def diffable_methods
|
9
|
+
[:argument_types, :return_type, :language]
|
10
|
+
end
|
5
11
|
|
6
12
|
def argument_types
|
7
13
|
@argument_types ||= @row['proargtypes'].split.map do |oid|
|
@@ -16,13 +22,6 @@ module PGExaminer
|
|
16
22
|
def language
|
17
23
|
@language ||= result.pg_language.find{|l| l['oid'] == @row['prolang']}['name']
|
18
24
|
end
|
19
|
-
|
20
|
-
def ==(other)
|
21
|
-
super &&
|
22
|
-
argument_types == other.argument_types &&
|
23
|
-
return_type == other.return_type &&
|
24
|
-
language == other.language
|
25
|
-
end
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
@@ -1,15 +1,16 @@
|
|
1
1
|
module PGExaminer
|
2
2
|
class Result
|
3
|
-
class Index <
|
4
|
-
|
3
|
+
class Index < Item
|
4
|
+
def diffable_attrs
|
5
|
+
[:name, :filter, :indisunique, :indisprimary]
|
6
|
+
end
|
5
7
|
|
6
|
-
def
|
7
|
-
|
8
|
+
def diffable_methods
|
9
|
+
[:expression]
|
8
10
|
end
|
9
11
|
|
10
|
-
def
|
11
|
-
|
12
|
-
expression == other.expression
|
12
|
+
def expression
|
13
|
+
@row['expression'] || @row['indkey'].split.map{|i| parent.columns.find{|c| c.row['attnum'] == i}}.map(&:name)
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module PGExaminer
|
2
2
|
class Result
|
3
|
-
class Base
|
3
|
+
class Item < Base
|
4
4
|
attr_reader :result, :row, :parent
|
5
5
|
|
6
6
|
def initialize(result, row, parent = nil)
|
@@ -15,11 +15,6 @@ module PGExaminer
|
|
15
15
|
@row['name']
|
16
16
|
end
|
17
17
|
|
18
|
-
def ==(other)
|
19
|
-
columns = self.class::COMPARISON_COLUMNS
|
20
|
-
self.class == other.class && row.values_at(*columns) == other.row.values_at(*columns)
|
21
|
-
end
|
22
|
-
|
23
18
|
def inspect
|
24
19
|
"#<#{self.class} @row=#{@row.inspect}>"
|
25
20
|
end
|
@@ -1,7 +1,9 @@
|
|
1
1
|
module PGExaminer
|
2
2
|
class Result
|
3
|
-
class Schema <
|
4
|
-
|
3
|
+
class Schema < Item
|
4
|
+
def diffable_lists
|
5
|
+
[:tables, :functions]
|
6
|
+
end
|
5
7
|
|
6
8
|
def tables
|
7
9
|
@tables ||= result.pg_class.select do |c|
|
@@ -14,12 +16,6 @@ module PGExaminer
|
|
14
16
|
c['pronamespace'] == oid
|
15
17
|
end.map{|row| Function.new(result, row, self)}.sort_by(&:name)
|
16
18
|
end
|
17
|
-
|
18
|
-
def ==(other)
|
19
|
-
super &&
|
20
|
-
tables == other.tables &&
|
21
|
-
functions == other.functions
|
22
|
-
end
|
23
19
|
end
|
24
20
|
end
|
25
21
|
end
|
@@ -1,7 +1,13 @@
|
|
1
1
|
module PGExaminer
|
2
2
|
class Result
|
3
|
-
class Table <
|
4
|
-
|
3
|
+
class Table < Item
|
4
|
+
def diffable_lists
|
5
|
+
[:columns, :indexes, :constraints, :triggers]
|
6
|
+
end
|
7
|
+
|
8
|
+
def diffable_attrs
|
9
|
+
[:name, :relpersistence, :reloptions]
|
10
|
+
end
|
5
11
|
|
6
12
|
def columns
|
7
13
|
@columns ||= result.pg_attribute.select do |c|
|
@@ -26,14 +32,6 @@ module PGExaminer
|
|
26
32
|
t['tgrelid'] == oid
|
27
33
|
end.map{|row| Trigger.new(result, row, self)}.sort_by(&:name)
|
28
34
|
end
|
29
|
-
|
30
|
-
def ==(other)
|
31
|
-
super &&
|
32
|
-
columns == other.columns &&
|
33
|
-
indexes == other.indexes &&
|
34
|
-
constraints == other.constraints &&
|
35
|
-
triggers == other.triggers
|
36
|
-
end
|
37
35
|
end
|
38
36
|
end
|
39
37
|
end
|
@@ -1,15 +1,16 @@
|
|
1
1
|
module PGExaminer
|
2
2
|
class Result
|
3
|
-
class Trigger <
|
4
|
-
|
3
|
+
class Trigger < Item
|
4
|
+
def diffable_attrs
|
5
|
+
[:name, :tgtype]
|
6
|
+
end
|
5
7
|
|
6
|
-
def
|
7
|
-
|
8
|
+
def diffable_methods
|
9
|
+
[:function]
|
8
10
|
end
|
9
11
|
|
10
|
-
def
|
11
|
-
|
12
|
-
function == other.function
|
12
|
+
def function
|
13
|
+
@function ||= result.pg_proc.find{|f| f['oid'] == @row['tgfoid']}['name']
|
13
14
|
end
|
14
15
|
end
|
15
16
|
end
|
data/lib/pg_examiner/result.rb
CHANGED
@@ -1,16 +1,7 @@
|
|
1
|
-
require 'pg_examiner/
|
2
|
-
require 'pg_examiner/result/column'
|
3
|
-
require 'pg_examiner/result/constraint'
|
4
|
-
require 'pg_examiner/result/extension'
|
5
|
-
require 'pg_examiner/result/function'
|
6
|
-
require 'pg_examiner/result/index'
|
7
|
-
require 'pg_examiner/result/language'
|
8
|
-
require 'pg_examiner/result/schema'
|
9
|
-
require 'pg_examiner/result/table'
|
10
|
-
require 'pg_examiner/result/trigger'
|
1
|
+
require 'pg_examiner/base'
|
11
2
|
|
12
3
|
module PGExaminer
|
13
|
-
class Result
|
4
|
+
class Result < Base
|
14
5
|
attr_reader :pg_namespace,
|
15
6
|
:pg_class,
|
16
7
|
:pg_type,
|
@@ -28,6 +19,10 @@ module PGExaminer
|
|
28
19
|
load_schema
|
29
20
|
end
|
30
21
|
|
22
|
+
def diffable_lists
|
23
|
+
[:schemas, :extensions, :languages]
|
24
|
+
end
|
25
|
+
|
31
26
|
def schemas
|
32
27
|
@schemas ||= @pg_namespace.map{|row| Schema.new(self, row)}.sort_by(&:name)
|
33
28
|
end
|
@@ -40,17 +35,6 @@ module PGExaminer
|
|
40
35
|
@languages ||= @pg_language.map{|row| Language.new(self, row)}.sort_by(&:name)
|
41
36
|
end
|
42
37
|
|
43
|
-
def ==(other)
|
44
|
-
# We want to be able to compare the contents of two schemas to each
|
45
|
-
# other, so compare names at the top level instead of schema-to-schema.
|
46
|
-
|
47
|
-
other.is_a?(Result) &&
|
48
|
-
schemas.map(&:name) == other.schemas.map(&:name) &&
|
49
|
-
schemas == other.schemas &&
|
50
|
-
extensions == other.extensions &&
|
51
|
-
languages == other.languages
|
52
|
-
end
|
53
|
-
|
54
38
|
def inspect
|
55
39
|
"#<#{self.class} @schemas=#{@schemas.inspect}, @extensions=#{@extensions.inspect}>"
|
56
40
|
end
|
@@ -147,3 +131,14 @@ module PGExaminer
|
|
147
131
|
end
|
148
132
|
end
|
149
133
|
end
|
134
|
+
|
135
|
+
require 'pg_examiner/result/item'
|
136
|
+
require 'pg_examiner/result/column'
|
137
|
+
require 'pg_examiner/result/constraint'
|
138
|
+
require 'pg_examiner/result/extension'
|
139
|
+
require 'pg_examiner/result/function'
|
140
|
+
require 'pg_examiner/result/index'
|
141
|
+
require 'pg_examiner/result/language'
|
142
|
+
require 'pg_examiner/result/schema'
|
143
|
+
require 'pg_examiner/result/table'
|
144
|
+
require 'pg_examiner/result/trigger'
|
data/lib/pg_examiner/version.rb
CHANGED
data/spec/constraint_spec.rb
CHANGED
@@ -50,6 +50,11 @@ describe PGExaminer do
|
|
50
50
|
a.should_not == e
|
51
51
|
a.should_not == f
|
52
52
|
e.should_not == f
|
53
|
+
|
54
|
+
a.diff(d).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:constraints=>{:added=>["con_two"], :removed=>["con"]}}}}}}
|
55
|
+
a.diff(e).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:constraints=>{:added=>["test_table_a_check"], :removed=>["con"]}}}}}}
|
56
|
+
a.diff(f).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:constraints=>{:removed=>["con"]}}}}}}
|
57
|
+
e.diff(f).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:constraints=>{:removed=>["test_table_a_check"]}}}}}}
|
53
58
|
end
|
54
59
|
|
55
60
|
it "should consider foreign keys when differentiating between schemas" do
|
@@ -118,6 +123,12 @@ describe PGExaminer do
|
|
118
123
|
b.should_not == d
|
119
124
|
b.should_not == e
|
120
125
|
d.should_not == e
|
126
|
+
|
127
|
+
a.diff(c).should == {:schemas=>{"public"=>{:tables=>{"child"=>{:constraints=>{"child_parent_id_fkey"=>{:definition=>{"FOREIGN KEY (parent_id) REFERENCES parent(int1)"=>"FOREIGN KEY (parent_id) REFERENCES parent(int2)"}}}}}}}}
|
128
|
+
b.diff(c).should == {:schemas=>{"public"=>{:tables=>{"child"=>{:constraints=>{"child_parent_id_fkey"=>{:definition=>{"FOREIGN KEY (parent_id) REFERENCES parent(int1)"=>"FOREIGN KEY (parent_id) REFERENCES parent(int2)"}}}}}}}}
|
129
|
+
b.diff(d).should == {:schemas=>{"public"=>{:tables=>{"child"=>{:constraints=>{"child_parent_id_fkey"=>{:definition=>{"FOREIGN KEY (parent_id) REFERENCES parent(int1)"=>"FOREIGN KEY (parent_id) REFERENCES parent(int1) ON UPDATE CASCADE"}}}}}}}}
|
130
|
+
b.diff(e).should == {:schemas=>{"public"=>{:tables=>{"child"=>{:constraints=>{"child_parent_id_fkey"=>{:definition=>{"FOREIGN KEY (parent_id) REFERENCES parent(int1)"=>"FOREIGN KEY (parent_id) REFERENCES parent(int1) ON DELETE CASCADE"}}}}}}}}
|
131
|
+
d.diff(e).should == {:schemas=>{"public"=>{:tables=>{"child"=>{:constraints=>{"child_parent_id_fkey"=>{:definition=>{"FOREIGN KEY (parent_id) REFERENCES parent(int1) ON UPDATE CASCADE"=>"FOREIGN KEY (parent_id) REFERENCES parent(int1) ON DELETE CASCADE"}}}}}}}}
|
121
132
|
end
|
122
133
|
|
123
134
|
it "should consider constraints when determining table equivalency" do
|
@@ -147,5 +158,35 @@ describe PGExaminer do
|
|
147
158
|
a.should_not == b
|
148
159
|
a.should_not == c
|
149
160
|
b.should == c
|
161
|
+
|
162
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:constraints=>{"con"=>{:definition=>{"CHECK ((a > 0)) NOT VALID"=>"CHECK ((a > 0))"}}}}}}}}
|
163
|
+
a.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:constraints=>{"con"=>{:definition=>{"CHECK ((a > 0)) NOT VALID"=>"CHECK ((a > 0))"}}}}}}}}
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should consider the tables each constraint is on" do
|
167
|
+
a = examine <<-SQL
|
168
|
+
CREATE TABLE test_table_1 (
|
169
|
+
a integer,
|
170
|
+
CONSTRAINT con CHECK (a > 0)
|
171
|
+
);
|
172
|
+
|
173
|
+
CREATE TABLE test_table_2 (
|
174
|
+
a integer
|
175
|
+
);
|
176
|
+
SQL
|
177
|
+
|
178
|
+
b = examine <<-SQL
|
179
|
+
CREATE TABLE test_table_1 (
|
180
|
+
a integer
|
181
|
+
);
|
182
|
+
|
183
|
+
CREATE TABLE test_table_2 (
|
184
|
+
a integer,
|
185
|
+
CONSTRAINT con CHECK (a > 0)
|
186
|
+
);
|
187
|
+
SQL
|
188
|
+
|
189
|
+
a.should_not == b
|
190
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table_1"=>{:constraints=>{:removed=>["con"]}}, "test_table_2"=>{:constraints=>{:added=>["con"]}}}}}}
|
150
191
|
end
|
151
192
|
end
|
data/spec/extension_spec.rb
CHANGED
@@ -2,17 +2,17 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe PGExaminer do
|
4
4
|
it "should be able to examine the extensions in the db" do
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
result1 = examine "SELECT 1"
|
6
|
+
result1.should be_an_instance_of PGExaminer::Result
|
7
|
+
result1.extensions.map(&:name).should == ['plpgsql']
|
8
8
|
|
9
|
-
|
9
|
+
result2 = examine <<-SQL
|
10
10
|
CREATE EXTENSION citext;
|
11
11
|
SQL
|
12
12
|
|
13
|
-
|
13
|
+
result2.extensions.length.should == 2
|
14
14
|
|
15
|
-
citext, plpgsql =
|
15
|
+
citext, plpgsql = result2.extensions # Ordered by name
|
16
16
|
|
17
17
|
citext.should be_an_instance_of PGExaminer::Result::Extension
|
18
18
|
citext.name.should == 'citext'
|
@@ -22,5 +22,8 @@ describe PGExaminer do
|
|
22
22
|
plpgsql.should be_an_instance_of PGExaminer::Result::Extension
|
23
23
|
plpgsql.name.should == 'plpgsql'
|
24
24
|
plpgsql.schema.should be nil
|
25
|
+
|
26
|
+
result1.diff(result2)[:extensions].should == {added: ['citext']}
|
27
|
+
result2.diff(result1)[:extensions].should == {removed: ['citext']}
|
25
28
|
end
|
26
29
|
end
|
data/spec/function_spec.rb
CHANGED
@@ -29,6 +29,9 @@ describe PGExaminer do
|
|
29
29
|
a.should == b
|
30
30
|
a.should_not == c
|
31
31
|
b.should_not == c
|
32
|
+
|
33
|
+
a.diff(c).should == {:schemas=>{"public"=>{:functions=>{:added=>["add_numbers"], :removed=>["add"]}}}}
|
34
|
+
b.diff(c).should == {:schemas=>{"public"=>{:functions=>{:added=>["add_numbers"], :removed=>["add"]}}}}
|
32
35
|
end
|
33
36
|
|
34
37
|
it "should be able to differentiate between functions by their argument types" do
|
@@ -70,6 +73,9 @@ describe PGExaminer do
|
|
70
73
|
b.should_not == c
|
71
74
|
b.should_not == d
|
72
75
|
c.should_not == d
|
76
|
+
|
77
|
+
a.diff(b).should == {:schemas=>{"public"=>{:functions=>{"add"=>{:definition=>{"CREATE OR REPLACE FUNCTION public.add(one integer, two integer)\n RETURNS integer\n LANGUAGE sql\nAS $function$\n SELECT one + two\n $function$\n"=>"CREATE OR REPLACE FUNCTION public.add(one integer, two integer, three integer)\n RETURNS integer\n LANGUAGE sql\nAS $function$\n SELECT one + two\n $function$\n"}, :argument_types=>{["int4", "int4"]=>["int4", "int4", "int4"]}}}}}}
|
78
|
+
a.diff(c).should == {:schemas=>{"public"=>{:functions=>{"add"=>{:definition=>{"CREATE OR REPLACE FUNCTION public.add(one integer, two integer)\n RETURNS integer\n LANGUAGE sql\nAS $function$\n SELECT one + two\n $function$\n"=>"CREATE OR REPLACE FUNCTION public.add(one integer, two integer, three integer[])\n RETURNS integer\n LANGUAGE sql\nAS $function$\n SELECT one + two\n $function$\n"}, :argument_types=>{["int4", "int4"]=>["int4", "int4", "_int4"]}}}}}}
|
73
79
|
end
|
74
80
|
|
75
81
|
it "should be able to differentiate between functions by their argument defaults" do
|
@@ -142,6 +148,8 @@ describe PGExaminer do
|
|
142
148
|
SQL_FUNCTION
|
143
149
|
|
144
150
|
a.should_not == b
|
151
|
+
|
152
|
+
a.diff(b)[:schemas]['public'][:functions]['add'][:language].should == {'sql' => 'plpgsql'}
|
145
153
|
end
|
146
154
|
|
147
155
|
it "should be able to differentiate between functions by their other flags" do
|
@@ -298,6 +306,9 @@ describe PGExaminer do
|
|
298
306
|
a.should == b
|
299
307
|
a.should_not == c
|
300
308
|
b.should_not == c
|
309
|
+
|
310
|
+
a.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:triggers=>{:added=>["trig2"], :removed=>["trig"]}}}}}}
|
311
|
+
b.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:triggers=>{:added=>["trig2"], :removed=>["trig"]}}}}}}
|
301
312
|
end
|
302
313
|
|
303
314
|
it "should be able to differentiate between triggers by their parent tables" do
|
@@ -342,6 +353,8 @@ describe PGExaminer do
|
|
342
353
|
SQL
|
343
354
|
|
344
355
|
a.should_not == b
|
356
|
+
|
357
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table_a"=>{:triggers=>{:removed=>["trig"]}}, "test_table_b"=>{:triggers=>{:added=>["trig"]}}}}}}
|
345
358
|
end
|
346
359
|
|
347
360
|
it "should be able to differentiate between triggers by their associated functions" do
|
@@ -394,6 +407,8 @@ describe PGExaminer do
|
|
394
407
|
SQL
|
395
408
|
|
396
409
|
a.should_not == b
|
410
|
+
|
411
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:triggers=>{"trig"=>{:function=>{"func1"=>"func2"}}}}}}}}
|
397
412
|
end
|
398
413
|
|
399
414
|
it "should be able to differentiate between triggers by their firing conditions" do
|
@@ -448,5 +463,7 @@ describe PGExaminer do
|
|
448
463
|
a.should_not == b
|
449
464
|
a.should_not == c
|
450
465
|
b.should_not == c
|
466
|
+
|
467
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:triggers=>{"trig"=>{:tgtype=>{"7"=>"19"}}}}}}}}
|
451
468
|
end
|
452
469
|
end
|
data/spec/index_spec.rb
CHANGED
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe PGExaminer do
|
4
4
|
it "should consider indexes when determining equivalency" do
|
5
|
-
|
5
|
+
a = examine <<-SQL
|
6
6
|
CREATE TABLE test_table (
|
7
7
|
id integer
|
8
8
|
);
|
@@ -10,7 +10,7 @@ describe PGExaminer do
|
|
10
10
|
CREATE INDEX int_idx ON test_table(id);
|
11
11
|
SQL
|
12
12
|
|
13
|
-
|
13
|
+
b = examine <<-SQL
|
14
14
|
CREATE TABLE test_table (
|
15
15
|
id integer
|
16
16
|
);
|
@@ -18,7 +18,7 @@ describe PGExaminer do
|
|
18
18
|
CREATE INDEX int_idx ON test_table(id);
|
19
19
|
SQL
|
20
20
|
|
21
|
-
|
21
|
+
c = examine <<-SQL
|
22
22
|
CREATE TABLE test_table (
|
23
23
|
id integer
|
24
24
|
);
|
@@ -26,13 +26,16 @@ describe PGExaminer do
|
|
26
26
|
CREATE INDEX int_idx2 ON test_table(id);
|
27
27
|
SQL
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
a.should == b
|
30
|
+
a.should_not == c
|
31
|
+
b.should_not == c
|
32
|
+
|
33
|
+
a.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:indexes=>{:added=>["int_idx2"], :removed=>["int_idx"]}}}}}}
|
34
|
+
b.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:indexes=>{:added=>["int_idx2"], :removed=>["int_idx"]}}}}}}
|
32
35
|
end
|
33
36
|
|
34
37
|
it "should consider the columns indexes are on when determining equivalency" do
|
35
|
-
|
38
|
+
a = examine <<-SQL
|
36
39
|
CREATE TABLE test_table (
|
37
40
|
a integer,
|
38
41
|
b integer
|
@@ -41,7 +44,7 @@ describe PGExaminer do
|
|
41
44
|
CREATE INDEX int_idx ON test_table(a);
|
42
45
|
SQL
|
43
46
|
|
44
|
-
|
47
|
+
b = examine <<-SQL
|
45
48
|
CREATE TABLE test_table (
|
46
49
|
a integer,
|
47
50
|
b integer
|
@@ -50,7 +53,7 @@ describe PGExaminer do
|
|
50
53
|
CREATE INDEX int_idx ON test_table(b);
|
51
54
|
SQL
|
52
55
|
|
53
|
-
|
56
|
+
c = examine <<-SQL
|
54
57
|
CREATE TABLE test_table (
|
55
58
|
a integer,
|
56
59
|
b integer
|
@@ -59,13 +62,17 @@ describe PGExaminer do
|
|
59
62
|
CREATE INDEX int_idx ON test_table(a, b);
|
60
63
|
SQL
|
61
64
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
+
a.should_not == b
|
66
|
+
a.should_not == c
|
67
|
+
b.should_not == c
|
68
|
+
|
69
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:indexes=>{"int_idx"=>{:expression=>{["a"]=>["b"]}}}}}}}}
|
70
|
+
a.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:indexes=>{"int_idx"=>{:expression=>{["a"]=>["a", "b"]}}}}}}}}
|
71
|
+
b.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:indexes=>{"int_idx"=>{:expression=>{["b"]=>["a", "b"]}}}}}}}}
|
65
72
|
end
|
66
73
|
|
67
74
|
it "should consider the filters indexes have when determining equivalency" do
|
68
|
-
|
75
|
+
a = examine <<-SQL
|
69
76
|
CREATE TABLE test_table (
|
70
77
|
a integer
|
71
78
|
);
|
@@ -73,9 +80,9 @@ describe PGExaminer do
|
|
73
80
|
CREATE INDEX int_idx ON test_table(a) WHERE a > 0;
|
74
81
|
SQL
|
75
82
|
|
76
|
-
|
83
|
+
a.schemas.first.tables.first.indexes.first.row['filter'].should == '(a > 0)'
|
77
84
|
|
78
|
-
|
85
|
+
b = examine <<-SQL
|
79
86
|
CREATE TABLE test_table (
|
80
87
|
a integer
|
81
88
|
);
|
@@ -83,9 +90,9 @@ describe PGExaminer do
|
|
83
90
|
CREATE INDEX int_idx ON test_table(a) WHERE a > 0;
|
84
91
|
SQL
|
85
92
|
|
86
|
-
|
93
|
+
b.schemas.first.tables.first.indexes.first.row['filter'].should == '(a > 0)'
|
87
94
|
|
88
|
-
|
95
|
+
c = examine <<-SQL
|
89
96
|
CREATE TABLE test_table (
|
90
97
|
a integer
|
91
98
|
);
|
@@ -93,13 +100,16 @@ describe PGExaminer do
|
|
93
100
|
CREATE INDEX int_idx ON test_table(a);
|
94
101
|
SQL
|
95
102
|
|
96
|
-
|
97
|
-
|
98
|
-
|
103
|
+
a.should == b
|
104
|
+
a.should_not == c
|
105
|
+
b.should_not == c
|
106
|
+
|
107
|
+
a.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:indexes=>{"int_idx"=>{:filter=>{"(a > 0)"=>nil}}}}}}}}
|
108
|
+
b.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:indexes=>{"int_idx"=>{:filter=>{"(a > 0)"=>nil}}}}}}}}
|
99
109
|
end
|
100
110
|
|
101
111
|
it "should consider the expressions indexes are on, if any" do
|
102
|
-
|
112
|
+
a = examine <<-SQL
|
103
113
|
CREATE TABLE test_table (
|
104
114
|
a text
|
105
115
|
);
|
@@ -107,9 +117,9 @@ describe PGExaminer do
|
|
107
117
|
CREATE INDEX text_idx ON test_table(lower(a));
|
108
118
|
SQL
|
109
119
|
|
110
|
-
|
120
|
+
a.schemas.first.tables.first.indexes.first.expression.should == 'lower(a)'
|
111
121
|
|
112
|
-
|
122
|
+
b = examine <<-SQL
|
113
123
|
CREATE TABLE test_table (
|
114
124
|
a text
|
115
125
|
);
|
@@ -117,9 +127,9 @@ describe PGExaminer do
|
|
117
127
|
CREATE INDEX text_idx ON test_table(LOWER(a));
|
118
128
|
SQL
|
119
129
|
|
120
|
-
|
130
|
+
b.schemas.first.tables.first.indexes.first.expression.should == 'lower(a)'
|
121
131
|
|
122
|
-
|
132
|
+
c = examine <<-SQL
|
123
133
|
CREATE TABLE test_table (
|
124
134
|
a text
|
125
135
|
);
|
@@ -127,13 +137,16 @@ describe PGExaminer do
|
|
127
137
|
CREATE INDEX text_idx ON test_table(a);
|
128
138
|
SQL
|
129
139
|
|
130
|
-
|
131
|
-
|
132
|
-
|
140
|
+
a.should == b
|
141
|
+
a.should_not == c
|
142
|
+
b.should_not == c
|
143
|
+
|
144
|
+
a.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:indexes=>{"text_idx"=>{:expression=>{"lower(a)"=>["a"]}}}}}}}}
|
145
|
+
b.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:indexes=>{"text_idx"=>{:expression=>{"lower(a)"=>["a"]}}}}}}}}
|
133
146
|
end
|
134
147
|
|
135
148
|
it "should consider the uniqueness and primary key status of an index, if any" do
|
136
|
-
|
149
|
+
a = examine <<-SQL
|
137
150
|
CREATE TABLE test_table (
|
138
151
|
a integer
|
139
152
|
);
|
@@ -141,7 +154,7 @@ describe PGExaminer do
|
|
141
154
|
CREATE INDEX int_idx ON test_table(a);
|
142
155
|
SQL
|
143
156
|
|
144
|
-
|
157
|
+
b = examine <<-SQL
|
145
158
|
CREATE TABLE test_table (
|
146
159
|
a integer
|
147
160
|
);
|
@@ -149,7 +162,7 @@ describe PGExaminer do
|
|
149
162
|
CREATE UNIQUE INDEX int_idx ON test_table(a);
|
150
163
|
SQL
|
151
164
|
|
152
|
-
|
165
|
+
c = examine <<-SQL
|
153
166
|
CREATE TABLE test_table (
|
154
167
|
a integer
|
155
168
|
);
|
@@ -157,8 +170,12 @@ describe PGExaminer do
|
|
157
170
|
ALTER TABLE test_table ADD PRIMARY KEY (a);
|
158
171
|
SQL
|
159
172
|
|
160
|
-
|
161
|
-
|
162
|
-
|
173
|
+
a.should_not == b
|
174
|
+
a.should_not == c
|
175
|
+
b.should_not == c
|
176
|
+
|
177
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:indexes=>{"int_idx"=>{:indisunique=>{"f"=>"t"}}}}}}}}
|
178
|
+
a.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{"a"=>{:attnotnull=>{"f"=>"t"}}}, :indexes=>{:added=>["test_table_pkey"], :removed=>["int_idx"]}, :constraints=>{:added=>["test_table_pkey"]}}}}}}
|
179
|
+
b.diff(c).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{"a"=>{:attnotnull=>{"f"=>"t"}}}, :indexes=>{:added=>["test_table_pkey"], :removed=>["int_idx"]}, :constraints=>{:added=>["test_table_pkey"]}}}}}}
|
163
180
|
end
|
164
181
|
end
|
data/spec/schema_spec.rb
CHANGED
@@ -10,6 +10,10 @@ describe PGExaminer do
|
|
10
10
|
schema.should be_an_instance_of PGExaminer::Result::Schema
|
11
11
|
schema.name.should == 'public'
|
12
12
|
schema.tables.should == []
|
13
|
+
|
14
|
+
other_result = examine("SELECT 1")
|
15
|
+
result.should == other_result
|
16
|
+
result.diff(other_result).should == {}
|
13
17
|
end
|
14
18
|
|
15
19
|
it "should detect other user-added schemas" do
|
@@ -21,6 +25,40 @@ describe PGExaminer do
|
|
21
25
|
result.schemas.map(&:name).should == %w(my_schema public)
|
22
26
|
end
|
23
27
|
|
28
|
+
it "should consider differently-named schemas non-equivalent" do
|
29
|
+
a = examine <<-SQL
|
30
|
+
CREATE SCHEMA test_schema_a;
|
31
|
+
SQL
|
32
|
+
|
33
|
+
b = examine <<-SQL
|
34
|
+
CREATE SCHEMA test_schema_b;
|
35
|
+
SQL
|
36
|
+
|
37
|
+
c = examine <<-SQL
|
38
|
+
SELECT 1;
|
39
|
+
SQL
|
40
|
+
|
41
|
+
a.should == a
|
42
|
+
a.should_not == b
|
43
|
+
a.should_not == c
|
44
|
+
b.should_not == a
|
45
|
+
b.should == b
|
46
|
+
b.should_not == c
|
47
|
+
c.should_not == a
|
48
|
+
c.should_not == b
|
49
|
+
c.should == c
|
50
|
+
|
51
|
+
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']}}
|
55
|
+
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']}}
|
59
|
+
c.diff(c).should == {}
|
60
|
+
end
|
61
|
+
|
24
62
|
it "should be able to compare the contents of different schemas" do
|
25
63
|
a = examine <<-SQL, :schema1
|
26
64
|
CREATE SCHEMA schema1;
|
@@ -38,6 +76,24 @@ describe PGExaminer do
|
|
38
76
|
);
|
39
77
|
SQL
|
40
78
|
|
79
|
+
c = examine <<-SQL, :schema2
|
80
|
+
CREATE SCHEMA schema2;
|
81
|
+
CREATE TABLE schema2.test_table_2 (
|
82
|
+
a integer,
|
83
|
+
b integer
|
84
|
+
);
|
85
|
+
SQL
|
86
|
+
|
87
|
+
d = examine <<-SQL, :schema2
|
88
|
+
CREATE SCHEMA schema2;
|
89
|
+
SQL
|
90
|
+
|
41
91
|
a.should == b
|
92
|
+
a.diff(b).should == {}
|
93
|
+
b.diff(a).should == {}
|
94
|
+
|
95
|
+
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']}}
|
42
98
|
end
|
43
99
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/table_spec.rb
CHANGED
@@ -51,43 +51,45 @@ describe PGExaminer do
|
|
51
51
|
end
|
52
52
|
|
53
53
|
it "should consider equivalent tables equivalent" do
|
54
|
-
|
54
|
+
a = examine <<-SQL
|
55
55
|
CREATE TABLE test_table (
|
56
56
|
id serial,
|
57
57
|
body text
|
58
58
|
)
|
59
59
|
SQL
|
60
60
|
|
61
|
-
|
61
|
+
b = examine <<-SQL
|
62
62
|
CREATE TABLE test_table (
|
63
63
|
id serial,
|
64
64
|
body text
|
65
65
|
)
|
66
66
|
SQL
|
67
67
|
|
68
|
-
|
68
|
+
a.should == b
|
69
69
|
end
|
70
70
|
|
71
71
|
it "should consider differently-named tables non-equivalent" do
|
72
|
-
|
72
|
+
a = examine <<-SQL
|
73
73
|
CREATE TABLE test_table_a (
|
74
74
|
id serial,
|
75
75
|
body text
|
76
76
|
)
|
77
77
|
SQL
|
78
78
|
|
79
|
-
|
79
|
+
b = examine <<-SQL
|
80
80
|
CREATE TABLE test_table_b (
|
81
81
|
id serial,
|
82
82
|
body text
|
83
83
|
)
|
84
84
|
SQL
|
85
85
|
|
86
|
-
|
86
|
+
a.should_not == b
|
87
|
+
|
88
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{:added=>["test_table_b"], :removed=>["test_table_a"]}}}}
|
87
89
|
end
|
88
90
|
|
89
91
|
it "should consider tables with current columns in the same order equivalent" do
|
90
|
-
|
92
|
+
a = examine <<-SQL
|
91
93
|
CREATE TABLE test_table (
|
92
94
|
a integer,
|
93
95
|
b integer,
|
@@ -97,14 +99,14 @@ describe PGExaminer do
|
|
97
99
|
ALTER TABLE test_table DROP COLUMN b;
|
98
100
|
SQL
|
99
101
|
|
100
|
-
|
102
|
+
b = examine <<-SQL
|
101
103
|
CREATE TABLE test_table (
|
102
104
|
a integer,
|
103
105
|
c integer
|
104
106
|
);
|
105
107
|
SQL
|
106
108
|
|
107
|
-
|
109
|
+
c = examine <<-SQL
|
108
110
|
CREATE TABLE test_table (
|
109
111
|
a integer
|
110
112
|
);
|
@@ -112,13 +114,13 @@ describe PGExaminer do
|
|
112
114
|
ALTER TABLE test_table ADD COLUMN c integer;
|
113
115
|
SQL
|
114
116
|
|
115
|
-
|
116
|
-
|
117
|
-
|
117
|
+
a.should == b
|
118
|
+
a.should == c
|
119
|
+
b.should == c
|
118
120
|
end
|
119
121
|
|
120
122
|
it "should consider tables with columns in differing orders not equivalent" do
|
121
|
-
|
123
|
+
a = examine <<-SQL
|
122
124
|
CREATE TABLE test_table (
|
123
125
|
a integer,
|
124
126
|
b integer,
|
@@ -126,7 +128,7 @@ describe PGExaminer do
|
|
126
128
|
);
|
127
129
|
SQL
|
128
130
|
|
129
|
-
|
131
|
+
b = examine <<-SQL
|
130
132
|
CREATE TABLE test_table (
|
131
133
|
a integer,
|
132
134
|
c integer,
|
@@ -134,135 +136,154 @@ describe PGExaminer do
|
|
134
136
|
)
|
135
137
|
SQL
|
136
138
|
|
137
|
-
|
139
|
+
a.should_not == b
|
140
|
+
|
141
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{}}}}}}
|
138
142
|
end
|
139
143
|
|
140
144
|
it "should consider tables with columns of differing types not equivalent" do
|
141
|
-
|
145
|
+
a = examine <<-SQL
|
142
146
|
CREATE TABLE test_table (
|
143
147
|
a integer
|
144
148
|
);
|
145
149
|
SQL
|
146
150
|
|
147
|
-
|
151
|
+
b = examine <<-SQL
|
148
152
|
CREATE TABLE test_table (
|
149
153
|
a text
|
150
154
|
)
|
151
155
|
SQL
|
152
156
|
|
153
|
-
|
157
|
+
c = examine <<-SQL
|
154
158
|
CREATE TABLE test_table (
|
155
159
|
a integer default 5
|
156
160
|
);
|
157
161
|
SQL
|
158
162
|
|
159
|
-
|
160
|
-
|
163
|
+
a.should_not == b
|
164
|
+
a.should_not == c
|
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"}}}}}}}}
|
161
168
|
end
|
162
169
|
|
163
170
|
it "should consider array types as different from scalar types" do
|
164
|
-
|
171
|
+
a = examine <<-SQL
|
165
172
|
CREATE TABLE test_table (
|
166
173
|
a integer
|
167
174
|
);
|
168
175
|
SQL
|
169
176
|
|
170
|
-
|
177
|
+
b = examine <<-SQL
|
171
178
|
CREATE TABLE test_table (
|
172
179
|
a integer[]
|
173
180
|
)
|
174
181
|
SQL
|
175
182
|
|
176
|
-
|
183
|
+
a.should_not == b
|
184
|
+
|
185
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{"a"=>{:attndims=>{"0"=>"1"}, :type=>{"int4"=>"_int4"}}}}}}}}
|
177
186
|
end
|
178
187
|
|
179
188
|
it "should consider the presence of not-null constraints" do
|
180
|
-
|
189
|
+
a = examine <<-SQL
|
181
190
|
CREATE TABLE test_table (
|
182
191
|
a integer
|
183
192
|
);
|
184
193
|
SQL
|
185
194
|
|
186
|
-
|
195
|
+
b = examine <<-SQL
|
187
196
|
CREATE TABLE test_table (
|
188
197
|
a integer not null
|
189
198
|
)
|
190
199
|
SQL
|
191
200
|
|
192
|
-
|
201
|
+
a.should_not == b
|
202
|
+
|
203
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{"a"=>{:attnotnull=>{"f"=>"t"}}}}}}}}
|
193
204
|
end
|
194
205
|
|
195
206
|
it "should consider the presence of type-specific data" do
|
196
|
-
|
207
|
+
a = examine <<-SQL
|
197
208
|
CREATE TABLE test_table (
|
198
209
|
a varchar(49)
|
199
210
|
);
|
200
211
|
SQL
|
201
212
|
|
202
|
-
|
213
|
+
b = examine <<-SQL
|
203
214
|
CREATE TABLE test_table (
|
204
215
|
a varchar(50)
|
205
216
|
)
|
206
217
|
SQL
|
207
218
|
|
208
|
-
|
219
|
+
a.should_not == b
|
220
|
+
|
221
|
+
a.diff(b).should == {:schemas=>{"public"=>{:tables=>{"test_table"=>{:columns=>{"a"=>{:atttypmod=>{"53"=>"54"}}}}}}}}
|
209
222
|
end
|
210
223
|
|
211
224
|
it "should consider unlogged and temporary tables as different from permanent tables" do
|
212
|
-
|
225
|
+
a = examine <<-SQL
|
213
226
|
CREATE TABLE test_table (
|
214
227
|
a integer
|
215
228
|
);
|
216
229
|
SQL
|
217
230
|
|
218
|
-
|
231
|
+
b = examine <<-SQL
|
219
232
|
CREATE UNLOGGED TABLE test_table (
|
220
233
|
a integer
|
221
234
|
)
|
222
235
|
SQL
|
223
236
|
|
224
|
-
|
237
|
+
c = examine <<-SQL
|
225
238
|
CREATE TEMPORARY TABLE test_table (
|
226
239
|
a integer
|
227
240
|
)
|
228
241
|
SQL
|
229
242
|
|
230
|
-
|
231
|
-
|
232
|
-
|
243
|
+
a.should_not == b
|
244
|
+
a.should_not == c
|
245
|
+
b.should_not == c
|
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"]}}}}
|
233
250
|
end
|
234
251
|
|
235
252
|
it "should consider additional specified options when comparing tables" do
|
236
|
-
|
253
|
+
a = examine <<-SQL
|
237
254
|
CREATE TABLE test_table (
|
238
255
|
a integer
|
239
256
|
);
|
240
257
|
SQL
|
241
258
|
|
242
|
-
|
259
|
+
b = examine <<-SQL
|
243
260
|
CREATE TABLE test_table (
|
244
261
|
a integer
|
245
262
|
)
|
246
263
|
WITH (fillfactor=90);
|
247
264
|
SQL
|
248
265
|
|
249
|
-
|
266
|
+
c = examine <<-SQL
|
250
267
|
CREATE TABLE test_table (
|
251
268
|
a integer
|
252
269
|
)
|
253
270
|
WITH (fillfactor=70);
|
254
271
|
SQL
|
255
272
|
|
256
|
-
|
273
|
+
d = examine <<-SQL
|
257
274
|
CREATE TABLE test_table (
|
258
275
|
a integer
|
259
276
|
);
|
260
277
|
ALTER TABLE test_table SET (fillfactor=70);
|
261
278
|
SQL
|
262
279
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
280
|
+
a.should_not == b
|
281
|
+
a.should_not == c
|
282
|
+
b.should_not == c
|
283
|
+
c.should == d
|
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}"}}}}}}
|
267
288
|
end
|
268
289
|
end
|
metadata
CHANGED
@@ -1,69 +1,80 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: pg_examiner
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
|
-
authors:
|
6
|
+
authors:
|
7
7
|
- Chris Hanks
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
- !ruby/object:Gem::Dependency
|
11
|
+
date: 2015-12-04 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
15
14
|
name: bundler
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
version: "1.6"
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.6'
|
22
20
|
type: :development
|
23
|
-
version_requirements: *id001
|
24
|
-
- !ruby/object:Gem::Dependency
|
25
|
-
name: rake
|
26
21
|
prerelease: false
|
27
|
-
|
28
|
-
requirements:
|
29
|
-
-
|
30
|
-
-
|
31
|
-
|
32
|
-
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.6'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
33
34
|
type: :development
|
34
|
-
version_requirements: *id002
|
35
|
-
- !ruby/object:Gem::Dependency
|
36
|
-
name: pry
|
37
35
|
prerelease: false
|
38
|
-
|
39
|
-
requirements:
|
40
|
-
-
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: pry
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
41
48
|
type: :development
|
42
|
-
|
43
|
-
|
44
|
-
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: Examine and compare the tables, columns, constraints and other information
|
56
|
+
that makes up the schema of a PG database
|
57
|
+
email:
|
45
58
|
- christopher.m.hanks@gmail.com
|
46
59
|
executables: []
|
47
|
-
|
48
60
|
extensions: []
|
49
|
-
|
50
61
|
extra_rdoc_files: []
|
51
|
-
|
52
|
-
|
53
|
-
- .gitignore
|
62
|
+
files:
|
63
|
+
- ".gitignore"
|
54
64
|
- Gemfile
|
55
65
|
- LICENSE.txt
|
56
66
|
- README.md
|
57
67
|
- Rakefile
|
58
68
|
- TODO.txt
|
59
69
|
- lib/pg_examiner.rb
|
70
|
+
- lib/pg_examiner/base.rb
|
60
71
|
- lib/pg_examiner/result.rb
|
61
|
-
- lib/pg_examiner/result/base.rb
|
62
72
|
- lib/pg_examiner/result/column.rb
|
63
73
|
- lib/pg_examiner/result/constraint.rb
|
64
74
|
- lib/pg_examiner/result/extension.rb
|
65
75
|
- lib/pg_examiner/result/function.rb
|
66
76
|
- lib/pg_examiner/result/index.rb
|
77
|
+
- lib/pg_examiner/result/item.rb
|
67
78
|
- lib/pg_examiner/result/language.rb
|
68
79
|
- lib/pg_examiner/result/schema.rb
|
69
80
|
- lib/pg_examiner/result/table.rb
|
@@ -79,29 +90,30 @@ files:
|
|
79
90
|
- spec/spec_helper.rb
|
80
91
|
- spec/table_spec.rb
|
81
92
|
homepage: https://github.com/chanks/pg_examiner
|
82
|
-
licenses:
|
93
|
+
licenses:
|
83
94
|
- MIT
|
84
95
|
metadata: {}
|
85
|
-
|
86
96
|
post_install_message:
|
87
97
|
rdoc_options: []
|
88
|
-
|
89
|
-
require_paths:
|
98
|
+
require_paths:
|
90
99
|
- lib
|
91
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
92
|
-
requirements:
|
93
|
-
-
|
94
|
-
|
95
|
-
|
96
|
-
|
100
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: '0'
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
97
110
|
requirements: []
|
98
|
-
|
99
111
|
rubyforge_project:
|
100
|
-
rubygems_version: 2.
|
112
|
+
rubygems_version: 2.4.8
|
101
113
|
signing_key:
|
102
114
|
specification_version: 4
|
103
115
|
summary: Parse the schemas of Postgres databases in detail
|
104
|
-
test_files:
|
116
|
+
test_files:
|
105
117
|
- spec/constraint_spec.rb
|
106
118
|
- spec/extension_spec.rb
|
107
119
|
- spec/function_spec.rb
|