arel-extensions 6.0.0 → 6.0.0.8

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: a2e57daa4864ca189927f6f4197009f057ce83d6cc4a1f12d7fd12e20a63ac68
4
- data.tar.gz: 39d7ab6d734005b482dd04f1e03c1e8b71b5a463d2c35b9cec3a71d46bf84b20
3
+ metadata.gz: 87c1e3d344cef64601be578c9efa5e05ca8a0fb2a0443cb81f586c06a3e1009f
4
+ data.tar.gz: 361a92b9257df496481556ccb63f78e399168dc021a5461f5a3b5b4e324a401e
5
5
  SHA512:
6
- metadata.gz: 4fbf0b2cdd5c76f856b027495b46ca5084dbadd5e1e0a5bcad2ab62de4fa0915a1453ee63ee35b4de397aa9fd1cdc214d10a2586025be6656cc985ed43468996
7
- data.tar.gz: d438b922e697b704c58a22734b647c7027defbf53cce02502ec52a3753fe8417cdf17976e1e956bc7c1e63eb7be0c7b2e8dbc4d5ca87ccd4cf4d1ce805567a03
6
+ metadata.gz: 4e83c72da829bf31e4113d777f4cede440c1ecb8d3ad7c552225978788956af72030c669b782aa935cc4945990bb02449c224e582643ed8e88694d4b439a1995
7
+ data.tar.gz: ade28f1b9fad88a81eeeb0d25a7a3608900c802858f0579a9f0713dd68a655433ce2c2f4504939c83600db20e77e4a28995feb2bd0db2573772c4ba762f00372
data/.gitignore CHANGED
@@ -1 +1,3 @@
1
1
  .DS_Store
2
+ *.gem
3
+ Gemfile.lock
@@ -8,14 +8,13 @@ cache:
8
8
  - /home/travis/.rvm/gems
9
9
 
10
10
  rvm:
11
- - 2.5
12
11
  - 2.6
13
12
 
14
13
  env:
15
14
  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
15
+ - RAILS_VERSION=v6.0.3.1 GEM=activerecord:mysql2
16
+ - RAILS_VERSION=v6.0.3.1 GEM=activerecord:sqlite3
17
+ - RAILS_VERSION=v6.0.3.1 GEM=activerecord:postgresql
19
18
 
20
19
  services:
21
20
  - mysql
@@ -26,6 +25,7 @@ before_install:
26
25
  - unset BUNDLE_GEMFILE
27
26
  - gem update --system
28
27
  - gem update bundler
28
+ - gem install bundler -v 1.17.3
29
29
 
30
30
  install:
31
31
  - git clone https://github.com/rails/rails.git ~/build/rails
@@ -37,7 +37,7 @@ install:
37
37
  - "sed -i \"/group :db do/a gem 'arel-extensions', require: 'arel/extensions', path: File.expand_path\\('~\\/build\\/malomalo\\/arel-extensions'\\)\" ~/build/rails/Gemfile"
38
38
  - sed -i "/rb-inotify/d" ~/build/rails/Gemfile
39
39
  - cat ~/build/rails/Gemfile
40
- - bundle install --jobs=3 --retry=3
40
+ - bundle install --jobs=3 --retry=3 --full-index
41
41
  - popd
42
42
 
43
43
  script:
@@ -1,7 +1,6 @@
1
1
  Gem::Specification.new do |gem|
2
2
  gem.name = 'arel-extensions'
3
- gem.version = '6.0.0'
4
-
3
+ gem.version = '6.0.0.8'
5
4
  gem.authors = ["Jon Bracy"]
6
5
  gem.email = ["jonbracy@gmail.com"]
7
6
  gem.summary = %q{Adds support for missing SQL operators and functions to Arel}
@@ -12,12 +11,14 @@ Gem::Specification.new do |gem|
12
11
  gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
13
12
  gem.require_paths = ["lib"]
14
13
 
15
- gem.add_dependency 'activerecord', '>= 6.0.0.rc1'
14
+ gem.add_dependency 'activerecord', '>= 6.0.0'
16
15
 
17
16
  gem.add_development_dependency "bundler"
18
17
  gem.add_development_dependency "rake"
19
18
  gem.add_development_dependency 'minitest'
20
19
  gem.add_development_dependency 'minitest-reporters'
20
+ gem.add_development_dependency "sunstone"
21
+ gem.add_development_dependency "webmock"
21
22
  gem.add_development_dependency 'pg'
22
23
  gem.add_development_dependency 'rgeo'
23
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__)
@@ -26,6 +31,7 @@ require File.expand_path('../nodes/ts_rank_cd', __FILE__)
26
31
  require File.expand_path('../ts_predications', __FILE__)
27
32
  Arel::Attributes::Attribute.include(Arel::TSPredications)
28
33
 
34
+ require File.expand_path('../nodes/relation', __FILE__)
29
35
 
30
36
  require File.expand_path('../gis_predications', __FILE__)
31
37
  Arel::Attributes::Attribute.include(Arel::GISPredications)
@@ -38,4 +44,8 @@ end
38
44
 
39
45
  if defined?(Arel::Visitors::Sunstone)
40
46
  require File.expand_path('../visitors/sunstone_extensions', __FILE__)
47
+ end
48
+
49
+ if defined?(Arel::Visitors::ToSql)
50
+ require File.expand_path('../visitors/to_sql_extensions', __FILE__)
41
51
  end
@@ -0,0 +1,7 @@
1
+ module Arel
2
+ module Nodes
3
+ class RandomOrdering < Arel::Nodes::Node
4
+
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,35 @@
1
+ module Arel
2
+ module Attributes
3
+ class Relation < Attribute
4
+
5
+ attr_accessor :collection, :for_write
6
+
7
+ def initialize(relation, name, collection = false, for_write=false)
8
+ self[:relation] = relation
9
+ self[:name] = name
10
+ @collection = collection
11
+ @for_write = for_write
12
+ end
13
+
14
+ def able_to_type_cast?
15
+ false
16
+ end
17
+
18
+ def table_name
19
+ nil
20
+ end
21
+
22
+ def eql? other
23
+ self.class == other.class &&
24
+ self.relation == other.relation &&
25
+ self.name == other.name &&
26
+ self.collection == other.collection
27
+ end
28
+
29
+ def type_cast_for_database(value)
30
+ relation.type_cast_for_database(value)
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -2,11 +2,11 @@ module Arel
2
2
  module TSPredications
3
3
 
4
4
  def ts_query(expression, language=nil)
5
- vector = Arel::Nodes::TSVector.new(self, language)
6
- query = Arel::Nodes::TSQuery.new(expression, language)
5
+ vector = Arel::Nodes::TSVector.new(self, language: language)
6
+ query = Arel::Nodes::TSQuery.new(expression, language: language)
7
7
 
8
8
  Arel::Nodes::TSMatch.new(vector, query)
9
9
  end
10
10
 
11
11
  end
12
- end
12
+ 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 << ' @> '
@@ -2,7 +2,67 @@ module Arel
2
2
  module Visitors
3
3
  class Sunstone
4
4
  private
5
+
6
+ def visit_Arel_Nodes_Ascending o, collector
7
+ hash = visit(o.expr, collector)
8
+
9
+ value = case o.nulls
10
+ when :nulls_first
11
+ {asc: :nulls_first}
12
+ when :nulls_last
13
+ {asc: :nulls_last}
14
+ else
15
+ :asc
16
+ end
17
+
18
+ if hash.is_a?(Hash)
19
+ add_to_bottom_of_hash_or_array(hash, value)
20
+ else
21
+ hash = { hash => value }
22
+ end
23
+
24
+ hash
25
+ end
26
+
27
+ def visit_Arel_Nodes_Descending o, collector
28
+ hash = visit(o.expr, collector)
29
+
30
+ value = case o.nulls
31
+ when :nulls_first
32
+ {desc: :nulls_first}
33
+ when :nulls_last
34
+ {desc: :nulls_last}
35
+ else
36
+ :desc
37
+ end
38
+
39
+ if hash.is_a?(Hash)
40
+ add_to_bottom_of_hash_or_array(hash, value)
41
+ else
42
+ hash = { hash => value }
43
+ end
44
+
45
+ hash
46
+ end
47
+
48
+ def visit_Arel_Nodes_RandomOrdering o, collector
49
+ :random
50
+ end
51
+
52
+ def visit_Hash o, collector
53
+ rvalue = {}
54
+ o.each do |key, value|
55
+ rvalue[visit(key, collector)] = visit(value, collector)
56
+ end
57
+ rvalue
58
+ end
5
59
 
60
+ alias :visit_String :literal
61
+
62
+ def visit_Symbol o, collector
63
+ o.to_s
64
+ end
65
+
6
66
  def visit_Arel_Nodes_Contains o, collector
7
67
  key = visit(o.left, collector)
8
68
  value = { contains: visit(o.right, collector) }
@@ -40,6 +100,30 @@ module Arel
40
100
  end
41
101
  end
42
102
 
103
+ def visit_Arel_Nodes_Overlaps o, collector
104
+ key = visit(o.left, collector)
105
+ value = { overlaps: o.left.type_cast_for_database(o.right) }
106
+
107
+ if key.is_a?(Hash)
108
+ add_to_bottom_of_hash_or_array(key, value)
109
+ key
110
+ else
111
+ {key => value}
112
+ end
113
+ end
114
+
115
+ def visit_Arel_Nodes_NotOverlaps o, collector
116
+ key = visit(o.left, collector)
117
+ value = { not_overlaps: o.left.type_cast_for_database(o.right) }
118
+
119
+ if key.is_a?(Hash)
120
+ add_to_bottom_of_hash_or_array(key, value)
121
+ key
122
+ else
123
+ {key => value}
124
+ end
125
+ end
126
+
43
127
  def visit_Arel_Nodes_HasKey o, collector
44
128
  key = visit(o.left, collector)
45
129
  value = {has_key: (o.right.nil? ? nil : o.right.to_s)}
@@ -64,7 +148,7 @@ module Arel
64
148
 
65
149
  def visit_Arel_Nodes_HasAnyKey o, collector
66
150
  key = visit(o.left, collector)
67
- value = {has_any_key: Array(o.right).map(&:to_s)}
151
+ value = { has_any_key: visit(Array(o.right), collector) }
68
152
 
69
153
  if key.is_a?(Hash)
70
154
  add_to_bottom_of_hash(key, value)
@@ -0,0 +1,11 @@
1
+ module Arel
2
+ module Visitors
3
+ class ToSql
4
+
5
+ def visit_Arel_Attributes_Relation(o, collector)
6
+ visit(o.relation, collector)
7
+ end
8
+
9
+ end
10
+ end
11
+ end
@@ -22,19 +22,30 @@ ActiveRecord::Migration.suppress_messages do
22
22
  create_table "properties", force: :cascade do |t|
23
23
  t.string "name", limit: 255
24
24
  t.tsvector 'vector_col'
25
+ t.jsonb 'metadata'
25
26
  end
26
27
 
27
28
  end
28
29
  end
29
30
 
30
31
  class Address < ActiveRecord::Base
31
-
32
32
  belongs_to :property
33
-
34
33
  end
35
34
 
36
35
  class Property < ActiveRecord::Base
37
-
38
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
39
50
 
40
- 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
@@ -0,0 +1,149 @@
1
+ require 'test_helper'
2
+
3
+ class SunstoneTest < ActiveSupport::TestCase
4
+
5
+ # schema do
6
+ # create_table "properties", force: :cascade do |t|
7
+ # t.jsonb 'metadata'
8
+ # end
9
+ # end
10
+
11
+ # class Property < ActiveRecord::Base
12
+ # end
13
+
14
+ # test "::filter json_column: STRING throws an error" do
15
+ # assert_raises(ActiveRecord::UnkownFilterError) do
16
+ # Property.filter(metadata: 'string').load
17
+ # end
18
+ # end
19
+
20
+ # test "::filter json_column: {eq: JSON_HASH}" do
21
+ # query = Property.where(metadata: {eq: {json: 'string'}})
22
+ # assert_equal(<<-SQL.strip.gsub(/\s+/, ' '), query.to_sql.strip)
23
+ # SELECT "properties".*
24
+ # FROM "properties"
25
+ # WHERE "properties"."metadata" = '{\"json\":\"string\"}'
26
+ # SQL
27
+ # end
28
+
29
+ test "::filter json_column: {contains: JSON_HASH}" do
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
+
35
+ # query = Property.where(metadata: {contains: {json: 'string'}})
36
+ # assert_equal(<<-SQL.strip.gsub(/\s+/, ' '), query.to_sql.strip)
37
+ # SELECT "properties".*
38
+ # FROM "properties"
39
+ # WHERE "properties"."metadata" @> '{\"json\":\"string\"}'
40
+ # SQL
41
+ end
42
+
43
+ # test "::filter json_column: {contained_by: JSON_HASH}" do
44
+ # query = Property.filter(metadata: {contained_by: {json: 'string'}})
45
+ # assert_equal(<<-SQL.strip.gsub(/\s+/, ' '), query.to_sql.strip)
46
+ # SELECT "properties".*
47
+ # FROM "properties"
48
+ # WHERE "properties"."metadata" <@ '{\"json\":\"string\"}'
49
+ # SQL
50
+ # end
51
+
52
+ # test "::filter json_column: {has_key: STRING}" do
53
+ # query = Property.filter(metadata: {has_key: 'string'})
54
+ # assert_equal(<<-SQL.strip.gsub(/\s+/, ' '), query.to_sql.strip)
55
+ # SELECT "properties".*
56
+ # FROM "properties"
57
+ # WHERE "properties"."metadata" ? 'string'
58
+ # SQL
59
+ # end
60
+
61
+ # test "::filter json_column.subkey: {eq: JSON_HASH}" do
62
+ # query = Property.filter("metadata.subkey" => {eq: 'string'})
63
+ # assert_equal(<<-SQL.strip.gsub(/\s+/, ' '), query.to_sql.strip)
64
+ # SELECT "properties".*
65
+ # FROM "properties"
66
+ # WHERE "properties"."metadata"#>'{subkey}' = 'string'
67
+ # SQL
68
+ # end
69
+
70
+ # test "::filter json_column: BOOLEAN" do
71
+ # query = Property.filter(metadata: true)
72
+ # assert_equal(<<-SQL.strip.gsub(/\s+/, ' '), query.to_sql.strip)
73
+ # SELECT "properties".*
74
+ # FROM "properties"
75
+ # WHERE "properties"."metadata" IS NOT NULL
76
+ # SQL
77
+
78
+ # query = Property.filter(metadata: "true")
79
+ # assert_equal(<<-SQL.strip.gsub(/\s+/, ' '), query.to_sql.strip)
80
+ # SELECT "properties".*
81
+ # FROM "properties"
82
+ # WHERE "properties"."metadata" IS NOT NULL
83
+ # SQL
84
+
85
+ # query = Property.filter(metadata: false)
86
+ # assert_equal(<<-SQL.strip.gsub(/\s+/, ' '), query.to_sql.strip)
87
+ # SELECT "properties".*
88
+ # FROM "properties"
89
+ # WHERE "properties"."metadata" IS NULL
90
+ # SQL
91
+
92
+ # query = Property.filter(metadata: "false")
93
+ # assert_equal(<<-SQL.strip.gsub(/\s+/, ' '), query.to_sql.strip)
94
+ # SELECT "properties".*
95
+ # FROM "properties"
96
+ # WHERE "properties"."metadata" IS NULL
97
+ # SQL
98
+ # end
99
+
100
+ test '::order(column.asc)' do
101
+ query = SunstoneProperty.order(SunstoneProperty.arel_table[:id].asc)
102
+ assert_sar(query, 'GET', '/sunstone_properties', {
103
+ order: [{ id: :asc }]
104
+ })
105
+ end
106
+
107
+ test '::order(column1.asc, column2.asc)' do
108
+ query = SunstoneProperty.order(SunstoneProperty.arel_table[:id].asc, SunstoneProperty.arel_table[:name].asc)
109
+ assert_sar(query, 'GET', '/sunstone_properties', {
110
+ order: [{ id: :asc }, { name: :asc }]
111
+ })
112
+ end
113
+
114
+ test '::order(column.desc)' do
115
+ query = SunstoneProperty.order(SunstoneProperty.arel_table[:id].desc)
116
+ assert_sar(query, 'GET', '/sunstone_properties', {
117
+ order: [{ id: :desc }]
118
+ })
119
+ end
120
+
121
+ test '::order(column.asc(:nulls_first))' do
122
+ query = SunstoneProperty.order(SunstoneProperty.arel_table[:id].asc(:nulls_first))
123
+ assert_sar(query, 'GET', '/sunstone_properties', {
124
+ order: [{ id: { asc: :nulls_first } }]
125
+ })
126
+ end
127
+
128
+ test '::order(column.asc(:nulls_last))' do
129
+ query = SunstoneProperty.order(SunstoneProperty.arel_table[:id].asc(:nulls_last))
130
+ assert_sar(query, 'GET', '/sunstone_properties', {
131
+ order: [{ id: { asc: :nulls_last } }]
132
+ })
133
+ end
134
+
135
+ test '::order(column.desc(:nulls_first))' do
136
+ query = SunstoneProperty.order(SunstoneProperty.arel_table[:id].desc(:nulls_first))
137
+ assert_sar(query, 'GET', '/sunstone_properties', {
138
+ order: [{ id: { desc: :nulls_first } }]
139
+ })
140
+ end
141
+
142
+ test '::order(column.desc(:nulls_last))' do
143
+ query = SunstoneProperty.order(SunstoneProperty.arel_table[:id].desc(:nulls_last))
144
+ assert_sar(query, 'GET', '/sunstone_properties', {
145
+ order: [{ id: { desc: :nulls_last } }]
146
+ })
147
+ end
148
+
149
+ end
@@ -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,37 @@ 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
+ if body.nil?
184
+ assert_nil sar.body
185
+ else
186
+ assert_equal body, sar.body
187
+ end
188
+ end
189
+
190
+ def assert_sql(expected, query)
191
+ assert_equal expected.strip, query.to_sql.strip.gsub(/\s+/, ' ')
192
+ end
115
193
  # test/unit backwards compatibility methods
116
194
  alias :assert_raise :assert_raises
117
195
  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
4
+ version: 6.0.0.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jon Bracy
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-05-29 00:00:00.000000000 Z
11
+ date: 2020-06-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 6.0.0.rc1
19
+ version: 6.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
- version: 6.0.0.rc1
26
+ version: 6.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: bundler
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -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
@@ -108,7 +136,7 @@ dependencies:
108
136
  - - ">="
109
137
  - !ruby/object:Gem::Version
110
138
  version: '0'
111
- description:
139
+ description:
112
140
  email:
113
141
  - jonbracy@gmail.com
114
142
  executables: []
@@ -118,11 +146,13 @@ files:
118
146
  - ".gitignore"
119
147
  - ".travis.yml"
120
148
  - Gemfile
121
- - Gemfile.lock
122
149
  - LICENSE
123
150
  - README.md
124
151
  - Rakefile
125
152
  - arel-extensions.gemspec
153
+ - ext/arel/nodes/ascending.rb
154
+ - ext/arel/nodes/descending.rb
155
+ - ext/arel/order_predications.rb
126
156
  - lib/active_record/query_methods.rb
127
157
  - lib/arel/array_predications.rb
128
158
  - lib/arel/attributes/cast.rb
@@ -138,6 +168,8 @@ files:
138
168
  - lib/arel/nodes/has_keys.rb
139
169
  - lib/arel/nodes/hex_encoded_binary.rb
140
170
  - lib/arel/nodes/overlaps.rb
171
+ - lib/arel/nodes/random.rb
172
+ - lib/arel/nodes/relation.rb
141
173
  - lib/arel/nodes/ts_match.rb
142
174
  - lib/arel/nodes/ts_query.rb
143
175
  - lib/arel/nodes/ts_rank.rb
@@ -147,14 +179,17 @@ files:
147
179
  - lib/arel/ts_predications.rb
148
180
  - lib/arel/visitors/postgresql_extensions.rb
149
181
  - lib/arel/visitors/sunstone_extensions.rb
182
+ - lib/arel/visitors/to_sql_extensions.rb
150
183
  - test/database.rb
184
+ - test/order_test.rb
185
+ - test/sunstone_test.rb
151
186
  - test/test_helper.rb
152
187
  - test/ts_test.rb
153
188
  homepage: https://github.com/malomalo/arel-extensions
154
189
  licenses:
155
190
  - MIT
156
191
  metadata: {}
157
- post_install_message:
192
+ post_install_message:
158
193
  rdoc_options: []
159
194
  require_paths:
160
195
  - lib
@@ -169,11 +204,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
169
204
  - !ruby/object:Gem::Version
170
205
  version: '0'
171
206
  requirements: []
172
- rubygems_version: 3.0.3
173
- signing_key:
207
+ rubygems_version: 3.1.2
208
+ signing_key:
174
209
  specification_version: 4
175
210
  summary: Adds support for missing SQL operators and functions to Arel
176
211
  test_files:
177
212
  - test/database.rb
213
+ - test/order_test.rb
214
+ - test/sunstone_test.rb
178
215
  - test/test_helper.rb
179
216
  - test/ts_test.rb
@@ -1,54 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- arel-extensions (6.0.0)
5
- activerecord (>= 6.0.0.rc1)
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- activemodel (6.0.0.rc1)
11
- activesupport (= 6.0.0.rc1)
12
- activerecord (6.0.0.rc1)
13
- activemodel (= 6.0.0.rc1)
14
- activesupport (= 6.0.0.rc1)
15
- activesupport (6.0.0.rc1)
16
- concurrent-ruby (~> 1.0, >= 1.0.2)
17
- i18n (>= 0.7, < 2)
18
- minitest (~> 5.1)
19
- tzinfo (~> 1.1)
20
- zeitwerk (~> 2.1, >= 2.1.4)
21
- ansi (1.5.0)
22
- builder (3.2.3)
23
- concurrent-ruby (1.1.5)
24
- i18n (1.6.0)
25
- concurrent-ruby (~> 1.0)
26
- minitest (5.11.3)
27
- minitest-reporters (1.3.5)
28
- ansi
29
- builder
30
- minitest (>= 5.0)
31
- ruby-progressbar
32
- pg (1.1.3)
33
- rake (12.3.1)
34
- rgeo (1.0.0)
35
- ruby-progressbar (1.10.0)
36
- thread_safe (0.3.6)
37
- tzinfo (1.2.5)
38
- thread_safe (~> 0.1)
39
- zeitwerk (2.1.6)
40
-
41
- PLATFORMS
42
- ruby
43
-
44
- DEPENDENCIES
45
- arel-extensions!
46
- bundler
47
- minitest
48
- minitest-reporters
49
- pg
50
- rake
51
- rgeo
52
-
53
- BUNDLED WITH
54
- 1.17.3