arel-extensions 6.0.0.5 → 6.0.0.6

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 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