postgres_ext 0.1.0 → 0.2.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.
- data/.travis.yml +4 -0
- data/CHANGELOG.md +22 -0
- data/README.md +12 -240
- data/docs/indexes.md +19 -0
- data/docs/migrations.md +76 -0
- data/docs/querying.md +138 -0
- data/docs/type_casting.md +51 -0
- data/lib/postgres_ext/active_record/connection_adapters/postgres_adapter.rb +10 -4
- data/lib/postgres_ext/active_record/relation/predicate_builder.rb +71 -0
- data/lib/postgres_ext/active_record/relation/query_methods.rb +84 -0
- data/lib/postgres_ext/active_record/relation.rb +2 -0
- data/lib/postgres_ext/active_record.rb +1 -0
- data/lib/postgres_ext/arel/nodes/contained_within.rb +12 -0
- data/lib/postgres_ext/arel/predications.rb +12 -0
- data/lib/postgres_ext/arel/visitors/to_sql.rb +15 -0
- data/lib/postgres_ext/arel/visitors/visitor.rb +14 -8
- data/lib/postgres_ext/arel/visitors.rb +1 -0
- data/lib/postgres_ext/version.rb +1 -1
- data/postgres_ext.gemspec +2 -2
- data/spec/arel/inet_spec.rb +25 -2
- data/spec/columns/array_spec.rb +39 -0
- data/spec/dummy/db/migrate/20120501163758_create_people.rb +3 -5
- data/spec/dummy/db/schema.rb +11 -7
- data/spec/migrations/array_spec.rb +23 -7
- data/spec/migrations/citext_spec.rb +27 -0
- data/spec/queries/array_queries_spec.rb +57 -0
- data/spec/queries/contains_querie_spec.rb +36 -0
- data/spec/queries/sanity_spec.rb +23 -0
- data/spec/schema_dumper/citext_spec.rb +17 -0
- metadata +26 -8
@@ -2,11 +2,9 @@ class CreatePeople < ActiveRecord::Migration
|
|
2
2
|
def change
|
3
3
|
create_table :people do |t|
|
4
4
|
t.inet :ip
|
5
|
-
t.cidr :subnet
|
6
|
-
t.
|
7
|
-
t.
|
8
|
-
t.string :str_arrayzerd, :array => true, :limit => 5
|
9
|
-
t.string :test
|
5
|
+
t.cidr :subnet
|
6
|
+
t.inet :tag_ids, :array => true
|
7
|
+
t.string :tags, :array => true
|
10
8
|
|
11
9
|
t.timestamps
|
12
10
|
end
|
data/spec/dummy/db/schema.rb
CHANGED
@@ -14,17 +14,21 @@
|
|
14
14
|
ActiveRecord::Schema.define(:version => 20120501163758) do
|
15
15
|
|
16
16
|
add_extension "hstore"
|
17
|
+
add_extension "pg_trgm"
|
18
|
+
add_extension "citext"
|
17
19
|
|
18
20
|
create_table "people", :force => true do |t|
|
19
21
|
t.inet "ip"
|
20
22
|
t.cidr "subnet"
|
21
|
-
t.
|
22
|
-
t.
|
23
|
-
t.
|
24
|
-
t.
|
25
|
-
|
26
|
-
|
27
|
-
|
23
|
+
t.inet "tag_ids", :array => true
|
24
|
+
t.string "tags", :array => true
|
25
|
+
t.datetime "created_at", :null => false
|
26
|
+
t.datetime "updated_at", :null => false
|
27
|
+
end
|
28
|
+
|
29
|
+
create_table "sanity_tests", :force => true do |t|
|
30
|
+
t.string "tags", :array => true
|
31
|
+
t.integer "tag_ids", :array => true
|
28
32
|
end
|
29
33
|
|
30
34
|
end
|
@@ -34,16 +34,32 @@ describe 'Array migrations' do
|
|
34
34
|
before { connection.create_table :data_types }
|
35
35
|
after { connection.drop_table :data_types }
|
36
36
|
describe 'Add Column' do
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
context 'no default' do
|
38
|
+
it 'creates an array column' do
|
39
|
+
lambda do
|
40
|
+
connection.add_column :data_types, :array_5, :cidr, :array => true
|
41
|
+
end.should_not raise_exception
|
41
42
|
|
42
|
-
|
43
|
+
columns = connection.columns(:data_types)
|
43
44
|
|
44
|
-
|
45
|
-
|
45
|
+
array_5 = columns.detect { |c| c.name == 'array_5'}
|
46
|
+
array_5.sql_type.should eq 'cidr[]'
|
47
|
+
end
|
46
48
|
end
|
49
|
+
|
50
|
+
context 'with default' do
|
51
|
+
it 'creates an array column' do
|
52
|
+
lambda do
|
53
|
+
connection.add_column :data_types, :array_6, :integer, :array => true, :default => []
|
54
|
+
end.should_not raise_exception
|
55
|
+
|
56
|
+
columns = connection.columns(:data_types)
|
57
|
+
|
58
|
+
array_6 = columns.detect { |c| c.name == 'array_6'}
|
59
|
+
array_6.sql_type.should eq 'integer[]'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
47
63
|
end
|
48
64
|
|
49
65
|
describe 'Change table methods' do
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'CITEXT migrations' do
|
4
|
+
let!(:connection) { ActiveRecord::Base.connection }
|
5
|
+
before(:all) { ActiveRecord::Base.connection.add_extension('citext') if ActiveRecord::Base.connection.supports_extensions? }
|
6
|
+
after { connection.drop_table :data_types }
|
7
|
+
it 'creates an citext column' do
|
8
|
+
lambda do
|
9
|
+
connection.create_table :data_types do |t|
|
10
|
+
t.citext :citext_1
|
11
|
+
t.citext :citext_2, :citext_3
|
12
|
+
t.column :citext_4, :citext
|
13
|
+
end
|
14
|
+
end.should_not raise_exception
|
15
|
+
|
16
|
+
columns = connection.columns(:data_types)
|
17
|
+
citext_1 = columns.detect { |c| c.name == 'citext_1'}
|
18
|
+
citext_2 = columns.detect { |c| c.name == 'citext_2'}
|
19
|
+
citext_3 = columns.detect { |c| c.name == 'citext_3'}
|
20
|
+
citext_4 = columns.detect { |c| c.name == 'citext_4'}
|
21
|
+
|
22
|
+
citext_1.sql_type.should eq 'citext'
|
23
|
+
citext_2.sql_type.should eq 'citext'
|
24
|
+
citext_3.sql_type.should eq 'citext'
|
25
|
+
citext_4.sql_type.should eq 'citext'
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Array queries' do
|
4
|
+
let(:equality_regex) { %r{\"people\"\.\"tags\" = '\{\"working\"\}'} }
|
5
|
+
let(:overlap_regex) { %r{\"people\"\.\"tag_ids\" && '\{1,2\}'} }
|
6
|
+
let(:any_regex) { %r{2 = ANY\(\"people\"\.\"tag_ids\"\)} }
|
7
|
+
let(:all_regex) { %r{2 = ALL\(\"people\"\.\"tag_ids\"\)} }
|
8
|
+
|
9
|
+
describe '.where(:array_column => [])' do
|
10
|
+
it 'returns an array string instead of IN ()' do
|
11
|
+
query = Person.where(:tags => ['working']).to_sql
|
12
|
+
query.should match equality_regex
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.where.overlap(:column => value)' do
|
17
|
+
it 'generates the appropriate where clause' do
|
18
|
+
query = Person.where.overlap(:tag_ids => [1,2])
|
19
|
+
query.to_sql.should match overlap_regex
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'allows chaining' do
|
23
|
+
query = Person.where.overlap(:tag_ids => [1,2]).where(:tags => ['working']).to_sql
|
24
|
+
|
25
|
+
query.should match overlap_regex
|
26
|
+
query.should match equality_regex
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '.where.any(:column => value)' do
|
31
|
+
it 'generates the appropriate where clause' do
|
32
|
+
query = Person.where.any(:tag_ids => 2)
|
33
|
+
query.to_sql.should match any_regex
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'allows chaining' do
|
37
|
+
query = Person.where.any(:tag_ids => 2).where(:tags => ['working']).to_sql
|
38
|
+
|
39
|
+
query.should match any_regex
|
40
|
+
query.should match equality_regex
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe '.where.all(:column => value)' do
|
45
|
+
it 'generates the appropriate where clause' do
|
46
|
+
query = Person.where.all(:tag_ids => 2)
|
47
|
+
query.to_sql.should match all_regex
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'allows chaining' do
|
51
|
+
query = Person.where.all(:tag_ids => 2).where(:tags => ['working']).to_sql
|
52
|
+
|
53
|
+
query.should match all_regex
|
54
|
+
query.should match equality_regex
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Contains queries' do
|
4
|
+
let(:contained_within_regex) { %r{\"people\"\.\"ip\" << '127.0.0.1/24'} }
|
5
|
+
let(:contained_within_equals_regex) { %r{\"people\"\.\"ip\" <<= '127.0.0.1/24'} }
|
6
|
+
let(:contains_regex) { %r{\"people\"\.\"ip\" >> '127.0.0.1'} }
|
7
|
+
let(:contains_equals_regex) { %r{\"people\"\.\"ip\" >>= '127.0.0.1'} }
|
8
|
+
|
9
|
+
describe '.where.contained_within(:column, value)' do
|
10
|
+
it 'generates the appropriate where clause' do
|
11
|
+
query = Person.where.contained_within(:ip => '127.0.0.1/24')
|
12
|
+
query.to_sql.should match contained_within_regex
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.where.contained_within_or_equals(:column, value)' do
|
17
|
+
it 'generates the appropriate where clause' do
|
18
|
+
query = Person.where.contained_within_or_equals(:ip => '127.0.0.1/24')
|
19
|
+
query.to_sql.should match contained_within_equals_regex
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '.where.contains(:column, value)' do
|
24
|
+
it 'generates the appropriate where clause' do
|
25
|
+
query = Person.where.contains(:ip => '127.0.0.1')
|
26
|
+
query.to_sql.should match contains_regex
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '.where.contained_within_or_equals(:column, value)' do
|
31
|
+
it 'generates the appropriate where clause' do
|
32
|
+
query = Person.where.contains_or_equals(:ip => '127.0.0.1')
|
33
|
+
query.to_sql.should match contains_equals_regex
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Ensure that we don\'t stomp on Active Record\'s queries' do
|
4
|
+
let!(:adapter) { ActiveRecord::Base.connection }
|
5
|
+
|
6
|
+
before do
|
7
|
+
adapter.create_table :sanity_tests, :force => true do |t|
|
8
|
+
t.string :tags, :array => true
|
9
|
+
t.integer :tag_ids, :array => true
|
10
|
+
end
|
11
|
+
|
12
|
+
class SanityTest < ActiveRecord::Base
|
13
|
+
attr_accessible :tags, :tags_ids
|
14
|
+
end
|
15
|
+
end
|
16
|
+
describe '.where' do
|
17
|
+
it 'generates IN clauses for non array columns' do
|
18
|
+
query = SanityTest.where(:id => [1,2,3]).to_sql
|
19
|
+
|
20
|
+
query.should match /IN \(1, 2, 3\)/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'CITEXT schema dump' do
|
4
|
+
let!(:connection) { ActiveRecord::Base.connection }
|
5
|
+
after { connection.drop_table :testings }
|
6
|
+
it 'correctly generates citext column statements' do
|
7
|
+
stream = StringIO.new
|
8
|
+
connection.create_table :testings do |t|
|
9
|
+
t.citext :citext_column
|
10
|
+
end
|
11
|
+
|
12
|
+
ActiveRecord::SchemaDumper.dump(connection, stream)
|
13
|
+
output = stream.string
|
14
|
+
|
15
|
+
output.should match /t\.citext/
|
16
|
+
end
|
17
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postgres_ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2013-02-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -66,7 +66,7 @@ dependencies:
|
|
66
66
|
requirements:
|
67
67
|
- - ~>
|
68
68
|
- !ruby/object:Gem::Version
|
69
|
-
version: 2.
|
69
|
+
version: 2.12.0
|
70
70
|
type: :development
|
71
71
|
prerelease: false
|
72
72
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -74,7 +74,7 @@ dependencies:
|
|
74
74
|
requirements:
|
75
75
|
- - ~>
|
76
76
|
- !ruby/object:Gem::Version
|
77
|
-
version: 2.
|
77
|
+
version: 2.12.0
|
78
78
|
- !ruby/object:Gem::Dependency
|
79
79
|
name: bourne
|
80
80
|
requirement: !ruby/object:Gem::Requirement
|
@@ -82,7 +82,7 @@ dependencies:
|
|
82
82
|
requirements:
|
83
83
|
- - ~>
|
84
84
|
- !ruby/object:Gem::Version
|
85
|
-
version: 1.
|
85
|
+
version: 1.3.0
|
86
86
|
type: :development
|
87
87
|
prerelease: false
|
88
88
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -90,7 +90,7 @@ dependencies:
|
|
90
90
|
requirements:
|
91
91
|
- - ~>
|
92
92
|
- !ruby/object:Gem::Version
|
93
|
-
version: 1.
|
93
|
+
version: 1.3.0
|
94
94
|
- !ruby/object:Gem::Dependency
|
95
95
|
name: pg
|
96
96
|
requirement: !ruby/object:Gem::Requirement
|
@@ -123,10 +123,17 @@ files:
|
|
123
123
|
- LICENSE
|
124
124
|
- README.md
|
125
125
|
- Rakefile
|
126
|
+
- docs/indexes.md
|
127
|
+
- docs/migrations.md
|
128
|
+
- docs/querying.md
|
129
|
+
- docs/type_casting.md
|
126
130
|
- lib/postgres_ext.rb
|
127
131
|
- lib/postgres_ext/active_record.rb
|
128
132
|
- lib/postgres_ext/active_record/connection_adapters.rb
|
129
133
|
- lib/postgres_ext/active_record/connection_adapters/postgres_adapter.rb
|
134
|
+
- lib/postgres_ext/active_record/relation.rb
|
135
|
+
- lib/postgres_ext/active_record/relation/predicate_builder.rb
|
136
|
+
- lib/postgres_ext/active_record/relation/query_methods.rb
|
130
137
|
- lib/postgres_ext/active_record/sanitization.rb
|
131
138
|
- lib/postgres_ext/active_record/schema_dumper.rb
|
132
139
|
- lib/postgres_ext/arel.rb
|
@@ -134,6 +141,7 @@ files:
|
|
134
141
|
- lib/postgres_ext/arel/nodes/contained_within.rb
|
135
142
|
- lib/postgres_ext/arel/predications.rb
|
136
143
|
- lib/postgres_ext/arel/visitors.rb
|
144
|
+
- lib/postgres_ext/arel/visitors/to_sql.rb
|
137
145
|
- lib/postgres_ext/arel/visitors/visitor.rb
|
138
146
|
- lib/postgres_ext/version.rb
|
139
147
|
- postgres_ext.gemspec
|
@@ -196,14 +204,19 @@ files:
|
|
196
204
|
- spec/migrations/active_record_migration_spec.rb
|
197
205
|
- spec/migrations/array_spec.rb
|
198
206
|
- spec/migrations/cidr_spec.rb
|
207
|
+
- spec/migrations/citext_spec.rb
|
199
208
|
- spec/migrations/index_spec.rb
|
200
209
|
- spec/migrations/inet_spec.rb
|
201
210
|
- spec/migrations/macaddr_spec.rb
|
202
211
|
- spec/migrations/uuid_spec.rb
|
203
212
|
- spec/models/array_spec.rb
|
204
213
|
- spec/models/inet_spec.rb
|
214
|
+
- spec/queries/array_queries_spec.rb
|
215
|
+
- spec/queries/contains_querie_spec.rb
|
216
|
+
- spec/queries/sanity_spec.rb
|
205
217
|
- spec/schema_dumper/array_spec.rb
|
206
218
|
- spec/schema_dumper/cidr_spec.rb
|
219
|
+
- spec/schema_dumper/citext_spec.rb
|
207
220
|
- spec/schema_dumper/extension_spec.rb
|
208
221
|
- spec/schema_dumper/index_spec.rb
|
209
222
|
- spec/schema_dumper/inet_spec.rb
|
@@ -224,7 +237,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
224
237
|
version: '0'
|
225
238
|
segments:
|
226
239
|
- 0
|
227
|
-
hash: -
|
240
|
+
hash: -3214971167706041644
|
228
241
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
229
242
|
none: false
|
230
243
|
requirements:
|
@@ -233,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
233
246
|
version: '0'
|
234
247
|
segments:
|
235
248
|
- 0
|
236
|
-
hash: -
|
249
|
+
hash: -3214971167706041644
|
237
250
|
requirements: []
|
238
251
|
rubyforge_project:
|
239
252
|
rubygems_version: 1.8.23
|
@@ -300,14 +313,19 @@ test_files:
|
|
300
313
|
- spec/migrations/active_record_migration_spec.rb
|
301
314
|
- spec/migrations/array_spec.rb
|
302
315
|
- spec/migrations/cidr_spec.rb
|
316
|
+
- spec/migrations/citext_spec.rb
|
303
317
|
- spec/migrations/index_spec.rb
|
304
318
|
- spec/migrations/inet_spec.rb
|
305
319
|
- spec/migrations/macaddr_spec.rb
|
306
320
|
- spec/migrations/uuid_spec.rb
|
307
321
|
- spec/models/array_spec.rb
|
308
322
|
- spec/models/inet_spec.rb
|
323
|
+
- spec/queries/array_queries_spec.rb
|
324
|
+
- spec/queries/contains_querie_spec.rb
|
325
|
+
- spec/queries/sanity_spec.rb
|
309
326
|
- spec/schema_dumper/array_spec.rb
|
310
327
|
- spec/schema_dumper/cidr_spec.rb
|
328
|
+
- spec/schema_dumper/citext_spec.rb
|
311
329
|
- spec/schema_dumper/extension_spec.rb
|
312
330
|
- spec/schema_dumper/index_spec.rb
|
313
331
|
- spec/schema_dumper/inet_spec.rb
|