pg_examiner 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,164 @@
1
+ require 'spec_helper'
2
+
3
+ describe PGExaminer do
4
+ it "should consider indexes when determining equivalency" do
5
+ one = examine <<-SQL
6
+ CREATE TABLE test_table (
7
+ id integer
8
+ );
9
+
10
+ CREATE INDEX int_idx ON test_table(id);
11
+ SQL
12
+
13
+ two = examine <<-SQL
14
+ CREATE TABLE test_table (
15
+ id integer
16
+ );
17
+
18
+ CREATE INDEX int_idx ON test_table(id);
19
+ SQL
20
+
21
+ three = examine <<-SQL
22
+ CREATE TABLE test_table (
23
+ id integer
24
+ );
25
+
26
+ CREATE INDEX int_idx2 ON test_table(id);
27
+ SQL
28
+
29
+ one.should == two
30
+ one.should_not == three
31
+ two.should_not == three
32
+ end
33
+
34
+ it "should consider the columns indexes are on when determining equivalency" do
35
+ one = examine <<-SQL
36
+ CREATE TABLE test_table (
37
+ a integer,
38
+ b integer
39
+ );
40
+
41
+ CREATE INDEX int_idx ON test_table(a);
42
+ SQL
43
+
44
+ two = examine <<-SQL
45
+ CREATE TABLE test_table (
46
+ a integer,
47
+ b integer
48
+ );
49
+
50
+ CREATE INDEX int_idx ON test_table(b);
51
+ SQL
52
+
53
+ three = examine <<-SQL
54
+ CREATE TABLE test_table (
55
+ a integer,
56
+ b integer
57
+ );
58
+
59
+ CREATE INDEX int_idx ON test_table(a, b);
60
+ SQL
61
+
62
+ one.should_not == two
63
+ one.should_not == three
64
+ two.should_not == three
65
+ end
66
+
67
+ it "should consider the filters indexes have when determining equivalency" do
68
+ one = examine <<-SQL
69
+ CREATE TABLE test_table (
70
+ a integer
71
+ );
72
+
73
+ CREATE INDEX int_idx ON test_table(a) WHERE a > 0;
74
+ SQL
75
+
76
+ one.schemas.first.tables.first.indexes.first.row['filter'].should == '(a > 0)'
77
+
78
+ two = examine <<-SQL
79
+ CREATE TABLE test_table (
80
+ a integer
81
+ );
82
+
83
+ CREATE INDEX int_idx ON test_table(a) WHERE a > 0;
84
+ SQL
85
+
86
+ two.schemas.first.tables.first.indexes.first.row['filter'].should == '(a > 0)'
87
+
88
+ three = examine <<-SQL
89
+ CREATE TABLE test_table (
90
+ a integer
91
+ );
92
+
93
+ CREATE INDEX int_idx ON test_table(a);
94
+ SQL
95
+
96
+ one.should == two
97
+ one.should_not == three
98
+ two.should_not == three
99
+ end
100
+
101
+ it "should consider the expressions indexes are on, if any" do
102
+ one = examine <<-SQL
103
+ CREATE TABLE test_table (
104
+ a text
105
+ );
106
+
107
+ CREATE INDEX text_idx ON test_table(lower(a));
108
+ SQL
109
+
110
+ one.schemas.first.tables.first.indexes.first.expression.should == 'lower(a)'
111
+
112
+ two = examine <<-SQL
113
+ CREATE TABLE test_table (
114
+ a text
115
+ );
116
+
117
+ CREATE INDEX text_idx ON test_table(LOWER(a));
118
+ SQL
119
+
120
+ two.schemas.first.tables.first.indexes.first.expression.should == 'lower(a)'
121
+
122
+ three = examine <<-SQL
123
+ CREATE TABLE test_table (
124
+ a text
125
+ );
126
+
127
+ CREATE INDEX text_idx ON test_table(a);
128
+ SQL
129
+
130
+ one.should == two
131
+ one.should_not == three
132
+ two.should_not == three
133
+ end
134
+
135
+ it "should consider the uniqueness and primary key status of an index, if any" do
136
+ one = examine <<-SQL
137
+ CREATE TABLE test_table (
138
+ a integer
139
+ );
140
+
141
+ CREATE INDEX int_idx ON test_table(a);
142
+ SQL
143
+
144
+ two = examine <<-SQL
145
+ CREATE TABLE test_table (
146
+ a integer
147
+ );
148
+
149
+ CREATE UNIQUE INDEX int_idx ON test_table(a);
150
+ SQL
151
+
152
+ three = examine <<-SQL
153
+ CREATE TABLE test_table (
154
+ a integer
155
+ );
156
+
157
+ ALTER TABLE test_table ADD PRIMARY KEY (a);
158
+ SQL
159
+
160
+ one.should_not == two
161
+ one.should_not == three
162
+ two.should_not == three
163
+ end
164
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe PGExaminer do
4
+ it "should be able to examine the languages loaded into the db" do
5
+ result = examine("SELECT 1")
6
+ result.should be_an_instance_of PGExaminer::Result
7
+ result.languages.map(&:name).should == %w(c internal plpgsql sql) # Different for other installations?
8
+ end
9
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe PGExaminer do
4
+ it "should be able to examine the public schema" do
5
+ result = examine("SELECT 1")
6
+ result.should be_an_instance_of PGExaminer::Result
7
+
8
+ result.schemas.length.should == 1
9
+ schema = result.schemas.first
10
+ schema.should be_an_instance_of PGExaminer::Result::Schema
11
+ schema.name.should == 'public'
12
+ schema.tables.should == []
13
+ end
14
+
15
+ it "should detect other user-added schemas" do
16
+ result = examine <<-SQL
17
+ CREATE SCHEMA my_schema;
18
+ SQL
19
+
20
+ result.schemas.length.should == 2
21
+ result.schemas.map(&:name).should == %w(my_schema public)
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ require 'uri'
2
+ require 'pg'
3
+ require 'pry'
4
+ require 'pg_examiner'
5
+
6
+ uri = URI.parse(ENV['DATABASE_URL'] || 'postgres://postgres:@localhost/pg_examiner_test')
7
+ CONNECTION = PG::Connection.open :host => uri.host,
8
+ :user => uri.user,
9
+ :password => uri.password,
10
+ :port => uri.port || 5432,
11
+ :dbname => uri.path[1..-1]
12
+
13
+ RSpec.configure do |config|
14
+ def examine(sql)
15
+ execute "BEGIN"
16
+ execute(sql)
17
+ PGExaminer.examine(CONNECTION)
18
+ ensure
19
+ execute "ROLLBACK"
20
+ end
21
+
22
+ def execute(*args)
23
+ CONNECTION.async_exec(*args).to_a
24
+ end
25
+ end
@@ -0,0 +1,268 @@
1
+ require 'spec_helper'
2
+
3
+ describe PGExaminer do
4
+ it "should be able to tell when a table exists" do
5
+ result = examine <<-SQL
6
+ CREATE TABLE test_table (
7
+ id serial,
8
+ body text
9
+ )
10
+ SQL
11
+
12
+ result.should be_an_instance_of PGExaminer::Result
13
+ result.schemas.length.should == 1
14
+
15
+ schema = result.schemas.first
16
+ schema.should be_an_instance_of PGExaminer::Result::Schema
17
+ schema.name.should == 'public'
18
+ schema.tables.length.should == 1
19
+
20
+ table = schema.tables.first
21
+ table.should be_an_instance_of PGExaminer::Result::Table
22
+ table.columns.length.should == 2
23
+
24
+ id, body = table.columns # Returned in proper ordering
25
+
26
+ id.should be_an_instance_of PGExaminer::Result::Column
27
+ id.name.should == 'id'
28
+ id.type.should == 'int4'
29
+ id.default.should == "nextval('test_table_id_seq'::regclass)"
30
+
31
+ body.should be_an_instance_of PGExaminer::Result::Column
32
+ body.name.should == 'body'
33
+ body.type.should == 'text'
34
+ body.default.should == nil
35
+ end
36
+
37
+ it "should order tables by name" do
38
+ result = examine <<-SQL
39
+ CREATE TABLE table_a ();
40
+ CREATE TABLE table_b ();
41
+ SQL
42
+
43
+ result.should be_an_instance_of PGExaminer::Result
44
+ result.schemas.length.should == 1
45
+
46
+ schema = result.schemas.first
47
+ schema.should be_an_instance_of PGExaminer::Result::Schema
48
+ schema.name.should == 'public'
49
+ schema.tables.length.should == 2
50
+ schema.tables.map(&:name).should == %w(table_a table_b)
51
+ end
52
+
53
+ it "should consider equivalent tables equivalent" do
54
+ one = examine <<-SQL
55
+ CREATE TABLE test_table (
56
+ id serial,
57
+ body text
58
+ )
59
+ SQL
60
+
61
+ two = examine <<-SQL
62
+ CREATE TABLE test_table (
63
+ id serial,
64
+ body text
65
+ )
66
+ SQL
67
+
68
+ one.should == two
69
+ end
70
+
71
+ it "should consider differently-named tables non-equivalent" do
72
+ one = examine <<-SQL
73
+ CREATE TABLE test_table_a (
74
+ id serial,
75
+ body text
76
+ )
77
+ SQL
78
+
79
+ two = examine <<-SQL
80
+ CREATE TABLE test_table_b (
81
+ id serial,
82
+ body text
83
+ )
84
+ SQL
85
+
86
+ one.should_not == two
87
+ end
88
+
89
+ it "should consider tables with current columns in the same order equivalent" do
90
+ one = examine <<-SQL
91
+ CREATE TABLE test_table (
92
+ a integer,
93
+ b integer,
94
+ c integer
95
+ );
96
+
97
+ ALTER TABLE test_table DROP COLUMN b;
98
+ SQL
99
+
100
+ two = examine <<-SQL
101
+ CREATE TABLE test_table (
102
+ a integer,
103
+ c integer
104
+ );
105
+ SQL
106
+
107
+ three = examine <<-SQL
108
+ CREATE TABLE test_table (
109
+ a integer
110
+ );
111
+
112
+ ALTER TABLE test_table ADD COLUMN c integer;
113
+ SQL
114
+
115
+ one.should == two
116
+ one.should == three
117
+ two.should == three
118
+ end
119
+
120
+ it "should consider tables with columns in differing orders not equivalent" do
121
+ one = examine <<-SQL
122
+ CREATE TABLE test_table (
123
+ a integer,
124
+ b integer,
125
+ c integer
126
+ );
127
+ SQL
128
+
129
+ two = examine <<-SQL
130
+ CREATE TABLE test_table (
131
+ a integer,
132
+ c integer,
133
+ b integer
134
+ )
135
+ SQL
136
+
137
+ one.should_not == two
138
+ end
139
+
140
+ it "should consider tables with columns of differing types not equivalent" do
141
+ one = examine <<-SQL
142
+ CREATE TABLE test_table (
143
+ a integer
144
+ );
145
+ SQL
146
+
147
+ two = examine <<-SQL
148
+ CREATE TABLE test_table (
149
+ a text
150
+ )
151
+ SQL
152
+
153
+ three = examine <<-SQL
154
+ CREATE TABLE test_table (
155
+ a integer default 5
156
+ );
157
+ SQL
158
+
159
+ one.should_not == two
160
+ one.should_not == three
161
+ end
162
+
163
+ it "should consider array types as different from scalar types" do
164
+ one = examine <<-SQL
165
+ CREATE TABLE test_table (
166
+ a integer
167
+ );
168
+ SQL
169
+
170
+ two = examine <<-SQL
171
+ CREATE TABLE test_table (
172
+ a integer[]
173
+ )
174
+ SQL
175
+
176
+ one.should_not == two
177
+ end
178
+
179
+ it "should consider the presence of not-null constraints" do
180
+ one = examine <<-SQL
181
+ CREATE TABLE test_table (
182
+ a integer
183
+ );
184
+ SQL
185
+
186
+ two = examine <<-SQL
187
+ CREATE TABLE test_table (
188
+ a integer not null
189
+ )
190
+ SQL
191
+
192
+ one.should_not == two
193
+ end
194
+
195
+ it "should consider the presence of type-specific data" do
196
+ one = examine <<-SQL
197
+ CREATE TABLE test_table (
198
+ a varchar(49)
199
+ );
200
+ SQL
201
+
202
+ two = examine <<-SQL
203
+ CREATE TABLE test_table (
204
+ a varchar(50)
205
+ )
206
+ SQL
207
+
208
+ one.should_not == two
209
+ end
210
+
211
+ it "should consider unlogged and temporary tables as different from permanent tables" do
212
+ one = examine <<-SQL
213
+ CREATE TABLE test_table (
214
+ a integer
215
+ );
216
+ SQL
217
+
218
+ two = examine <<-SQL
219
+ CREATE UNLOGGED TABLE test_table (
220
+ a integer
221
+ )
222
+ SQL
223
+
224
+ three = examine <<-SQL
225
+ CREATE TEMPORARY TABLE test_table (
226
+ a integer
227
+ )
228
+ SQL
229
+
230
+ one.should_not == two
231
+ one.should_not == three
232
+ two.should_not == three
233
+ end
234
+
235
+ it "should consider additional specified options when comparing tables" do
236
+ one = examine <<-SQL
237
+ CREATE TABLE test_table (
238
+ a integer
239
+ );
240
+ SQL
241
+
242
+ two = examine <<-SQL
243
+ CREATE TABLE test_table (
244
+ a integer
245
+ )
246
+ WITH (fillfactor=90);
247
+ SQL
248
+
249
+ three = examine <<-SQL
250
+ CREATE TABLE test_table (
251
+ a integer
252
+ )
253
+ WITH (fillfactor=70);
254
+ SQL
255
+
256
+ four = examine <<-SQL
257
+ CREATE TABLE test_table (
258
+ a integer
259
+ );
260
+ ALTER TABLE test_table SET (fillfactor=70);
261
+ SQL
262
+
263
+ one.should_not == two
264
+ one.should_not == three
265
+ two.should_not == three
266
+ three.should == four
267
+ end
268
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pg_examiner
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Chris Hanks
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2014-06-13 00:00:00 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ prerelease: false
17
+ requirement: &id001 !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: "1.6"
22
+ type: :development
23
+ version_requirements: *id001
24
+ - !ruby/object:Gem::Dependency
25
+ name: rake
26
+ prerelease: false
27
+ requirement: &id002 !ruby/object:Gem::Requirement
28
+ requirements:
29
+ - &id003
30
+ - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id002
35
+ - !ruby/object:Gem::Dependency
36
+ name: pry
37
+ prerelease: false
38
+ requirement: &id004 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - *id003
41
+ type: :development
42
+ version_requirements: *id004
43
+ description: Examine and compare the tables, columns, constraints and other information that makes up the schema of a PG database
44
+ email:
45
+ - christopher.m.hanks@gmail.com
46
+ executables: []
47
+
48
+ extensions: []
49
+
50
+ extra_rdoc_files: []
51
+
52
+ files:
53
+ - .gitignore
54
+ - Gemfile
55
+ - LICENSE.txt
56
+ - README.md
57
+ - Rakefile
58
+ - TODO.txt
59
+ - lib/pg_examiner.rb
60
+ - lib/pg_examiner/result.rb
61
+ - lib/pg_examiner/result/base.rb
62
+ - lib/pg_examiner/result/column.rb
63
+ - lib/pg_examiner/result/constraint.rb
64
+ - lib/pg_examiner/result/extension.rb
65
+ - lib/pg_examiner/result/function.rb
66
+ - lib/pg_examiner/result/index.rb
67
+ - lib/pg_examiner/result/language.rb
68
+ - lib/pg_examiner/result/schema.rb
69
+ - lib/pg_examiner/result/table.rb
70
+ - lib/pg_examiner/result/trigger.rb
71
+ - lib/pg_examiner/version.rb
72
+ - pg_examiner.gemspec
73
+ - spec/constraint_spec.rb
74
+ - spec/extension_spec.rb
75
+ - spec/function_spec.rb
76
+ - spec/index_spec.rb
77
+ - spec/language_spec.rb
78
+ - spec/schema_spec.rb
79
+ - spec/spec_helper.rb
80
+ - spec/table_spec.rb
81
+ homepage: https://github.com/chanks/pg_examiner
82
+ licenses:
83
+ - MIT
84
+ metadata: {}
85
+
86
+ post_install_message:
87
+ rdoc_options: []
88
+
89
+ require_paths:
90
+ - lib
91
+ required_ruby_version: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - *id003
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - *id003
97
+ requirements: []
98
+
99
+ rubyforge_project:
100
+ rubygems_version: 2.2.2
101
+ signing_key:
102
+ specification_version: 4
103
+ summary: Parse the schemas of Postgres databases in detail
104
+ test_files:
105
+ - spec/constraint_spec.rb
106
+ - spec/extension_spec.rb
107
+ - spec/function_spec.rb
108
+ - spec/index_spec.rb
109
+ - spec/language_spec.rb
110
+ - spec/schema_spec.rb
111
+ - spec/spec_helper.rb
112
+ - spec/table_spec.rb