arel-extensions 1.0.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 +7 -0
- data/LICENSE +21 -0
- data/README.md +216 -0
- data/arel-extensions.gemspec +19 -0
- data/lib/arel/array_predications.rb +20 -0
- data/lib/arel/attributes/key.rb +13 -0
- data/lib/arel/extensions.rb +16 -0
- data/lib/arel/json_predications.rb +23 -0
- data/lib/arel/nodes/contains.rb +6 -0
- data/lib/arel/nodes/has_any_key.rb +7 -0
- data/lib/arel/nodes/has_key.rb +7 -0
- data/lib/arel/nodes/has_keys.rb +7 -0
- data/lib/arel/nodes/overlaps.rb +6 -0
- data/lib/arel/visitors/postgresql_extensions.rb +45 -0
- metadata +99 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4847138fb20c8ca58e5bf419b595e1cf9e4dc809
|
4
|
+
data.tar.gz: 54565109b15574583361a153a2558bdb5deac376
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: d934dc0afa953e09db3837747ebc919ae473901f6da32033a76635261eda113c75504a7ac98c861b48983993c2e0dace2f439f31d18542b62e01ce30b1d66d74
|
7
|
+
data.tar.gz: f568ff754c5f16fca13c73925353ffe9aae53fcd1cdfa8da74dafebabef5110c0308135375241c8c82e7bb2f420229da4ec41bdc3d9b99e055215d387a988ae6
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2016 Jon Bracy
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,216 @@
|
|
1
|
+
# Arel Extensions
|
2
|
+
|
3
|
+
Adds support for missing SQL operators and functions to Arel for ActiveRecord.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'arel-extensions', require: 'arel/extensions'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install arel-extensions
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Just `require 'arel-extensions'` and use Arel/ActiveRecord as you normally would!
|
22
|
+
arel-extensions extends ActiveRecord's query methods in both Arel and ActiveRecord.
|
23
|
+
|
24
|
+
* [Querying PostgreSQL datatypes](docs/querying.md)
|
25
|
+
|
26
|
+
## Arrays
|
27
|
+
|
28
|
+
* [@> - Array Contains operator](#---array-contains-operator)
|
29
|
+
* [<@ - Array Contained By operator](#---array-contined-by-operator)
|
30
|
+
* [&& - Array Overlap operator](#---array-overlap-operator)
|
31
|
+
|
32
|
+
### && - Array Overlap operator
|
33
|
+
|
34
|
+
PostgreSQL implements the `&&` operator, known as the overlap operator,
|
35
|
+
for arrays. The overlap operator returns `t` (true) when two arrays have
|
36
|
+
one or more elements in common.
|
37
|
+
|
38
|
+
```sql
|
39
|
+
ARRAY[1,2,3] && ARRAY[4,5,6]
|
40
|
+
-- f
|
41
|
+
|
42
|
+
ARRAY[1,2,3] && ARRAY[3,5,6]
|
43
|
+
-- t
|
44
|
+
```
|
45
|
+
|
46
|
+
Postgres\_ext extends the `ActiveRecord::Relation.where` method similar
|
47
|
+
to the Rails 4.0 not clause. The easiest way to make a overlap query
|
48
|
+
would be:
|
49
|
+
|
50
|
+
```ruby
|
51
|
+
User.where.overlap(:nick_names => ['Bob', 'Fred'])
|
52
|
+
```
|
53
|
+
|
54
|
+
Postgres\_ext defines `overlap`, an [Arel](https://github.com/rails/arel)
|
55
|
+
predicate for the `&&` operator. This is utilized by the `where.overlap`
|
56
|
+
call above.
|
57
|
+
|
58
|
+
```ruby
|
59
|
+
user_arel = User.arel_table
|
60
|
+
|
61
|
+
# Execute the query
|
62
|
+
User.where(user_arel[:tags].overlap(['one','two']))
|
63
|
+
# => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"tags\" && '{one,two}'
|
64
|
+
```
|
65
|
+
|
66
|
+
### @> - Array Contains operator
|
67
|
+
|
68
|
+
PostgreSQL has a contains (`@>`) operator for querying whether all the
|
69
|
+
elements of an array are within another.
|
70
|
+
|
71
|
+
```sql
|
72
|
+
ARRAY[1,2,3] @> ARRAY[3,4]
|
73
|
+
-- f
|
74
|
+
|
75
|
+
ARRAY[1,2,3] @> ARRAY[2,3]
|
76
|
+
-- t
|
77
|
+
```
|
78
|
+
|
79
|
+
Postgres\_ext extends the `ActiveRecord::Relation.where` method by
|
80
|
+
adding a `contains` method. To make a contains query, you can do:
|
81
|
+
|
82
|
+
```ruby
|
83
|
+
User.where.contains(:nick_names => ['Bob', 'Fred'])
|
84
|
+
```
|
85
|
+
|
86
|
+
Postgres\_ext overrides `contains`, an [Arel](https://github.com/rails/arel)
|
87
|
+
predicate, to use the `@>` operator for arrays. This is utilized by the
|
88
|
+
`where.contains` call above.
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
user_arel = User.arel_table
|
92
|
+
|
93
|
+
# Execute the query
|
94
|
+
User.where(user_arel[:tags].contains(['one','two']))
|
95
|
+
# => SELECT "users".* FROM "users" WHERE "users"."tags" @> '{"one","two"}'
|
96
|
+
```
|
97
|
+
|
98
|
+
### ANY or ALL functions
|
99
|
+
|
100
|
+
When querying array columns, you have the ability to see if a predicate
|
101
|
+
apply's to either *any* element in the array, or *all* elements of the
|
102
|
+
array. The syntax for these predicates are slightly different then the
|
103
|
+
normal `where` syntax in PostgreSQL. To see if an array contains the
|
104
|
+
string `'test'` in any location, you would write the following in SQL
|
105
|
+
|
106
|
+
```sql
|
107
|
+
SELECT *
|
108
|
+
FROM users
|
109
|
+
WHERE 'test' = ANY(users.tags)
|
110
|
+
```
|
111
|
+
|
112
|
+
Notice that the column is on the right hand side of the predicate,
|
113
|
+
instead of the left, because we have to call the `ANY` function on that
|
114
|
+
column.
|
115
|
+
|
116
|
+
Postgres\_ext provides a `ActiveRecord::Relation.where.any()` method. The
|
117
|
+
easiest way to make a ANY query would be:
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
User.where.any(:nick_names => 'Bob')
|
121
|
+
```
|
122
|
+
|
123
|
+
There is also an `ActiveRecord::Relation.where.all()` call as well. This
|
124
|
+
method utilizes the following code to create the query:
|
125
|
+
|
126
|
+
We can generate the above query using [Arel](https://github.com/rails/arel)
|
127
|
+
and generating the Node manually. We would use the following to
|
128
|
+
accompish this:
|
129
|
+
|
130
|
+
```ruby
|
131
|
+
user_arel = User.arel_table
|
132
|
+
|
133
|
+
# Execute the query
|
134
|
+
User.where(user_arel[:tags].any('test'))
|
135
|
+
#=> SELECT \"users\".* FROM \"users\" WHERE 'test' = ANY(\"users\".\"tags\")
|
136
|
+
```
|
137
|
+
|
138
|
+
The ALL version of this same predicate can be generated by swapping
|
139
|
+
`#any()` for `#all()`.
|
140
|
+
|
141
|
+
## INET/CIDR Queries
|
142
|
+
|
143
|
+
PostgreSQL defines the `<<`, or contained within operator for INET and
|
144
|
+
CIDR datatypes. The `<<` operator returns `t` (true) if a INET or CIDR
|
145
|
+
address is contained within the given subnet.
|
146
|
+
|
147
|
+
```sql
|
148
|
+
inet '192.168.1.6' << inet '10.0.0.0/24'
|
149
|
+
-- f
|
150
|
+
|
151
|
+
inet '192.168.1.6' << inet '192.168.1.0/24'
|
152
|
+
-- t
|
153
|
+
```
|
154
|
+
|
155
|
+
In addition to contained within, there is also:
|
156
|
+
|
157
|
+
* `<<=` - Contained within or equals
|
158
|
+
* `>>` - Contains
|
159
|
+
* `>>=` - Contains or equals
|
160
|
+
|
161
|
+
Postgres\_ext extends the `ActiveRecord::Relation.where` method similar
|
162
|
+
to the Rails 4.0 not clause. The easiest way to make a overlap query
|
163
|
+
would be:
|
164
|
+
|
165
|
+
```ruby
|
166
|
+
User.where.contained_within(:ip => '192.168.1.1/24')
|
167
|
+
User.where.contained_within_or_equals(:ip => '192.168.1.1/24')
|
168
|
+
User.where.contains(:ip => '192.168.1.14')
|
169
|
+
User.where.contains_or_equals(:ip => '192.168.1.14')
|
170
|
+
```
|
171
|
+
|
172
|
+
Postgres\_ext defines `contained_within`, an [Arel](https://github.com/rails/arel)
|
173
|
+
predicate for the `<<` operator. This is utilized by the
|
174
|
+
methods above.
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
user_arel = User.arel_table
|
178
|
+
|
179
|
+
# Execute the query
|
180
|
+
User.where(user_arel[:ip_address].contained_within('127.0.0.1/24'))
|
181
|
+
# => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"ip_address\" << '127.0.0.1/24'
|
182
|
+
User.where(user_arel[:ip_address].contained_within_or_equals('127.0.0.1/24'))
|
183
|
+
# => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"ip_address\" <<= '127.0.0.1/24'
|
184
|
+
User.where(user_arel[:ip_address].contains('127.0.0.1'))
|
185
|
+
# => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"ip_address\" >> '127.0.0.1'
|
186
|
+
User.where(user_arel[:ip_address].contains_or_equals('127.0.0.1'))
|
187
|
+
# => SELECT \"users\".* FROM \"users\" WHERE \"users\".\"ip_address\" >>= '127.0.0.1'
|
188
|
+
```
|
189
|
+
|
190
|
+
## Developing
|
191
|
+
|
192
|
+
To work on postgres\_ext locally, follow these steps:
|
193
|
+
|
194
|
+
1. Run `bundle install`, this will install (almost) all the development
|
195
|
+
dependencies
|
196
|
+
2. Run `gem install byebug` (not a declared dependency to not break CI)
|
197
|
+
3. Run `bundle exec rake db:setup`, this will set up the `.env` file necessary to run
|
198
|
+
the tests and set up the database
|
199
|
+
4. Run `bundle exec rake db:create`, this will create the test database
|
200
|
+
5. Run `bundle exec rake db:migrate`, this will set up the database tables required
|
201
|
+
by the test
|
202
|
+
6. Run `BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-4.0.x' bundle install --quiet` to create the Gemfile.lock for 4.0.
|
203
|
+
7. Run `BUNDLE_GEMFILE='gemfiles/Gemfile.activerecord-4.1.x' bundle install --quiet` to create the Gemfile.lock for 4.1.
|
204
|
+
8. Run `bundle exec rake test:all` to run tests against all supported versions of Active Record
|
205
|
+
|
206
|
+
## Authors
|
207
|
+
|
208
|
+
Dan McClain [twitter](http://twitter.com/_danmcclain) [github](http://github.com/danmcclain)
|
209
|
+
|
210
|
+
|
211
|
+
|
212
|
+
|
213
|
+
|
214
|
+
Change.arel_table[:diff].has_key?(:in_review)
|
215
|
+
Change.arel_table[:diff].has_keys?(:in_review, :cached_at)
|
216
|
+
Change.arel_table[:diff].has_any_key?(:in_review, :nokey)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |gem|
|
2
|
+
gem.name = 'arel-extensions'
|
3
|
+
gem.version = '1.0.0'
|
4
|
+
|
5
|
+
gem.authors = ["Jon Bracy"]
|
6
|
+
gem.email = ["jonbracy@gmail.com"]
|
7
|
+
gem.summary = %q{Adds support for missing SQL operators and functions to Arel}
|
8
|
+
gem.homepage = 'https://github.com/malomalo/arel-extensions'
|
9
|
+
gem.licenses = ['MIT']
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split("\n")
|
12
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
13
|
+
gem.require_paths = ["lib"]
|
14
|
+
|
15
|
+
gem.add_dependency 'arel', '>= 7.0.0'
|
16
|
+
|
17
|
+
gem.add_development_dependency 'rake'
|
18
|
+
gem.add_development_dependency 'minitest'
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Arel
|
2
|
+
module ArrayPredications
|
3
|
+
|
4
|
+
def contains(*values)
|
5
|
+
values = values[0] if values.size == 1 && values[0].is_a?(Array)
|
6
|
+
Arel::Nodes::Contains.new(self, values)
|
7
|
+
end
|
8
|
+
|
9
|
+
def contained_by(*values)
|
10
|
+
values = values[0] if values.size == 1 && values[0].is_a?(Array)
|
11
|
+
Arel::Nodes::ContainedBy.new(self, values)
|
12
|
+
end
|
13
|
+
|
14
|
+
def overlaps(*values)
|
15
|
+
values = values[0] if values.size == 1 && values[0].is_a?(Array)
|
16
|
+
Arel::Nodes::Overlaps.new(self, values)
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.expand_path('../array_predications', __FILE__)
|
2
|
+
require File.expand_path('../nodes/overlaps', __FILE__)
|
3
|
+
require File.expand_path('../nodes/contains', __FILE__)
|
4
|
+
Arel::Attributes::Attribute.include(Arel::ArrayPredications)
|
5
|
+
|
6
|
+
|
7
|
+
require File.expand_path('../attributes/key', __FILE__)
|
8
|
+
require File.expand_path('../nodes/has_any_key', __FILE__)
|
9
|
+
require File.expand_path('../nodes/has_key', __FILE__)
|
10
|
+
require File.expand_path('../nodes/has_keys', __FILE__)
|
11
|
+
require File.expand_path('../json_predications', __FILE__)
|
12
|
+
Arel::Attributes::Attribute.include(Arel::JSONPredications)
|
13
|
+
|
14
|
+
if defined?(Arel::Visitors::PostgreSQL)
|
15
|
+
require File.expand_path('../visitors/postgresql_extensions', __FILE__)
|
16
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Arel
|
2
|
+
module JSONPredications
|
3
|
+
|
4
|
+
def key(key)
|
5
|
+
Arel::Attributes::Key.new(self, key)
|
6
|
+
end
|
7
|
+
alias :[] :key
|
8
|
+
alias :index :key
|
9
|
+
|
10
|
+
def has_key(key)
|
11
|
+
Arel::Nodes::HasKey.new(self, key)
|
12
|
+
end
|
13
|
+
|
14
|
+
def has_keys(*keys)
|
15
|
+
Arel::Nodes::HasKeys.new(self, keys)
|
16
|
+
end
|
17
|
+
|
18
|
+
def has_any_key(*keys)
|
19
|
+
Arel::Nodes::HasAnyKeys.new(self, keys)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Arel
|
2
|
+
module Visitors
|
3
|
+
class PostgreSQL
|
4
|
+
private
|
5
|
+
|
6
|
+
def visit_Arel_Nodes_Contains o, collector
|
7
|
+
visit o.left, collector
|
8
|
+
collector << ' @> '
|
9
|
+
collector << quote(o.left.type_cast_for_database(o.right))
|
10
|
+
end
|
11
|
+
|
12
|
+
def visit_Arel_Nodes_ContainedBy o, collector
|
13
|
+
visit o.left, collector
|
14
|
+
collector << ' <@ '
|
15
|
+
collector << quote(o.left.type_cast_for_database(o.right))
|
16
|
+
end
|
17
|
+
|
18
|
+
def visit_Arel_Nodes_Overlaps o, collector
|
19
|
+
visit o.left, collector
|
20
|
+
collector << ' && '
|
21
|
+
collector << quote(o.left.type_cast_for_database(o.right))
|
22
|
+
end
|
23
|
+
|
24
|
+
def visit_Arel_Attributes_Key(o, collector, last_key = true)
|
25
|
+
if o.relation.is_a?(Arel::Attributes::Key)
|
26
|
+
visit_Arel_Attributes_Key(o.relation, collector, false)
|
27
|
+
if last_key
|
28
|
+
collector << o.name.to_s
|
29
|
+
collector << "}'"
|
30
|
+
else
|
31
|
+
collector << o.name.to_s
|
32
|
+
collector << "."
|
33
|
+
end
|
34
|
+
else
|
35
|
+
visit(o.relation, collector)
|
36
|
+
collector << "\#>>'{" << o.name.to_s
|
37
|
+
if !last_key
|
38
|
+
collector << "."
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
metadata
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: arel-extensions
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jon Bracy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-06 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: arel
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 7.0.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 7.0.0
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: minitest
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description:
|
56
|
+
email:
|
57
|
+
- jonbracy@gmail.com
|
58
|
+
executables: []
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- LICENSE
|
63
|
+
- README.md
|
64
|
+
- arel-extensions.gemspec
|
65
|
+
- lib/arel/array_predications.rb
|
66
|
+
- lib/arel/attributes/key.rb
|
67
|
+
- lib/arel/extensions.rb
|
68
|
+
- lib/arel/json_predications.rb
|
69
|
+
- lib/arel/nodes/contains.rb
|
70
|
+
- lib/arel/nodes/has_any_key.rb
|
71
|
+
- lib/arel/nodes/has_key.rb
|
72
|
+
- lib/arel/nodes/has_keys.rb
|
73
|
+
- lib/arel/nodes/overlaps.rb
|
74
|
+
- lib/arel/visitors/postgresql_extensions.rb
|
75
|
+
homepage: https://github.com/malomalo/arel-extensions
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
metadata: {}
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 2.5.1
|
96
|
+
signing_key:
|
97
|
+
specification_version: 4
|
98
|
+
summary: Adds support for missing SQL operators and functions to Arel
|
99
|
+
test_files: []
|