postgres_ext 2.2.0 → 2.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 +4 -4
- data/.gitignore +3 -0
- data/.travis.yml +6 -6
- data/CHANGELOG.md +22 -13
- data/README.md +8 -4
- data/Rakefile +14 -0
- data/docs/querying.md +1 -1
- data/gemfiles/Gemfile.activerecord-4.0.x +9 -0
- data/gemfiles/Gemfile.activerecord-4.1.x +9 -0
- data/lib/postgres_ext/active_record/cte_proxy.rb +21 -1
- data/lib/postgres_ext/active_record/relation/predicate_builder.rb +1 -1
- data/lib/postgres_ext/active_record/relation/query_methods.rb +1 -1
- data/lib/postgres_ext/arel/visitors/visitor.rb +1 -1
- data/lib/postgres_ext/version.rb +1 -1
- data/postgres_ext.gemspec +3 -3
- data/test/queries/array_queries_test.rb +0 -14
- data/test/queries/common_table_expression_test.rb +12 -6
- data/test/queries/contains_test.rb +28 -8
- data/test/queries/sanity_test.rb +8 -0
- data/test/test_helper.rb +8 -2
- metadata +9 -8
- data/.rspec +0 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f8878d742f2c1d692cca006bbd3fe55dfb69e1d
|
4
|
+
data.tar.gz: 64ae985d2dae1389ee05b0c843b2ad8d578d1ffc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1a8cd94d52fce6e7dbf5472899b1a1f45b9328fbf31e42a912c4ec4cf10880d2e398f0f954bf9ab49fea5e503c11a660f6ee89fbf690162e2bf3c96d64a338bc
|
7
|
+
data.tar.gz: 66a9c9c002c548b0920657f243c6c23ea04a4468666b3799f5bc52ea76b25d0f47f2e84ec8071e2f818638f6af12e804223994e515456540b1eab9f38cbadcab
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
@@ -1,19 +1,19 @@
|
|
1
1
|
rvm:
|
2
|
-
- 1.9.3
|
3
2
|
- 2.0.0
|
4
|
-
-
|
3
|
+
- 2.1.2
|
4
|
+
|
5
|
+
gemfile:
|
6
|
+
- gemfiles/Gemfile.activerecord-4.0.x
|
7
|
+
- gemfiles/Gemfile.activerecord-4.1.x
|
5
8
|
|
6
9
|
env: DATABASE_URL=postgres://postgres@localhost/postgres_ext_test
|
7
10
|
|
8
11
|
before_script:
|
9
12
|
- psql -c 'create database postgres_ext_test;' -U postgres -h localhost
|
10
|
-
- rake db:migrate
|
13
|
+
- bundle exec rake db:migrate
|
11
14
|
|
12
15
|
notifications:
|
13
16
|
email:
|
14
17
|
- git@danmcclain.net
|
15
|
-
hipchat:
|
16
|
-
rooms:
|
17
|
-
secure: gebjx8Q/jmnNmf6l+SyQHHJjGn9RfA6s4e8sIoRBVt9pomkOCBvHq7++AjpVlqkXcvV6rK2L90rAEPKMP0QUS04vRtRY6LvwmjiQHFo99/gktG6LO+5/QGvy9zbK4PxWe35Yr1F98Gs0mQ+y/ZbU6u8rJsI7DM1iPq2ULzo/QUw=
|
18
18
|
addons:
|
19
19
|
postgresql: '9.3'
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
## 2.3.0
|
2
|
+
|
3
|
+
* Fixes an issue with `where(table: { column: [] })` was not properly
|
4
|
+
converting the where clause to an equality instead of an `IN`
|
5
|
+
predicate (#111) - Dan McClain
|
6
|
+
* Adds support for Rails 4.1 - Dan McClain
|
7
|
+
* Adds support for hstore columns when using `contains` (#120) - Dan McClain
|
8
|
+
* Quotes CTE names (#130) - Dan McClain
|
9
|
+
|
1
10
|
## 2.2.0
|
2
11
|
|
3
12
|
* Adds Arel predications for `ANY` and `ALL` - Dan McClain
|
@@ -6,37 +15,37 @@
|
|
6
15
|
* Relation.with now accepts Arel::SelectMangers - Dan McClain
|
7
16
|
|
8
17
|
## 2.1.3
|
9
|
-
|
18
|
+
|
10
19
|
* Fixes Arel 4.0.1 issues - Dan McClain
|
11
20
|
* Prevents coversion of string to order statement - Dan McClain
|
12
|
-
|
21
|
+
|
13
22
|
## 2.1.2
|
14
23
|
|
15
24
|
* Fixes calls to count when ranking a relation - Dan McClain
|
16
|
-
|
25
|
+
|
17
26
|
## 2.1.1
|
18
|
-
|
27
|
+
|
19
28
|
* Fixes cte proxy so that it can create records - Dan McClain
|
20
|
-
|
29
|
+
|
21
30
|
## 2.1.0
|
22
|
-
|
31
|
+
|
23
32
|
* Support added for common table expressions - Dan McClain
|
24
33
|
* Support added for rank windowing function - Dan McClain
|
25
34
|
* Insert Code Climate badge into README - Doug Yun
|
26
|
-
|
35
|
+
|
27
36
|
# 2.0.0
|
28
|
-
|
37
|
+
|
29
38
|
* JRuby fixes - Dan McClain
|
30
39
|
* Updates docs and description - Dan McClain
|
31
40
|
* Rails 4 support - Dan McClain
|
32
|
-
|
41
|
+
|
33
42
|
# 1.0.0
|
34
|
-
|
43
|
+
|
35
44
|
1.0.0 is the last major and minor release for Rails 3.2.x. Postgres\_ext
|
36
45
|
will only receive bug fixes in the future. Also, bug fixes for 1.0.x
|
37
46
|
will come from PRs only, future development efforts are concentrated on
|
38
47
|
2.x.
|
39
|
-
|
48
|
+
|
40
49
|
* Fixing array tests in jruby - Dan McClain
|
41
50
|
* Removes encoding patches from PostgreSQLAdapter - Dan McClain
|
42
51
|
* Update documentation to reflect changes in 0.3.0 - Fabian Schwahn
|
@@ -129,7 +138,7 @@ encoded strings - Michael Graff (@skandragon)
|
|
129
138
|
|
130
139
|
## 0.0.8
|
131
140
|
|
132
|
-
Fixes add and change column
|
141
|
+
Fixes add and change column
|
133
142
|
|
134
143
|
## 0.0.7
|
135
144
|
|
@@ -143,5 +152,5 @@ Lots of array related fixes:
|
|
143
152
|
array column
|
144
153
|
* Array columns follow database defaults
|
145
154
|
|
146
|
-
Migration fix (rn0 and gilltots)
|
155
|
+
Migration fix (rn0 and gilltots)
|
147
156
|
Typos in README (bcardarella)
|
data/README.md
CHANGED
@@ -44,13 +44,17 @@ be adding more datatypes as we come across them.
|
|
44
44
|
|
45
45
|
To work on postgres\_ext locally, follow these steps:
|
46
46
|
|
47
|
-
1. Run `bundle install`, this will install all the development
|
47
|
+
1. Run `bundle install`, this will install (almost) all the development
|
48
48
|
dependencies
|
49
|
-
2. Run `
|
49
|
+
2. Run `gem install byebug` (not a declared dependency to not break CI)
|
50
|
+
3. Run `bundle exec rake setup`, this will set up the `.env` file necessary to run
|
50
51
|
the tests and set up the database
|
51
|
-
|
52
|
-
|
52
|
+
4. Run `bundle exec rake db:create`, this will create the test database
|
53
|
+
5. Run `bundle exec rake db:migrate`, this will set up the database tables required
|
53
54
|
by the test
|
55
|
+
6. Run `BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-4.0.x' bundle install --quiet` to create the Gemfile.lock for 4.0.
|
56
|
+
7. Run `BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-4.1.x' bundle install --quiet` to create the Gemfile.lock for 4.1.
|
57
|
+
8. Run `bundle exec rake test:all` to run tests against all supported versions of Active Record
|
54
58
|
|
55
59
|
## Authors
|
56
60
|
|
data/Rakefile
CHANGED
@@ -34,6 +34,17 @@ end
|
|
34
34
|
|
35
35
|
task :default => :test
|
36
36
|
|
37
|
+
namespace :test do
|
38
|
+
desc 'Test against all supported ActiveRecord versions'
|
39
|
+
task :all do
|
40
|
+
# Currently only supports Active Record v4.0
|
41
|
+
%w(4.0.x 4.1.x).each do |version|
|
42
|
+
sh "BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-#{version}' bundle install --quiet"
|
43
|
+
sh "BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-#{version}' bundle exec rake test"
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
37
48
|
task :setup do
|
38
49
|
if File.exist?('.env')
|
39
50
|
puts 'This will overwrite your existing .env file'
|
@@ -82,11 +93,14 @@ namespace :db do
|
|
82
93
|
task :migrate => :load_db_settings do
|
83
94
|
ActiveRecord::Base.establish_connection
|
84
95
|
|
96
|
+
ActiveRecord::Base.connection.enable_extension 'hstore'
|
97
|
+
|
85
98
|
ActiveRecord::Base.connection.create_table :people, force: true do |t|
|
86
99
|
t.inet "ip"
|
87
100
|
t.cidr "subnet"
|
88
101
|
t.integer "tag_ids", array: true
|
89
102
|
t.string "tags", array: true
|
103
|
+
t.hstore "data"
|
90
104
|
t.integer "lucky_number"
|
91
105
|
t.datetime "created_at"
|
92
106
|
t.datetime "updated_at"
|
data/docs/querying.md
CHANGED
@@ -12,7 +12,7 @@ We can add CTEs to queries by chaining `#with` off a relation.
|
|
12
12
|
`Relation#with` accepts a hash, and will convert `Relation`s to the
|
13
13
|
proper SQL in the CTE.
|
14
14
|
|
15
|
-
Let's expand a `#with` call to
|
15
|
+
Let's expand a `#with` call to its resulting SQL code:
|
16
16
|
|
17
17
|
```ruby
|
18
18
|
Score.with(my_games: Game.where(id: 1)).joins('JOIN my_games ON scores.game_id = my_games.id')
|
@@ -11,7 +11,7 @@ class CTEProxy
|
|
11
11
|
@arel_table = Arel::Table.new(name)
|
12
12
|
@model = model
|
13
13
|
@connection = model.connection
|
14
|
-
@
|
14
|
+
@_reflections = {}
|
15
15
|
end
|
16
16
|
|
17
17
|
def name
|
@@ -30,11 +30,31 @@ class CTEProxy
|
|
30
30
|
@model.columns_hash
|
31
31
|
end
|
32
32
|
|
33
|
+
def model_name
|
34
|
+
@model.model_name
|
35
|
+
end
|
36
|
+
|
33
37
|
def primary_key
|
34
38
|
@model.primary_key
|
35
39
|
end
|
36
40
|
|
41
|
+
def attribute_alias?(*args)
|
42
|
+
@model.attribute_alias?(*args)
|
43
|
+
end
|
44
|
+
|
45
|
+
def aggregate_reflections(*args)
|
46
|
+
@model.aggregate_reflections(*args)
|
47
|
+
end
|
48
|
+
|
37
49
|
def instantiate(record, column_types = {})
|
38
50
|
@model.instantiate(record, column_types)
|
39
51
|
end
|
52
|
+
|
53
|
+
private
|
54
|
+
|
55
|
+
def reflections
|
56
|
+
@_reflections
|
57
|
+
end
|
58
|
+
|
59
|
+
alias _reflections reflections
|
40
60
|
end
|
@@ -8,7 +8,7 @@ module ActiveRecord
|
|
8
8
|
case value
|
9
9
|
when Array
|
10
10
|
engine = attribute.relation.engine
|
11
|
-
column = engine.columns.detect{ |col| col.name.to_s == attribute.name.to_s }
|
11
|
+
column = engine.connection.columns(attribute.relation.name).detect{ |col| col.name.to_s == attribute.name.to_s }
|
12
12
|
if column && column.array
|
13
13
|
attribute.eq(value)
|
14
14
|
else
|
@@ -162,7 +162,7 @@ module ActiveRecord
|
|
162
162
|
when Arel::SelectManager
|
163
163
|
select = Arel::SqlLiteral.new visitor.accept(expression)
|
164
164
|
end
|
165
|
-
as = Arel::Nodes::As.new Arel::SqlLiteral.new(name.to_s), select
|
165
|
+
as = Arel::Nodes::As.new Arel::SqlLiteral.new("\"#{name.to_s}\""), select
|
166
166
|
end
|
167
167
|
end
|
168
168
|
end
|
@@ -15,7 +15,7 @@ module Arel
|
|
15
15
|
def visit_Arel_Nodes_Contains o, a = nil
|
16
16
|
left_column = o.left.relation.engine.columns.find { |col| col.name == o.left.name.to_s }
|
17
17
|
|
18
|
-
if left_column && left_column.respond_to?(:array) && left_column.array
|
18
|
+
if left_column && (left_column.type == :hstore || (left_column.respond_to?(:array) && left_column.array))
|
19
19
|
"#{visit o.left, a} @> #{visit o.right, o.left}"
|
20
20
|
else
|
21
21
|
"#{visit o.left, a} >> #{visit o.right, o.left}"
|
data/lib/postgres_ext/version.rb
CHANGED
data/postgres_ext.gemspec
CHANGED
@@ -6,7 +6,7 @@ Gem::Specification.new do |gem|
|
|
6
6
|
gem.email = ["git@danmcclain.net"]
|
7
7
|
gem.description = %q{Adds missing native PostgreSQL data types to ActiveRecord and convenient querying extensions for ActiveRecord and Arel}
|
8
8
|
gem.summary = %q{Extends ActiveRecord to handle native PostgreSQL data types}
|
9
|
-
gem.homepage =
|
9
|
+
gem.homepage = 'https://github.com/dockyard/postgres_ext'
|
10
10
|
gem.licenses = ['MIT']
|
11
11
|
|
12
12
|
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
@@ -16,8 +16,8 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.require_paths = ["lib"]
|
17
17
|
gem.version = PostgresExt::VERSION
|
18
18
|
|
19
|
-
gem.add_dependency 'activerecord', '
|
20
|
-
gem.add_dependency 'arel', '
|
19
|
+
gem.add_dependency 'activerecord', '>= 4.0.0'
|
20
|
+
gem.add_dependency 'arel', '>= 4.0.1'
|
21
21
|
gem.add_dependency 'pg_array_parser', '~> 0.0.9'
|
22
22
|
|
23
23
|
gem.add_development_dependency 'rake', '~> 10.1.0'
|
@@ -3,7 +3,6 @@ require 'test_helper'
|
|
3
3
|
describe 'Array queries' do
|
4
4
|
let(:equality_regex) { %r{\"people\"\.\"tags\" = '\{\"working\"\}'} }
|
5
5
|
let(:overlap_regex) { %r{\"people\"\.\"tag_ids\" && '\{1,2\}'} }
|
6
|
-
let(:contains_regex) { %r{\"people\"\.\"tag_ids\" @> '\{1,2\}'} }
|
7
6
|
let(:any_regex) { %r{2 = ANY\(\"people\"\.\"tag_ids\"\)} }
|
8
7
|
let(:all_regex) { %r{2 = ALL\(\"people\"\.\"tag_ids\"\)} }
|
9
8
|
|
@@ -36,19 +35,6 @@ describe 'Array queries' do
|
|
36
35
|
end
|
37
36
|
end
|
38
37
|
|
39
|
-
describe '.where.contains(:column => value)' do
|
40
|
-
it 'generates the appropriate where clause' do
|
41
|
-
query = Person.where.contains(:tag_ids => [1,2])
|
42
|
-
query.to_sql.must_match contains_regex
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'allows chaining' do
|
46
|
-
query = Person.where.contains(:tag_ids => [1,2]).where(:tags => ['working']).to_sql
|
47
|
-
|
48
|
-
query.must_match contains_regex
|
49
|
-
query.must_match equality_regex
|
50
|
-
end
|
51
|
-
end
|
52
38
|
|
53
39
|
describe '.where.any(:column => value)' do
|
54
40
|
it 'generates the appropriate where clause' do
|
@@ -4,22 +4,22 @@ describe 'Common Table Expression queries' do
|
|
4
4
|
describe '.with(common_table_expression_hash)' do
|
5
5
|
it 'generates an expression with the CTE' do
|
6
6
|
query = Person.with(lucky_number_seven: Person.where(lucky_number: 7)).joins('JOIN lucky_number_seven ON lucky_number_seven.id = people.id')
|
7
|
-
query.to_sql.must_equal 'WITH lucky_number_seven AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 7) SELECT "people".* FROM "people" JOIN lucky_number_seven ON lucky_number_seven.id = people.id'
|
7
|
+
query.to_sql.must_equal 'WITH "lucky_number_seven" AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 7) SELECT "people".* FROM "people" JOIN lucky_number_seven ON lucky_number_seven.id = people.id'
|
8
8
|
end
|
9
9
|
|
10
10
|
it 'generates an expression with multiple CTEs' do
|
11
11
|
query = Person.with(lucky_number_seven: Person.where(lucky_number: 7), lucky_number_three: Person.where(lucky_number: 3)).joins('JOIN lucky_number_seven ON lucky_number_seven.id = people.id').joins('JOIN lucky_number_three ON lucky_number_three.id = people.id')
|
12
|
-
query.to_sql.must_equal 'WITH lucky_number_seven AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 7), lucky_number_three AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 3) SELECT "people".* FROM "people" JOIN lucky_number_seven ON lucky_number_seven.id = people.id JOIN lucky_number_three ON lucky_number_three.id = people.id'
|
12
|
+
query.to_sql.must_equal 'WITH "lucky_number_seven" AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 7), "lucky_number_three" AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 3) SELECT "people".* FROM "people" JOIN lucky_number_seven ON lucky_number_seven.id = people.id JOIN lucky_number_three ON lucky_number_three.id = people.id'
|
13
13
|
end
|
14
14
|
|
15
15
|
it 'generates an expression with multiple with calls' do
|
16
16
|
query = Person.with(lucky_number_seven: Person.where(lucky_number: 7)).with(lucky_number_three: Person.where(lucky_number: 3)).joins('JOIN lucky_number_seven ON lucky_number_seven.id = people.id').joins('JOIN lucky_number_three ON lucky_number_three.id = people.id')
|
17
|
-
query.to_sql.must_equal 'WITH lucky_number_seven AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 7), lucky_number_three AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 3) SELECT "people".* FROM "people" JOIN lucky_number_seven ON lucky_number_seven.id = people.id JOIN lucky_number_three ON lucky_number_three.id = people.id'
|
17
|
+
query.to_sql.must_equal 'WITH "lucky_number_seven" AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 7), "lucky_number_three" AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 3) SELECT "people".* FROM "people" JOIN lucky_number_seven ON lucky_number_seven.id = people.id JOIN lucky_number_three ON lucky_number_three.id = people.id'
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'generates an expression with recursive' do
|
21
21
|
query = Person.with.recursive(lucky_number_seven: Person.where(lucky_number: 7)).joins('JOIN lucky_number_seven ON lucky_number_seven.id = people.id')
|
22
|
-
query.to_sql.must_equal 'WITH RECURSIVE lucky_number_seven AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 7) SELECT "people".* FROM "people" JOIN lucky_number_seven ON lucky_number_seven.id = people.id'
|
22
|
+
query.to_sql.must_equal 'WITH RECURSIVE "lucky_number_seven" AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 7) SELECT "people".* FROM "people" JOIN lucky_number_seven ON lucky_number_seven.id = people.id'
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'accepts Arel::SelectMangers' do
|
@@ -27,14 +27,14 @@ describe 'Common Table Expression queries' do
|
|
27
27
|
arel_manager = arel_table.project arel_table[:foo]
|
28
28
|
|
29
29
|
query = Person.with(testing: arel_manager)
|
30
|
-
query.to_sql.must_equal 'WITH testing AS (SELECT "test"."foo" FROM "test") SELECT "people".* FROM "people"'
|
30
|
+
query.to_sql.must_equal 'WITH "testing" AS (SELECT "test"."foo" FROM "test") SELECT "people".* FROM "people"'
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
34
|
describe '.from_cte(common_table_expression_hash)' do
|
35
35
|
it 'generates an expression with the CTE as the main table' do
|
36
36
|
query = Person.from_cte('lucky_number_seven', Person.where(lucky_number: 7)).where(id: 5)
|
37
|
-
query.to_sql.must_equal 'WITH lucky_number_seven AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 7) SELECT "lucky_number_seven".* FROM "lucky_number_seven" WHERE "lucky_number_seven"."id" = 5'
|
37
|
+
query.to_sql.must_equal 'WITH "lucky_number_seven" AS (SELECT "people".* FROM "people" WHERE "people"."lucky_number" = 7) SELECT "lucky_number_seven".* FROM "lucky_number_seven" WHERE "lucky_number_seven"."id" = 5'
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'returns instances of the model' do
|
@@ -45,5 +45,11 @@ describe 'Common Table Expression queries' do
|
|
45
45
|
people.count.must_equal 3
|
46
46
|
people.first.lucky_number.must_equal 7
|
47
47
|
end
|
48
|
+
|
49
|
+
it 'responds to table_name' do
|
50
|
+
people = Person.from_cte('lucky_number_seven', Person.where(lucky_number: 7))
|
51
|
+
|
52
|
+
people.model_name.must_equal 'Person'
|
53
|
+
end
|
48
54
|
end
|
49
55
|
end
|
@@ -3,8 +3,11 @@ require 'test_helper'
|
|
3
3
|
describe 'Contains queries' do
|
4
4
|
let(:contained_within_regex) { %r{\"people\"\.\"ip\" << '127.0.0.1/24'} }
|
5
5
|
let(:contained_within_equals_regex) { %r{\"people\"\.\"ip\" <<= '127.0.0.1/24'} }
|
6
|
-
let(:
|
6
|
+
let(:contains_ip_regex) { %r{\"people\"\.\"ip\" >> '127.0.0.1'} }
|
7
|
+
let(:contains_array_regex) { %r{\"people\"\.\"tag_ids\" @> '\{1,2\}'} }
|
8
|
+
let(:contains_hstore_regex) { %r{\"people\"\.\"data\" @> '\"nickname\"=>"Dan"'} }
|
7
9
|
let(:contains_equals_regex) { %r{\"people\"\.\"ip\" >>= '127.0.0.1'} }
|
10
|
+
let(:equality_regex) { %r{\"people\"\.\"tags\" = '\{\"working\"\}'} }
|
8
11
|
|
9
12
|
describe '.where.contained_within(:column, value)' do
|
10
13
|
it 'generates the appropriate where clause' do
|
@@ -20,17 +23,34 @@ describe 'Contains queries' do
|
|
20
23
|
end
|
21
24
|
end
|
22
25
|
|
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.must_match contains_regex
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
26
|
describe '.where.contained_within_or_equals(:column, value)' do
|
31
27
|
it 'generates the appropriate where clause' do
|
32
28
|
query = Person.where.contains_or_equals(:ip => '127.0.0.1')
|
33
29
|
query.to_sql.must_match contains_equals_regex
|
34
30
|
end
|
35
31
|
end
|
32
|
+
|
33
|
+
describe '.where.contains(:column => value)' do
|
34
|
+
it 'generates the appropriate where clause for inet columns' do
|
35
|
+
query = Person.where.contains(:ip => '127.0.0.1')
|
36
|
+
query.to_sql.must_match contains_ip_regex
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'generates the appropriate where clause for array columns' do
|
40
|
+
query = Person.where.contains(:tag_ids => [1,2])
|
41
|
+
query.to_sql.must_match contains_array_regex
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'generates the appropriate where clause for array columns' do
|
45
|
+
query = Person.where.contains(data: { nickname: 'Dan' })
|
46
|
+
query.to_sql.must_match contains_hstore_regex
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'allows chaining' do
|
50
|
+
query = Person.where.contains(:tag_ids => [1,2]).where(:tags => ['working']).to_sql
|
51
|
+
|
52
|
+
query.must_match contains_array_regex
|
53
|
+
query.must_match equality_regex
|
54
|
+
end
|
55
|
+
end
|
36
56
|
end
|
data/test/queries/sanity_test.rb
CHANGED
@@ -29,4 +29,12 @@ describe 'Ensure that we don\'t stomp on Active Record\'s queries' do
|
|
29
29
|
person.habtm_tag_ids.must_be_empty
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
describe 'Associated record array query' do
|
34
|
+
it 'correctly identifies the column on associations with different class names' do
|
35
|
+
person = Person.create(:habtm_tag_ids => [Tag.create(categories: ['wicked', 'awesome']).id])
|
36
|
+
wicked_people = Person.wicked_people
|
37
|
+
wicked_people.must_include(person)
|
38
|
+
end
|
39
|
+
end
|
32
40
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'active_record'
|
2
2
|
require 'minitest/autorun'
|
3
3
|
require 'bourne'
|
4
|
-
require 'postgres_ext'
|
5
4
|
require 'database_cleaner'
|
6
5
|
unless ENV['CI'] || RUBY_PLATFORM =~ /java/
|
7
6
|
require 'byebug'
|
@@ -10,11 +9,18 @@ end
|
|
10
9
|
require 'dotenv'
|
11
10
|
Dotenv.load
|
12
11
|
|
13
|
-
|
12
|
+
require 'postgres_ext'
|
13
|
+
|
14
|
+
ActiveRecord::Base.establish_connection(ENV['DATABASE_URL'])
|
14
15
|
|
15
16
|
class Person < ActiveRecord::Base
|
16
17
|
has_many :hm_tags, class_name: 'Tag'
|
17
18
|
has_and_belongs_to_many :habtm_tags, class_name: 'Tag'
|
19
|
+
|
20
|
+
def self.wicked_people
|
21
|
+
includes(:habtm_tags)
|
22
|
+
.where(:tags => {:categories => ['wicked','awesome']})
|
23
|
+
end
|
18
24
|
end
|
19
25
|
|
20
26
|
class Tag < ActiveRecord::Base
|
metadata
CHANGED
@@ -1,41 +1,41 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postgres_ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan McClain
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-07-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: 4.0.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 4.0.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: arel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: 4.0.1
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 4.0.1
|
41
41
|
- !ruby/object:Gem::Dependency
|
@@ -159,7 +159,6 @@ extensions: []
|
|
159
159
|
extra_rdoc_files: []
|
160
160
|
files:
|
161
161
|
- ".gitignore"
|
162
|
-
- ".rspec"
|
163
162
|
- ".travis.yml"
|
164
163
|
- CHANGELOG.md
|
165
164
|
- CONTRIBUTING.md
|
@@ -167,6 +166,8 @@ files:
|
|
167
166
|
- README.md
|
168
167
|
- Rakefile
|
169
168
|
- docs/querying.md
|
169
|
+
- gemfiles/Gemfile.activerecord-4.0.x
|
170
|
+
- gemfiles/Gemfile.activerecord-4.1.x
|
170
171
|
- lib/postgres_ext.rb
|
171
172
|
- lib/postgres_ext/active_record.rb
|
172
173
|
- lib/postgres_ext/active_record/cte_proxy.rb
|
@@ -192,7 +193,7 @@ files:
|
|
192
193
|
- test/queries/sanity_test.rb
|
193
194
|
- test/queries/window_functions_test.rb
|
194
195
|
- test/test_helper.rb
|
195
|
-
homepage:
|
196
|
+
homepage: https://github.com/dockyard/postgres_ext
|
196
197
|
licenses:
|
197
198
|
- MIT
|
198
199
|
metadata: {}
|
data/.rspec
DELETED