arel-extensions 6.0.0.5 → 6.0.0.6

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 77163aa72e10eb31450da65c1b1df14a021e5b4075fb4593d5fef7bcc99b5601
4
- data.tar.gz: 6f3c923426a618ff4cab75573a9249f5ff96f03ce270fa4f70218815df617fed
3
+ metadata.gz: b8b1c993b347393ad06a933f8ab1c8b1e315d7f39c5921ad21c995538a3fc64c
4
+ data.tar.gz: 32e7728efa400fd618557a39ddabdb4b4e2ec01fbb8e220053d2e6f228a103c2
5
5
  SHA512:
6
- metadata.gz: 6b4ba6222a1324e349ee69e4f6463f5fa964b4f965291db74712876749af64ddc77fe957c38fd2081cfcbf7263440989aa5230708a69ce6562a76417a131eef3
7
- data.tar.gz: 448a6441598e3a7648df5f9e261b52840988ad1d0ac2836eecfbd45110a1d2918033622702261efd7cf9b6ca604e9d130cc878e6f34dc5a20032e21700c3e610
6
+ metadata.gz: 7d35be931c9fa7e39f1265b11851d034da64d49f8e2c30d457208dcc4d66991bec244590087bd20ff0127cb8a12966fa654a7cf78ad881280031215f0baa1c7d
7
+ data.tar.gz: 0eb34be84a36821aaa96ef5a15e0de64d703194c1764c37981fb862952683cfb56218c12ce4be81bdf977c118dcc6560a40fce9be68413cb99385ed057730f52
data/.travis.yml CHANGED
@@ -13,12 +13,9 @@ rvm:
13
13
 
14
14
  env:
15
15
  matrix:
16
- - RAILS_VERSION=v6.0.0.rc1 GEM=activerecord:mysql2
17
- - RAILS_VERSION=v6.0.0.rc1 GEM=activerecord:sqlite3
18
- - RAILS_VERSION=v6.0.0.rc1 GEM=activerecord:postgresql
19
- - RAILS_VERSION=v6.0.0.rc2 GEM=activerecord:mysql2
20
- - RAILS_VERSION=v6.0.0.rc2 GEM=activerecord:sqlite3
21
- - RAILS_VERSION=v6.0.0.rc2 GEM=activerecord:postgresql
16
+ - RAILS_VERSION=v6.0.0 GEM=activerecord:mysql2
17
+ - RAILS_VERSION=v6.0.0 GEM=activerecord:sqlite3
18
+ - RAILS_VERSION=v6.0.0 GEM=activerecord:postgresql
22
19
 
23
20
  services:
24
21
  - mysql
data/Gemfile.lock CHANGED
@@ -18,9 +18,15 @@ GEM
18
18
  minitest (~> 5.1)
19
19
  tzinfo (~> 1.1)
20
20
  zeitwerk (~> 2.1, >= 2.1.8)
21
+ addressable (2.7.0)
22
+ public_suffix (>= 2.0.2, < 5.0)
21
23
  ansi (1.5.0)
22
24
  builder (3.2.3)
23
25
  concurrent-ruby (1.1.5)
26
+ cookie_store (0.1.4)
27
+ crack (0.4.3)
28
+ safe_yaml (~> 1.0.0)
29
+ hashdiff (1.0.0)
24
30
  i18n (1.6.0)
25
31
  concurrent-ruby (~> 1.0)
26
32
  minitest (5.11.3)
@@ -29,13 +35,24 @@ GEM
29
35
  builder
30
36
  minitest (>= 5.0)
31
37
  ruby-progressbar
38
+ msgpack (1.3.1)
32
39
  pg (1.1.4)
40
+ public_suffix (4.0.1)
33
41
  rake (12.3.3)
34
42
  rgeo (2.1.0)
35
43
  ruby-progressbar (1.10.1)
44
+ safe_yaml (1.0.5)
45
+ sunstone (6.0.0.5)
46
+ activerecord (>= 6.0.0.rc1)
47
+ cookie_store
48
+ msgpack
36
49
  thread_safe (0.3.6)
37
50
  tzinfo (1.2.5)
38
51
  thread_safe (~> 0.1)
52
+ webmock (3.7.6)
53
+ addressable (>= 2.3.6)
54
+ crack (>= 0.3.2)
55
+ hashdiff (>= 0.4.0, < 2.0.0)
39
56
  zeitwerk (2.1.10)
40
57
 
41
58
  PLATFORMS
@@ -49,6 +66,8 @@ DEPENDENCIES
49
66
  pg
50
67
  rake
51
68
  rgeo
69
+ sunstone
70
+ webmock
52
71
 
53
72
  BUNDLED WITH
54
73
  1.17.3
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'arel-extensions'
3
- gem.version = '6.0.0.5'
3
+ gem.version = '6.0.0.6'
4
4
  gem.authors = ["Jon Bracy"]
5
5
  gem.email = ["jonbracy@gmail.com"]
6
6
  gem.summary = %q{Adds support for missing SQL operators and functions to Arel}
@@ -17,6 +17,8 @@ Gem::Specification.new do |gem|
17
17
  gem.add_development_dependency "rake"
18
18
  gem.add_development_dependency 'minitest'
19
19
  gem.add_development_dependency 'minitest-reporters'
20
+ gem.add_development_dependency "sunstone"
21
+ gem.add_development_dependency "webmock"
20
22
  gem.add_development_dependency 'pg'
21
23
  gem.add_development_dependency 'rgeo'
22
24
 
@@ -0,0 +1,14 @@
1
+ module Arel
2
+ module Nodes
3
+ class Ascending < Ordering
4
+
5
+ attr_accessor :nulls
6
+
7
+ def initialize expr, nulls=nil
8
+ super(expr)
9
+ @nulls = nulls
10
+ end
11
+
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,15 @@
1
+ module Arel
2
+ module Nodes
3
+ class Descending < Ordering
4
+
5
+ attr_accessor :nulls
6
+
7
+ def initialize expr, nulls=nil
8
+ super(expr)
9
+ @nulls = nulls
10
+ end
11
+
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,14 @@
1
+ # Ordering with :nulls_last, :nulls_first options
2
+ module Arel
3
+ module OrderPredications
4
+
5
+ def asc(nulls=nil)
6
+ Nodes::Ascending.new self, nulls
7
+ end
8
+
9
+ def desc(nulls=nil)
10
+ Nodes::Descending.new self, nulls
11
+ end
12
+
13
+ end
14
+ end
@@ -9,6 +9,11 @@ require File.expand_path('../nodes/contained_by', __FILE__)
9
9
  require File.expand_path('../array_predications', __FILE__)
10
10
  Arel::Attributes::Attribute.include(Arel::ArrayPredications)
11
11
 
12
+ require File.expand_path('../nodes/random', __FILE__)
13
+ require File.expand_path(File.join(__FILE__, '../../../ext/arel/nodes/ascending'))
14
+ require File.expand_path(File.join(__FILE__, '../../../ext/arel/nodes/descending'))
15
+ require File.expand_path(File.join(__FILE__, '../../../ext/arel/order_predications'))
16
+
12
17
 
13
18
  require File.expand_path('../attributes/key', __FILE__)
14
19
  require File.expand_path('../attributes/cast', __FILE__)
@@ -0,0 +1,7 @@
1
+ module Arel
2
+ module Nodes
3
+ class RandomOrdering < Arel::Nodes::Node
4
+
5
+ end
6
+ end
7
+ end
@@ -8,6 +8,26 @@ module Arel
8
8
  super
9
9
  end
10
10
 
11
+ def visit_Arel_Nodes_Ascending o, collector
12
+ case o.nulls
13
+ when :nulls_first then visit(o.expr, collector) << ' ASC NULLS FIRST'
14
+ when :nulls_last then visit(o.expr, collector) << ' ASC NULLS LAST'
15
+ else visit(o.expr, collector) << ' ASC'
16
+ end
17
+ end
18
+
19
+ def visit_Arel_Nodes_Descending o, collector
20
+ case o.nulls
21
+ when :nulls_first then visit(o.expr, collector) << ' DESC NULLS FIRST'
22
+ when :nulls_last then visit(o.expr, collector) << ' DESC NULLS LAST'
23
+ else visit(o.expr, collector) << ' DESC'
24
+ end
25
+ end
26
+
27
+ def visit_Arel_Nodes_RandomOrdering o, collector
28
+ collector << "RANDOM()"
29
+ end
30
+
11
31
  def visit_Arel_Nodes_Contains o, collector
12
32
  visit o.left, collector
13
33
  collector << ' @> '
@@ -3,12 +3,52 @@ module Arel
3
3
  class Sunstone
4
4
  private
5
5
 
6
+ def visit_Arel_Nodes_Ascending o, collector
7
+ hash = visit(o.expr, collector)
8
+
9
+ case o.nulls
10
+ when :nulls_first
11
+ add_to_bottom_of_hash_or_array(hash, {asc: :nulls_first})
12
+ when :nulls_last
13
+ add_to_bottom_of_hash_or_array(hash, {asc: :nulls_last})
14
+ else
15
+ add_to_bottom_of_hash_or_array(hash, :asc)
16
+ end
17
+
18
+ hash
19
+ end
20
+
21
+ def visit_Arel_Nodes_Descending o, collector
22
+ hash = visit(o.expr, collector)
23
+
24
+ case o.nulls
25
+ when :nulls_first
26
+ add_to_bottom_of_hash_or_array(hash, {desc: :nulls_first})
27
+ when :nulls_last
28
+ add_to_bottom_of_hash_or_array(hash, {desc: :nulls_last})
29
+ else
30
+ add_to_bottom_of_hash_or_array(hash, :desc)
31
+ end
32
+
33
+ hash
34
+ end
35
+
36
+ def visit_Arel_Nodes_RandomOrdering o, collector
37
+ :random
38
+ end
39
+
6
40
  def visit_Hash o, collector
7
- value = {}
41
+ rvalue = {}
8
42
  o.each do |key, value|
9
- value[visit(key, collector)] = visit(value, collector)
43
+ rvalue[visit(key, collector)] = visit(value, collector)
10
44
  end
11
- value
45
+ rvalue
46
+ end
47
+
48
+ alias :visit_String :literal
49
+
50
+ def visit_Symbol o, collector
51
+ o.to_s
12
52
  end
13
53
 
14
54
  def visit_Arel_Nodes_Contains o, collector
data/test/database.rb CHANGED
@@ -29,13 +29,23 @@ ActiveRecord::Migration.suppress_messages do
29
29
  end
30
30
 
31
31
  class Address < ActiveRecord::Base
32
-
33
32
  belongs_to :property
34
-
35
33
  end
36
34
 
37
35
  class Property < ActiveRecord::Base
38
-
39
36
  has_many :addresses
37
+ end
38
+
39
+ class SunstoneRecord < ActiveRecord::Base
40
+ self.abstract_class = true
41
+ end
42
+
43
+ class SunstoneAddress < SunstoneRecord
44
+ belongs_to :property, class_name: 'SunstoneProperty'
45
+ end
46
+
47
+ class SunstoneProperty < SunstoneRecord
48
+ has_many :addresses, class_name: 'SunstoneAddress'
49
+ end
40
50
 
41
- end
51
+ SunstoneRecord.establish_connection(adapter: 'sunstone', url: 'http://example.com')
@@ -0,0 +1,47 @@
1
+ require 'test_helper'
2
+
3
+ class OrderTest < ActiveSupport::TestCase
4
+
5
+ test '::order(column.asc)' do
6
+ assert_sql(<<~SQL, Property.order(Property.arel_table[:id].asc))
7
+ SELECT "properties".* FROM "properties" ORDER BY "properties"."id" ASC
8
+ SQL
9
+ end
10
+
11
+ test '::order(column1.asc, column2.asc)' do
12
+ assert_sql(<<~SQL, Property.order(Property.arel_table[:id].asc, Property.arel_table[:name].asc))
13
+ SELECT "properties".* FROM "properties" ORDER BY "properties"."id" ASC, "properties"."name" ASC
14
+ SQL
15
+ end
16
+
17
+ test '::order(column.desc)' do
18
+ assert_sql(<<~SQL, Property.order(Property.arel_table[:id].desc))
19
+ SELECT "properties".* FROM "properties" ORDER BY "properties"."id" DESC
20
+ SQL
21
+ end
22
+
23
+ test '::order(column.asc(:nulls_first))' do
24
+ assert_sql(<<~SQL, Property.order(Property.arel_table[:id].asc(:nulls_first)))
25
+ SELECT "properties".* FROM "properties" ORDER BY "properties"."id" ASC NULLS FIRST
26
+ SQL
27
+ end
28
+
29
+ test '::order(column.asc(:nulls_last))' do
30
+ assert_sql(<<~SQL, Property.order(Property.arel_table[:id].asc(:nulls_last)))
31
+ SELECT "properties".* FROM "properties" ORDER BY "properties"."id" ASC NULLS LAST
32
+ SQL
33
+ end
34
+
35
+ test '::order(column.desc(:nulls_first))' do
36
+ assert_sql(<<~SQL, Property.order(Property.arel_table[:id].desc(:nulls_first)))
37
+ SELECT "properties".* FROM "properties" ORDER BY "properties"."id" DESC NULLS FIRST
38
+ SQL
39
+ end
40
+
41
+ test '::order(column.desc(:nulls_last))' do
42
+ assert_sql(<<~SQL, Property.order(Property.arel_table[:id].desc(:nulls_last)))
43
+ SELECT "properties".* FROM "properties" ORDER BY "properties"."id" DESC NULLS LAST
44
+ SQL
45
+ end
46
+
47
+ end
@@ -27,8 +27,11 @@ class SunstoneTest < ActiveSupport::TestCase
27
27
  # end
28
28
 
29
29
  test "::filter json_column: {contains: JSON_HASH}" do
30
- query = Property.where(Property.arel_attribute('metadata').contains({json: 'string'}))
31
- assert_equal '', query.to_sar.path
30
+ query = SunstoneProperty.where(SunstoneProperty.arel_attribute('metadata').contains({json: 'string'}))
31
+ assert_sar(query, 'GET', '/sunstone_properties', {
32
+ where: {metadata: {contains: { json: 'string' }}}
33
+ })
34
+
32
35
  # query = Property.where(metadata: {contains: {json: 'string'}})
33
36
  # assert_equal(<<-SQL.strip.gsub(/\s+/, ' '), query.to_sql.strip)
34
37
  # SELECT "properties".*
data/test/test_helper.rb CHANGED
@@ -12,11 +12,13 @@ require 'rgeo'
12
12
  require "minitest/autorun"
13
13
  require 'minitest/unit'
14
14
  require 'minitest/reporters'
15
- # require 'webmock/minitest'
15
+ require 'webmock/minitest'
16
16
  # require 'mocha/minitest'
17
17
  require 'active_record'
18
+ require 'sunstone'
18
19
  require 'arel/extensions'
19
20
 
21
+
20
22
  # Setup the test db
21
23
  ActiveSupport.test_order = :random
22
24
  require File.expand_path('../database', __FILE__)
@@ -27,7 +29,7 @@ $debugging = false
27
29
 
28
30
  # File 'lib/active_support/testing/declarative.rb', somewhere in rails....
29
31
  class ActiveSupport::TestCase
30
- # include WebMock::API
32
+ include WebMock::API
31
33
 
32
34
  # File 'lib/active_support/testing/declarative.rb'
33
35
  def self.test(name, &block)
@@ -54,6 +56,51 @@ class ActiveSupport::TestCase
54
56
  end
55
57
  end
56
58
  end
59
+
60
+ def setup
61
+ sunstone_schema = {
62
+ addresses: {
63
+ columns: {
64
+ id: { type: :integer, primary_key: true, null: false, array: false },
65
+ name: { type: :string, primary_key: false, null: true, array: false },
66
+ property_id: { type: :integer, primary_key: false, null: true, array: false }
67
+ }
68
+ },
69
+ properties: {
70
+ columns: {
71
+ id: { type: :integer, primary_key: true, null: false, array: false },
72
+ name: { type: :string, primary_key: false, null: true, array: false },
73
+ metadata: { type: :json, primary_key: false, null: true, array: false }
74
+ }
75
+ }
76
+ }
77
+
78
+ req_stub = stub_request(:get, /^http:\/\/example.com/).with do |req|
79
+ case req.uri.path
80
+ when '/tables'
81
+ true
82
+ when /^\/\w+\/schema$/i
83
+ true
84
+ else
85
+ false
86
+ end
87
+ end
88
+
89
+ req_stub.to_return do |req|
90
+ case req.uri.path
91
+ when '/tables'
92
+ {
93
+ body: sunstone_schema.keys.to_json,
94
+ headers: { 'StandardAPI-Version' => '5.0.0.5' }
95
+ }
96
+ when /^\/(\w+)\/schema$/i
97
+ {
98
+ body: sunstone_schema[$1.to_sym].to_json,
99
+ headers: { 'StandardAPI-Version' => '5.0.0.5' }
100
+ }
101
+ end
102
+ end
103
+ end
57
104
 
58
105
  def debug
59
106
  ActiveRecord::Base.logger = Logger.new(STDOUT)
@@ -112,6 +159,33 @@ class ActiveSupport::TestCase
112
159
  end
113
160
  ActiveSupport::Notifications.subscribe('sql.active_record', SQLLogger.new)
114
161
 
162
+ def deep_transform_query(object)
163
+ case object
164
+ when Hash
165
+ object.each_with_object({}) do |(key, value), result|
166
+ result[key.to_s] = deep_transform_query(value)
167
+ end
168
+ when Array
169
+ object.map {|e| deep_transform_query(e) }
170
+ when Symbol
171
+ object.to_s
172
+ else
173
+ object
174
+ end
175
+ end
176
+
177
+ def assert_sar(query, method, path, query_params = {}, body = nil)
178
+ sar = query.to_sar
179
+
180
+ assert_equal method, sar.method
181
+ assert_equal path, sar.path.split('?').first
182
+ assert_equal deep_transform_query(query_params), MessagePack.unpack(CGI::unescape(sar.path.split('?').last))
183
+ assert_equal body, sar.body
184
+ end
185
+
186
+ def assert_sql(expected, query)
187
+ assert_equal expected.strip, query.to_sql.strip.gsub(/\s+/, ' ')
188
+ end
115
189
  # test/unit backwards compatibility methods
116
190
  alias :assert_raise :assert_raises
117
191
  alias :assert_not_empty :refute_empty
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arel-extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.0.0.5
4
+ version: 6.0.0.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Bracy
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-09-18 00:00:00.000000000 Z
11
+ date: 2019-10-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -80,6 +80,34 @@ dependencies:
80
80
  - - ">="
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: sunstone
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: webmock
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: pg
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -123,6 +151,9 @@ files:
123
151
  - README.md
124
152
  - Rakefile
125
153
  - arel-extensions.gemspec
154
+ - ext/arel/nodes/ascending.rb
155
+ - ext/arel/nodes/descending.rb
156
+ - ext/arel/order_predications.rb
126
157
  - lib/active_record/query_methods.rb
127
158
  - lib/arel/array_predications.rb
128
159
  - lib/arel/attributes/cast.rb
@@ -138,6 +169,7 @@ files:
138
169
  - lib/arel/nodes/has_keys.rb
139
170
  - lib/arel/nodes/hex_encoded_binary.rb
140
171
  - lib/arel/nodes/overlaps.rb
172
+ - lib/arel/nodes/random.rb
141
173
  - lib/arel/nodes/relation.rb
142
174
  - lib/arel/nodes/ts_match.rb
143
175
  - lib/arel/nodes/ts_query.rb
@@ -150,6 +182,7 @@ files:
150
182
  - lib/arel/visitors/sunstone_extensions.rb
151
183
  - lib/arel/visitors/to_sql_extensions.rb
152
184
  - test/database.rb
185
+ - test/order_test.rb
153
186
  - test/sunstone_test.rb
154
187
  - test/test_helper.rb
155
188
  - test/ts_test.rb
@@ -178,6 +211,7 @@ specification_version: 4
178
211
  summary: Adds support for missing SQL operators and functions to Arel
179
212
  test_files:
180
213
  - test/database.rb
214
+ - test/order_test.rb
181
215
  - test/sunstone_test.rb
182
216
  - test/test_helper.rb
183
217
  - test/ts_test.rb