pg_examiner 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|