pg_examiner 0.1.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.
@@ -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