postgres_ext 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/CONTRIBUTING.md +34 -26
- data/Gemfile +1 -5
- data/LICENSE +7 -0
- data/README.md +10 -9
- data/lib/postgres_ext/active_record/relation/predicate_builder.rb +20 -14
- data/lib/postgres_ext/active_record/relation/predicate_builder/array_handler.rb +8 -2
- data/lib/postgres_ext/active_record/relation/query_methods.rb +20 -0
- data/lib/postgres_ext/arel/4.1/predications.rb +4 -0
- data/lib/postgres_ext/arel/4.1/visitors/postgresql.rb +16 -6
- data/lib/postgres_ext/arel/4.2/predications.rb +4 -0
- data/lib/postgres_ext/arel/4.2/visitors/postgresql.rb +16 -8
- data/lib/postgres_ext/arel/nodes/contained_within.rb +11 -3
- data/lib/postgres_ext/version.rb +1 -1
- data/postgres_ext.gemspec +2 -2
- data/test/arel/array_test.rb +31 -0
- data/test/queries/alias_test.rb +8 -0
- data/test/queries/contains_test.rb +38 -1
- metadata +12 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b48714dc520de316aa59b0d2b060fbef891b6593
|
4
|
+
data.tar.gz: 7dad4eb4d9c355531dd3d32541b1b40bb351a86d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 089f82f5a520a181bae6c89aa9d5156f359ab36b6668fabe280311674eaa1a5b98b26f55e871f816a45ba56cb2a2957bda810519ce168b7029606032a08c336b
|
7
|
+
data.tar.gz: 6dd4946cf1306451410327bc05a627c5e867f8a43701d0687081d5e2e8a787a9476a5788cb9ce22ce55f5c05a264d0915038594603ee7d6048b3fa73b9d5db50
|
data/CHANGELOG.md
CHANGED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,74 @@
|
|
1
|
+
# Contributor Covenant Code of Conduct
|
2
|
+
|
3
|
+
## Our Pledge
|
4
|
+
|
5
|
+
In the interest of fostering an open and welcoming environment, we as
|
6
|
+
contributors and maintainers pledge to making participation in our project and
|
7
|
+
our community a harassment-free experience for everyone, regardless of age, body
|
8
|
+
size, disability, ethnicity, gender identity and expression, level of experience,
|
9
|
+
nationality, personal appearance, race, religion, or sexual identity and
|
10
|
+
orientation.
|
11
|
+
|
12
|
+
## Our Standards
|
13
|
+
|
14
|
+
Examples of behavior that contributes to creating a positive environment
|
15
|
+
include:
|
16
|
+
|
17
|
+
* Using welcoming and inclusive language
|
18
|
+
* Being respectful of differing viewpoints and experiences
|
19
|
+
* Gracefully accepting constructive criticism
|
20
|
+
* Focusing on what is best for the community
|
21
|
+
* Showing empathy towards other community members
|
22
|
+
|
23
|
+
Examples of unacceptable behavior by participants include:
|
24
|
+
|
25
|
+
* The use of sexualized language or imagery and unwelcome sexual attention or
|
26
|
+
advances
|
27
|
+
* Trolling, insulting/derogatory comments, and personal or political attacks
|
28
|
+
* Public or private harassment
|
29
|
+
* Publishing others' private information, such as a physical or electronic
|
30
|
+
address, without explicit permission
|
31
|
+
* Other conduct which could reasonably be considered inappropriate in a
|
32
|
+
professional setting
|
33
|
+
|
34
|
+
## Our Responsibilities
|
35
|
+
|
36
|
+
Project maintainers are responsible for clarifying the standards of acceptable
|
37
|
+
behavior and are expected to take appropriate and fair corrective action in
|
38
|
+
response to any instances of unacceptable behavior.
|
39
|
+
|
40
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
41
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
42
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
43
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
44
|
+
threatening, offensive, or harmful.
|
45
|
+
|
46
|
+
## Scope
|
47
|
+
|
48
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
49
|
+
when an individual is representing the project or its community. Examples of
|
50
|
+
representing a project or community include using an official project e-mail
|
51
|
+
address, posting via an official social media account, or acting as an appointed
|
52
|
+
representative at an online or offline event. Representation of a project may be
|
53
|
+
further defined and clarified by project maintainers.
|
54
|
+
|
55
|
+
## Enforcement
|
56
|
+
|
57
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
58
|
+
reported by contacting the project team at dan@danmcclain.net. All
|
59
|
+
complaints will be reviewed and investigated and will result in a response that
|
60
|
+
is deemed necessary and appropriate to the circumstances. The project team is
|
61
|
+
obligated to maintain confidentiality with regard to the reporter of an incident.
|
62
|
+
Further details of specific enforcement policies may be posted separately.
|
63
|
+
|
64
|
+
Project maintainers who do not follow or enforce the Code of Conduct in good
|
65
|
+
faith may face temporary or permanent repercussions as determined by other
|
66
|
+
members of the project's leadership.
|
67
|
+
|
68
|
+
## Attribution
|
69
|
+
|
70
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
|
71
|
+
available at [http://contributor-covenant.org/version/1/4][version]
|
72
|
+
|
73
|
+
[homepage]: http://contributor-covenant.org
|
74
|
+
[version]: http://contributor-covenant.org/version/1/4/
|
data/CONTRIBUTING.md
CHANGED
@@ -1,35 +1,43 @@
|
|
1
|
-
#
|
1
|
+
# How to contribute
|
2
2
|
|
3
|
-
##
|
3
|
+
## Improve documentation
|
4
4
|
|
5
|
-
|
5
|
+
We are always looking to improve our documentation. If at some moment you are
|
6
|
+
reading the documentation and something is not clear, or you can't find what you
|
7
|
+
are looking for, then please open an issue with the repository. This gives us a
|
8
|
+
chance to answer your question and to improve the documentation if needed.
|
6
9
|
|
7
|
-
|
10
|
+
Pull requests correcting spelling or grammar mistakes are always welcome.
|
8
11
|
|
9
|
-
|
10
|
-
issue being closed.
|
12
|
+
## Found a bug?
|
11
13
|
|
12
|
-
|
13
|
-
attempt to reproduce the issue in an isolated example application that
|
14
|
-
you can share.
|
14
|
+
Please try to answer at least the following questions when reporting a bug:
|
15
15
|
|
16
|
-
|
16
|
+
- Which version of the project did you use when you noticed the bug?
|
17
|
+
- How do you reproduce the error condition?
|
18
|
+
- What happened that you think is a bug?
|
19
|
+
- What should it do instead?
|
17
20
|
|
18
|
-
|
21
|
+
It would really help the maintainers if you could provide a reduced test case
|
22
|
+
that reproduces the error condition.
|
19
23
|
|
20
|
-
|
21
|
-
2. No single-character variables
|
22
|
-
3. Two-spaces instead of tabs
|
23
|
-
4. Single-quotes instead of double-quotes unless you are using string
|
24
|
-
interpolation or escapes.
|
25
|
-
5. General Rails/Ruby naming conventions for files and classes
|
26
|
-
6. *Do not* use Ruby 1.9 hash syntax
|
27
|
-
7. *Do not* use Ruby 1.9 stubby proc syntax
|
28
|
-
8. Follow Tim Pope's [model for git commit messages](http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html). This will make it
|
29
|
-
much easier to generate change logs and navigate through the logs
|
24
|
+
## Have a feature request?
|
30
25
|
|
31
|
-
Please
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
26
|
+
Please provide some thoughful commentary and code samples on what this feature
|
27
|
+
should do and why it should be added (your use case). The minimal questions you
|
28
|
+
should answer when submitting a feature request should be:
|
29
|
+
|
30
|
+
- What will it allow you to do that you can't do today?
|
31
|
+
- Why do you need this feature and how will it benefit other users?
|
32
|
+
- Are there any drawbacks to this feature?
|
33
|
+
|
34
|
+
## Submitting a pull-request?
|
35
|
+
|
36
|
+
Here are some things that will increase the chance that your pull-request will
|
37
|
+
get accepted:
|
38
|
+
- Did you confirm this fix/feature is something that is needed?
|
39
|
+
- Did you write tests, preferably in a test driven style?
|
40
|
+
- Did you add documentation for the changes you made?
|
41
|
+
|
42
|
+
If your pull-request addresses an issue then please add the corresponding
|
43
|
+
issue's number to the description of your pull-request.
|
data/Gemfile
CHANGED
data/LICENSE
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
Copyright (c) 2012 Dan McClain
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
4
|
+
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
6
|
+
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,19 +1,20 @@
|
|
1
1
|
# PostgresExt
|
2
2
|
|
3
|
+
## You can help!
|
4
|
+
This gem could use some updating, and I've moved on from Ruby, but I'd like to see this gem continue to survive. If you're interested in helping maintain the gem, please reach out on [twitter](https://twitter.com/_danmcclain).
|
5
|
+
|
6
|
+
## Overview
|
7
|
+
|
3
8
|
Adds missing native PostgreSQL data types to ActiveRecord and convenient querying extensions for ActiveRecord and Arel for Rails 4.x
|
4
9
|
|
5
|
-
[![Build Status](https://secure.travis-ci.org/
|
6
|
-
[![Code Climate](https://codeclimate.com/github/
|
7
|
-
[![Gem Version](https://badge.fury.io/rb/postgres_ext.png)](
|
10
|
+
[![Build Status](https://secure.travis-ci.org/danmcclain/postgres_ext.png?branch=master)](https://travis-ci.org/danmcclain/postgres_ext)
|
11
|
+
[![Code Climate](https://codeclimate.com/github/danmcclain/postgres_ext.png)](https://codeclimate.com/github/danmcclain/postgres_ext)
|
12
|
+
[![Gem Version](https://badge.fury.io/rb/postgres_ext.png)](https://badge.fury.io/rb/postgres_ext)
|
8
13
|
|
9
14
|
## Looking for help? ##
|
10
15
|
|
11
|
-
|
12
|
-
Github](https://github.com/
|
13
|
-
the gem please ask the question on
|
14
|
-
[Stack Overflow](http://stackoverflow.com). Be sure to tag the
|
15
|
-
question with `DockYard` so we can find it.
|
16
|
-
|
16
|
+
Bug or question? [Please open an issue on
|
17
|
+
Github](https://github.com/danmcclain/postgres_ext/issues).
|
17
18
|
## Installation
|
18
19
|
|
19
20
|
Add this line to your application's Gemfile:
|
@@ -5,8 +5,14 @@ module ActiveRecord
|
|
5
5
|
def self.build(attribute, value)
|
6
6
|
case value
|
7
7
|
when Array
|
8
|
-
|
9
|
-
|
8
|
+
column = case attribute.try(:relation)
|
9
|
+
when Arel::Nodes::TableAlias, NilClass
|
10
|
+
else
|
11
|
+
cache = attribute.relation.engine.connection.schema_cache
|
12
|
+
if cache.table_exists? attribute.relation.name
|
13
|
+
cache.columns(attribute.relation.name).detect{ |col| col.name.to_s == attribute.name.to_s }
|
14
|
+
end
|
15
|
+
end
|
10
16
|
if column && column.respond_to?(:array) && column.array
|
11
17
|
attribute.eq(value)
|
12
18
|
else
|
@@ -14,19 +20,19 @@ module ActiveRecord
|
|
14
20
|
ranges, values = values.partition {|v| v.is_a?(Range)}
|
15
21
|
|
16
22
|
values_predicate = if values.include?(nil)
|
17
|
-
|
23
|
+
values = values.compact
|
18
24
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
25
|
+
case values.length
|
26
|
+
when 0
|
27
|
+
attribute.eq(nil)
|
28
|
+
when 1
|
29
|
+
attribute.eq(values.first).or(attribute.eq(nil))
|
30
|
+
else
|
31
|
+
attribute.in(values).or(attribute.eq(nil))
|
32
|
+
end
|
33
|
+
else
|
34
|
+
attribute.in(values)
|
35
|
+
end
|
30
36
|
|
31
37
|
array_predicates = ranges.map { |range| attribute.in(range) }
|
32
38
|
array_predicates << values_predicate
|
@@ -10,8 +10,14 @@ module ActiveRecord
|
|
10
10
|
|
11
11
|
included do
|
12
12
|
def call_with_feature(attribute, value)
|
13
|
-
|
14
|
-
|
13
|
+
column = case attribute.try(:relation)
|
14
|
+
when Arel::Nodes::TableAlias, NilClass
|
15
|
+
else
|
16
|
+
cache = attribute.relation.engine.connection.schema_cache
|
17
|
+
if cache.table_exists? attribute.relation.name
|
18
|
+
cache.columns(attribute.relation.name).detect{ |col| col.name.to_s == attribute.name.to_s }
|
19
|
+
end
|
20
|
+
end
|
15
21
|
if column && column.respond_to?(:array) && column.array
|
16
22
|
attribute.eq(value)
|
17
23
|
else
|
@@ -33,6 +33,26 @@ module ActiveRecord
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
+
def contained_in_array(opts, *rest)
|
37
|
+
build_where_chain(opts, rest) do |rel|
|
38
|
+
case rel
|
39
|
+
when Arel::Nodes::In, Arel::Nodes::Equality
|
40
|
+
column = left_column(rel) || column_from_association(rel)
|
41
|
+
equality_for_hstore(rel) if column.type == :hstore
|
42
|
+
|
43
|
+
if column.type == :hstore
|
44
|
+
Arel::Nodes::ContainedInHStore.new(rel.left, rel.right)
|
45
|
+
elsif column.respond_to?(:array) && column.array
|
46
|
+
Arel::Nodes::ContainedInArray.new(rel.left, rel.right)
|
47
|
+
else
|
48
|
+
Arel::Nodes::ContainsINet.new(rel.left, rel.right)
|
49
|
+
end
|
50
|
+
else
|
51
|
+
raise ArgumentError, "Invalid argument for .where.overlap(), got #{rel.class}"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
36
56
|
def contains_or_equals(opts, *rest)
|
37
57
|
substitute_comparisons(opts, rest, Arel::Nodes::ContainsEquals, 'contains_or_equals')
|
38
58
|
end
|
@@ -10,12 +10,14 @@ module Arel
|
|
10
10
|
when Arel::Nodes::TableAlias, NilClass
|
11
11
|
# noop Prevent from searching for table alias name in schema cache
|
12
12
|
# which won't exist for aliased table when used with Single Table
|
13
|
-
# Inheritance. see dockyard/postgres_ext#154
|
13
|
+
# Inheritance. see dockyard/postgres_ext#154 (This issue has been removed)
|
14
14
|
else
|
15
|
-
|
16
|
-
|
15
|
+
cache = a.relation.engine.connection.schema_cache
|
16
|
+
if cache.table_exists? a.relation.name
|
17
|
+
cache.columns(a.relation.name).find { |col| col.name == a.name.to_s }
|
18
|
+
end
|
17
19
|
end
|
18
|
-
|
20
|
+
|
19
21
|
if column && column.respond_to?(:array) && column.array
|
20
22
|
quoted o, a
|
21
23
|
else
|
@@ -25,14 +27,14 @@ module Arel
|
|
25
27
|
|
26
28
|
def visit_Arel_Nodes_Contains o, a = nil
|
27
29
|
left_column = o.left.relation.engine.columns.find { |col| col.name == o.left.name.to_s }
|
28
|
-
|
30
|
+
|
29
31
|
if left_column && (left_column.type == :hstore || (left_column.respond_to?(:array) && left_column.array))
|
30
32
|
"#{visit o.left, a} @> #{visit o.right, o.left}"
|
31
33
|
else
|
32
34
|
"#{visit o.left, a} >> #{visit o.right, o.left}"
|
33
35
|
end
|
34
36
|
end
|
35
|
-
|
37
|
+
|
36
38
|
def visit_Arel_Nodes_ContainedWithin o, a = nil
|
37
39
|
"#{visit o.left, a} << #{visit o.right, o.left}"
|
38
40
|
end
|
@@ -45,10 +47,18 @@ module Arel
|
|
45
47
|
"#{visit o.left, a} @> #{visit o.right, o.left}"
|
46
48
|
end
|
47
49
|
|
50
|
+
def visit_Arel_Nodes_ContainedInArray o, a = nil
|
51
|
+
"#{visit o.left, a} <@ #{visit o.right, o.left}"
|
52
|
+
end
|
53
|
+
|
48
54
|
def visit_Arel_Nodes_ContainsHStore o, a = nil
|
49
55
|
"#{visit o.left, a} @> #{visit o.right, o.left}"
|
50
56
|
end
|
51
57
|
|
58
|
+
def visit_Arel_Nodes_ContainedInHStore o, a = nil
|
59
|
+
"#{visit o.left, a} <@ #{visit o.right, o.left}"
|
60
|
+
end
|
61
|
+
|
52
62
|
def visit_Arel_Nodes_ContainsINet o, a = nil
|
53
63
|
"#{visit o.left, a} >> #{visit o.right, o.left}"
|
54
64
|
end
|
@@ -14,6 +14,10 @@ module Arel
|
|
14
14
|
Nodes::Contains.new self, Nodes.build_quoted(other, self)
|
15
15
|
end
|
16
16
|
|
17
|
+
def contained_in_array(other)
|
18
|
+
Nodes::ContainedInArray.new self, Nodes.build_quoted(other, self)
|
19
|
+
end
|
20
|
+
|
17
21
|
def contains_or_equals(other)
|
18
22
|
Nodes::ContainsEquals.new self, Nodes.build_quoted(other, self)
|
19
23
|
end
|
@@ -4,13 +4,13 @@ module Arel
|
|
4
4
|
module Visitors
|
5
5
|
class PostgreSQL
|
6
6
|
private
|
7
|
-
|
7
|
+
|
8
8
|
def visit_Arel_Nodes_ContainedWithin o, collector
|
9
|
-
infix_value o, collector, " << "
|
9
|
+
infix_value o, collector, " << "
|
10
10
|
end
|
11
11
|
|
12
12
|
def visit_Arel_Nodes_ContainedWithinEquals o, collector
|
13
|
-
infix_value o, collector, " <<= "
|
13
|
+
infix_value o, collector, " <<= "
|
14
14
|
end
|
15
15
|
|
16
16
|
def visit_Arel_Nodes_Contains o, collector
|
@@ -21,24 +21,32 @@ module Arel
|
|
21
21
|
if left_column && (left_column.type == :hstore || (left_column.respond_to?(:array) && left_column.array))
|
22
22
|
infix_value o, collector, " @> "
|
23
23
|
else
|
24
|
-
infix_value o, collector, " >> "
|
24
|
+
infix_value o, collector, " >> "
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
28
|
def visit_Arel_Nodes_ContainsINet o, collector
|
29
|
-
infix_value o, collector, " >> "
|
29
|
+
infix_value o, collector, " >> "
|
30
30
|
end
|
31
31
|
|
32
32
|
def visit_Arel_Nodes_ContainsHStore o, collector
|
33
33
|
infix_value o, collector, " @> "
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
|
+
def visit_Arel_Nodes_ContainedInHStore o, collector
|
37
|
+
infix_value o, collector, " <@ "
|
38
|
+
end
|
39
|
+
|
36
40
|
def visit_Arel_Nodes_ContainsArray o, collector
|
37
41
|
infix_value o, collector, " @> "
|
38
42
|
end
|
39
|
-
|
43
|
+
|
44
|
+
def visit_Arel_Nodes_ContainedInArray o, collector
|
45
|
+
infix_value o, collector, " <@ "
|
46
|
+
end
|
47
|
+
|
40
48
|
def visit_Arel_Nodes_ContainsEquals o, collector
|
41
|
-
infix_value o, collector, " >>= "
|
49
|
+
infix_value o, collector, " >>= "
|
42
50
|
end
|
43
51
|
|
44
52
|
def visit_Arel_Nodes_Overlap o, collector
|
@@ -12,7 +12,7 @@ module Arel
|
|
12
12
|
class Contains < Arel::Nodes::Binary
|
13
13
|
def operator; :>> end
|
14
14
|
end
|
15
|
-
|
15
|
+
|
16
16
|
class ContainsINet < Arel::Nodes::Binary
|
17
17
|
def operator; :>> end
|
18
18
|
end
|
@@ -20,11 +20,19 @@ module Arel
|
|
20
20
|
class ContainsHStore < Arel::Nodes::Binary
|
21
21
|
def operator; :"@>" end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
|
+
class ContainedInHStore < Arel::Nodes::Binary
|
25
|
+
def operator; :"<@" end
|
26
|
+
end
|
27
|
+
|
24
28
|
class ContainsArray < Arel::Nodes::Binary
|
25
29
|
def operator; :"@>" end
|
26
30
|
end
|
27
|
-
|
31
|
+
|
32
|
+
class ContainedInArray < Arel::Nodes::Binary
|
33
|
+
def operator; :"<@" end
|
34
|
+
end
|
35
|
+
|
28
36
|
class ContainsEquals < Arel::Nodes::Binary
|
29
37
|
def operator; :">>=" end
|
30
38
|
end
|
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 = 'https://github.com/
|
9
|
+
gem.homepage = 'https://github.com/danmcclain/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,7 +16,7 @@ Gem::Specification.new do |gem|
|
|
16
16
|
gem.require_paths = ["lib"]
|
17
17
|
gem.version = PostgresExt::VERSION
|
18
18
|
|
19
|
-
gem.add_dependency 'activerecord', '
|
19
|
+
gem.add_dependency 'activerecord', '~> 4.0'
|
20
20
|
gem.add_dependency 'arel', '>= 4.0.1'
|
21
21
|
gem.add_dependency 'pg_array_parser', '~> 0.0.9'
|
22
22
|
|
data/test/arel/array_test.rb
CHANGED
@@ -89,4 +89,35 @@ describe 'Array Column Predicates' do
|
|
89
89
|
Person.find_by_sql(query.to_sql).wont_include two
|
90
90
|
end
|
91
91
|
end
|
92
|
+
|
93
|
+
describe 'Array Contained In Array' do
|
94
|
+
it 'converts Arel contained_in_array statement and escapes strings' do
|
95
|
+
arel_table.where(arel_table[:tags].contained_in_array(['tag','tag 2'])).to_sql.must_match /<@ '\{"?tag"?,"tag 2"\}'/
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'converts Arel contained_in_array statement with numbers' do
|
99
|
+
arel_table.where(arel_table[:tag_ids].contained_in_array([1,2])).to_sql.must_match /<@ '\{1,2\}'/
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'works with count (and other predicates)' do
|
103
|
+
Person.where(arel_table[:tag_ids].contained_in_array([1,2])).count.must_equal 0
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'returns matched records' do
|
107
|
+
one = Person.create!(:tags => ['one', 'two'])
|
108
|
+
two = Person.create!(:tags => ['one', 'three'])
|
109
|
+
|
110
|
+
query = arel_table.where(arel_table[:tags].contained_in_array(['one', 'two', 'three'])).project(Arel.sql('*'))
|
111
|
+
Person.find_by_sql(query.to_sql).must_include one
|
112
|
+
Person.find_by_sql(query.to_sql).must_include two
|
113
|
+
|
114
|
+
query = arel_table.where(arel_table[:tags].contained_in_array(['one', 'three'])).project(Arel.sql('*'))
|
115
|
+
Person.find_by_sql(query.to_sql).wont_include one
|
116
|
+
Person.find_by_sql(query.to_sql).must_include two
|
117
|
+
|
118
|
+
query = arel_table.where(arel_table[:tags].contained_in_array(['two'])).project(Arel.sql('*'))
|
119
|
+
Person.find_by_sql(query.to_sql).wont_include one
|
120
|
+
Person.find_by_sql(query.to_sql).wont_include two
|
121
|
+
end
|
122
|
+
end
|
92
123
|
end
|
@@ -6,6 +6,8 @@ describe 'Contains queries' do
|
|
6
6
|
let(:contains_ip_regex) { %r{\"people\"\.\"ip\" >> '127.0.0.1'} }
|
7
7
|
let(:contains_array_regex) { %r{\"people\"\.\"tag_ids\" @> '\{1,2\}'} }
|
8
8
|
let(:contains_hstore_regex) { %r{\"people\"\.\"data\" @> '\"nickname\"=>"Dan"'} }
|
9
|
+
let(:contained_in_array_regex) { %r{\"people\"\.\"tag_ids\" <@ '\{1,2\}'} }
|
10
|
+
let(:contained_in_hstore_regex) { %r{\"people\"\.\"data\" <@ '\"nickname\"=>"Dan"'} }
|
9
11
|
let(:contains_equals_regex) { %r{\"people\"\.\"ip\" >>= '127.0.0.1'} }
|
10
12
|
let(:equality_regex) { %r{\"people\"\.\"tags\" = '\{"?working"?\}'} }
|
11
13
|
|
@@ -50,7 +52,7 @@ describe 'Contains queries' do
|
|
50
52
|
query = Tag.joins(:person).where.contains(people: { data: { nickname: 'Dan' } })
|
51
53
|
query.to_sql.must_match contains_hstore_regex
|
52
54
|
end
|
53
|
-
|
55
|
+
|
54
56
|
it 'allows chaining' do
|
55
57
|
query = Person.where.contains(:tag_ids => [1,2]).where(:tags => ['working']).to_sql
|
56
58
|
|
@@ -64,4 +66,39 @@ describe 'Contains queries' do
|
|
64
66
|
query.must_match contains_array_regex
|
65
67
|
end
|
66
68
|
end
|
69
|
+
|
70
|
+
describe '.where.contained_in_array(:column => value)' do
|
71
|
+
it 'generates the appropriate where clause for inet columns' do
|
72
|
+
query = Person.where.contains(:ip => '127.0.0.1')
|
73
|
+
query.to_sql.must_match contains_ip_regex
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'generates the appropriate where clause for array columns' do
|
77
|
+
query = Person.where.contained_in_array(:tag_ids => [1,2])
|
78
|
+
query.to_sql.must_match contained_in_array_regex
|
79
|
+
end
|
80
|
+
|
81
|
+
it 'generates the appropriate where clause for hstore columns' do
|
82
|
+
query = Person.where.contained_in_array(data: { nickname: 'Dan' })
|
83
|
+
query.to_sql.must_match contained_in_hstore_regex
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'generates the appropriate where clause for hstore columns on joins' do
|
87
|
+
query = Tag.joins(:person).where.contained_in_array(people: { data: { nickname: 'Dan' } })
|
88
|
+
query.to_sql.must_match contained_in_hstore_regex
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'allows chaining' do
|
92
|
+
query = Person.where.contained_in_array(:tag_ids => [1,2]).where(:tags => ['working']).to_sql
|
93
|
+
|
94
|
+
query.must_match contained_in_array_regex
|
95
|
+
query.must_match equality_regex
|
96
|
+
end
|
97
|
+
|
98
|
+
it 'generates the appropriate where clause for array columns on joins' do
|
99
|
+
query = Tag.joins(:person).where.contained_in_array(people: { tag_ids: [1,2] }).to_sql
|
100
|
+
|
101
|
+
query.must_match contained_in_array_regex
|
102
|
+
end
|
103
|
+
end
|
67
104
|
end
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: postgres_ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dan McClain
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-04-16 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
|
-
version: 4.0
|
19
|
+
version: '4.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
|
-
version: 4.0
|
26
|
+
version: '4.0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: arel
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -161,8 +161,10 @@ files:
|
|
161
161
|
- ".gitignore"
|
162
162
|
- ".travis.yml"
|
163
163
|
- CHANGELOG.md
|
164
|
+
- CODE_OF_CONDUCT.md
|
164
165
|
- CONTRIBUTING.md
|
165
166
|
- Gemfile
|
167
|
+
- LICENSE
|
166
168
|
- README.md
|
167
169
|
- Rakefile
|
168
170
|
- docs/querying.md
|
@@ -193,6 +195,7 @@ files:
|
|
193
195
|
- postgres_ext.gemspec
|
194
196
|
- test/arel/array_test.rb
|
195
197
|
- test/arel/inet_test.rb
|
198
|
+
- test/queries/alias_test.rb
|
196
199
|
- test/queries/array_queries_test.rb
|
197
200
|
- test/queries/common_table_expression_test.rb
|
198
201
|
- test/queries/contains_test.rb
|
@@ -200,7 +203,7 @@ files:
|
|
200
203
|
- test/queries/sanity_test.rb
|
201
204
|
- test/queries/window_functions_test.rb
|
202
205
|
- test/test_helper.rb
|
203
|
-
homepage: https://github.com/
|
206
|
+
homepage: https://github.com/danmcclain/postgres_ext
|
204
207
|
licenses:
|
205
208
|
- MIT
|
206
209
|
metadata: {}
|
@@ -220,13 +223,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
220
223
|
version: '0'
|
221
224
|
requirements: []
|
222
225
|
rubyforge_project:
|
223
|
-
rubygems_version: 2.4.
|
226
|
+
rubygems_version: 2.4.5
|
224
227
|
signing_key:
|
225
228
|
specification_version: 4
|
226
229
|
summary: Extends ActiveRecord to handle native PostgreSQL data types
|
227
230
|
test_files:
|
228
231
|
- test/arel/array_test.rb
|
229
232
|
- test/arel/inet_test.rb
|
233
|
+
- test/queries/alias_test.rb
|
230
234
|
- test/queries/array_queries_test.rb
|
231
235
|
- test/queries/common_table_expression_test.rb
|
232
236
|
- test/queries/contains_test.rb
|