arel_extensions 1.2.5 → 1.2.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +7 -4
- data/README.md +7 -2
- data/Rakefile +23 -23
- data/arel_extensions.gemspec +1 -1
- data/functions.html +2 -2
- data/gemfiles/rails6.gemfile +30 -0
- data/gemspec_v2/arel_extensions-v2.gemspec +28 -0
- data/generate_gems.sh +13 -0
- data/lib/arel_extensions.rb +4 -1
- data/lib/arel_extensions/boolean_functions.rb +0 -2
- data/lib/arel_extensions/common_sql_functions.rb +5 -4
- data/lib/arel_extensions/insert_manager.rb +24 -24
- data/lib/arel_extensions/math.rb +3 -3
- data/lib/arel_extensions/math_functions.rb +4 -4
- data/lib/arel_extensions/nodes/case.rb +0 -2
- data/lib/arel_extensions/nodes/collate.rb +1 -1
- data/lib/arel_extensions/nodes/date_diff.rb +1 -3
- data/lib/arel_extensions/nodes/duration.rb +0 -2
- data/lib/arel_extensions/nodes/formatted_number.rb +20 -20
- data/lib/arel_extensions/nodes/json.rb +28 -30
- data/lib/arel_extensions/nodes/power.rb +5 -4
- data/lib/arel_extensions/nodes/replace.rb +23 -5
- data/lib/arel_extensions/nodes/round.rb +5 -5
- data/lib/arel_extensions/nodes/soundex.rb +14 -13
- data/lib/arel_extensions/nodes/substring.rb +8 -15
- data/lib/arel_extensions/nodes/trim.rb +1 -1
- data/lib/arel_extensions/nodes/union.rb +0 -1
- data/lib/arel_extensions/nodes/union_all.rb +0 -1
- data/lib/arel_extensions/predications.rb +16 -17
- data/lib/arel_extensions/string_functions.rb +12 -6
- data/lib/arel_extensions/tasks.rb +5 -5
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +13 -12
- data/lib/arel_extensions/visitors/mysql.rb +50 -35
- data/lib/arel_extensions/visitors/oracle.rb +7 -6
- data/lib/arel_extensions/visitors/oracle12.rb +1 -1
- data/lib/arel_extensions/visitors/postgresql.rb +45 -27
- data/lib/arel_extensions/visitors/sqlite.rb +41 -27
- data/lib/arel_extensions/visitors/to_sql.rb +18 -5
- data/test/visitors/test_bulk_insert_oracle.rb +6 -6
- data/test/visitors/test_bulk_insert_sqlite.rb +5 -5
- data/test/visitors/test_to_sql.rb +10 -2
- data/test/with_ar/all_agnostic_test.rb +44 -33
- data/test/with_ar/test_bulk_sqlite.rb +1 -1
- data/test/with_ar/test_math_sqlite.rb +1 -1
- data/test/with_ar/test_string_mysql.rb +1 -3
- data/test/with_ar/test_string_sqlite.rb +1 -5
- data/version_v1.rb +3 -0
- data/version_v2.rb +3 -0
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5292bc7a2f6bf9741b33125c301936c2effcd0b964760d42f822ca3a58bb95cb
|
4
|
+
data.tar.gz: d90202ae9fdf6d124fad15d7413f0ff20fa6c286a15d0f74252e80e59e8a1e43
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 86be4d9f4e17498047f5325f74bc62873bbdc4937bbbf3f7e353b183b91741a06170028558d828c9d48115d4b4175e31dc3df67cea4d8e4408b17e9695f08cd8
|
7
|
+
data.tar.gz: 333e52c7aeebd773e1f05c6f0ef89c33152c62e126bcbdf112bd893a4238939eebfd909ca59f1d892f30e3553eb22ca41f556fb651c0e66c4434b7bf3096e14d
|
data/.rubocop.yml
CHANGED
@@ -12,7 +12,10 @@ Layout/ExtraSpacing:
|
|
12
12
|
Layout/SpaceAroundEqualsInParameterDefault:
|
13
13
|
Enabled: true
|
14
14
|
|
15
|
-
Layout/
|
15
|
+
Layout/TrailingEmptyLines:
|
16
|
+
Enabled: true
|
17
|
+
|
18
|
+
Naming/FileName:
|
16
19
|
Enabled: true
|
17
20
|
|
18
21
|
Style/CollectionMethods:
|
@@ -33,12 +36,12 @@ Style/EmptyElse:
|
|
33
36
|
Style/Encoding:
|
34
37
|
Enabled: true
|
35
38
|
|
36
|
-
Style/FileName:
|
37
|
-
Enabled: true
|
38
|
-
|
39
39
|
Style/MethodCallWithArgsParentheses:
|
40
40
|
Enabled: false
|
41
41
|
|
42
|
+
# Performance cops have been transferred to rubocop-performance gem.
|
43
|
+
require: rubocop-performance
|
44
|
+
|
42
45
|
Performance/DoubleStartEndWith:
|
43
46
|
Enabled: true
|
44
47
|
|
data/README.md
CHANGED
@@ -19,6 +19,11 @@ It allows to use more advanced SQL functions for any supported RDBMS.
|
|
19
19
|
Arel 6 (Rails 4) or Arel 7+ (Rails 5).
|
20
20
|
[Arel Repository](http://github.com/rails/arel)
|
21
21
|
|
22
|
+
or
|
23
|
+
|
24
|
+
Rails 6
|
25
|
+
[Arel Repository](http://github.com/rails/rails)
|
26
|
+
|
22
27
|
## Usage
|
23
28
|
|
24
29
|
Most of the features will work just by adding the gem to your Gemfiles. To make sure to get all the features for any dbms, you should execute the next line as soon as you get your connection to your DB:
|
@@ -209,7 +214,7 @@ User.connection.execute(insert_manager.to_sql)
|
|
209
214
|
<td class="tg-yw4l">CEIL<br>column.ceil</td>
|
210
215
|
<td class="ok">✔</td>
|
211
216
|
<td class="ok">✔</td>
|
212
|
-
<td class="tg-j6lv">CASE +
|
217
|
+
<td class="tg-j6lv">CASE + CAST</td>
|
213
218
|
<td class="ok">✔</td>
|
214
219
|
<td class="tg-j6lv">CEILING()</td>
|
215
220
|
<td class="tg-j6lv">CEILING()</td>
|
@@ -218,7 +223,7 @@ User.connection.execute(insert_manager.to_sql)
|
|
218
223
|
<td class="tg-yw4l">FLOOR<br>column.floor</td>
|
219
224
|
<td class="ok">✔</td>
|
220
225
|
<td class="ok">✔</td>
|
221
|
-
<td class="tg-j6lv">CASE +
|
226
|
+
<td class="tg-j6lv">CASE + CAST</td>
|
222
227
|
<td class="ok">✔</td>
|
223
228
|
<td class="ok">✔</td>
|
224
229
|
<td class="ok">✔</td>
|
data/Rakefile
CHANGED
@@ -7,33 +7,33 @@ desc "Default Task"
|
|
7
7
|
task default: [ :test ]
|
8
8
|
|
9
9
|
Rake::TestTask.new(:test) do |t|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
t.libs << 'lib'
|
11
|
+
t.libs << 'test'
|
12
|
+
t.pattern = 'test/**/test_*.rb'
|
13
|
+
t.warning = true
|
14
|
+
t.verbose = true
|
15
15
|
end
|
16
16
|
|
17
17
|
%w(mysql postgresql sqlite ibm_db oracle mssql).each do |adapter|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
18
|
+
namespace :test do
|
19
|
+
Rake::TestTask.new(adapter => "#{adapter}:env") { |t|
|
20
|
+
t.libs << 'lib'
|
21
|
+
t.libs << 'test'
|
22
|
+
t.pattern = 'test/with_ar/*_agnostic_test.rb'
|
23
|
+
t.warning = true
|
24
|
+
t.verbose = true
|
25
|
+
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
|
26
|
+
}
|
27
|
+
end
|
28
28
|
|
29
|
-
|
30
|
-
|
31
|
-
|
29
|
+
namespace adapter do
|
30
|
+
task :test => "test_#{adapter}"
|
31
|
+
task :isolated_test => "isolated_test_#{adapter}"
|
32
32
|
|
33
|
-
|
34
|
-
|
35
|
-
|
33
|
+
# Set the connection environment for the adapter
|
34
|
+
task(:env) { ENV['DB'] = adapter }
|
35
|
+
end
|
36
36
|
|
37
|
-
|
38
|
-
|
37
|
+
# Make sure the adapter test evaluates the env setting task
|
38
|
+
task "test_#{adapter}" => ["#{adapter}:env", "test:#{adapter}"]
|
39
39
|
end
|
data/arel_extensions.gemspec
CHANGED
data/functions.html
CHANGED
@@ -55,7 +55,7 @@
|
|
55
55
|
<td class="tg-yw4l">CEIL<br>column.ceil</td>
|
56
56
|
<td class="ok">✔</td>
|
57
57
|
<td class="ok">✔</td>
|
58
|
-
<td class="tg-j6lv">CASE +
|
58
|
+
<td class="tg-j6lv">CASE + CAST</td>
|
59
59
|
<td class="ok">✔</td>
|
60
60
|
<td class="tg-j6lv">CEILING()</td>
|
61
61
|
<td class="tg-j6lv">CEILING()</td>
|
@@ -64,7 +64,7 @@
|
|
64
64
|
<td class="tg-yw4l">FLOOR<br>column.floor</td>
|
65
65
|
<td class="ok">✔</td>
|
66
66
|
<td class="ok">✔</td>
|
67
|
-
<td class="tg-j6lv">CASE +
|
67
|
+
<td class="tg-j6lv">CASE + CAST</td>
|
68
68
|
<td class="ok">✔</td>
|
69
69
|
<td class="ok">✔</td>
|
70
70
|
<td class="ok">✔</td>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem 'rails', '~> 6.0.0'
|
4
|
+
|
5
|
+
|
6
|
+
group :development, :test do
|
7
|
+
gem 'activesupport', '~> 6.0.0'
|
8
|
+
gem 'activemodel', '~> 6.0.0'
|
9
|
+
gem 'activerecord', '~> 6.0.0'
|
10
|
+
|
11
|
+
gem "sqlite3", '~> 1.4', :platforms => [:mri, :mswin, :mingw]
|
12
|
+
gem "mysql2", '0.5.2', :platforms => [:mri, :mswin, :mingw]
|
13
|
+
gem "pg",'< 1.0.0', :platforms => [:mri, :mingw]
|
14
|
+
|
15
|
+
gem "tiny_tds", :platforms => [:mri, :mingw] if RUBY_PLATFORM =~ /windows/
|
16
|
+
gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
|
17
|
+
|
18
|
+
gem 'ruby-oci8', :platforms => [:mri, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
|
19
|
+
gem 'activerecord-oracle_enhanced-adapter', '~> 6.0.0' if ENV.has_key? 'ORACLE_HOME'
|
20
|
+
|
21
|
+
# for JRuby
|
22
|
+
gem 'activerecord-jdbc-adapter', :platforms => :jruby
|
23
|
+
gem "jdbc-sqlite3", :platforms => :jruby
|
24
|
+
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
25
|
+
gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
|
26
|
+
gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
|
27
|
+
gem "activerecord-jdbcmssql-adapter", :platforms => :jruby
|
28
|
+
end
|
29
|
+
|
30
|
+
gemspec :path => "../"
|
@@ -0,0 +1,28 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "arel_extensions/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "arel_extensions"
|
6
|
+
s.version = ArelExtensions::VERSION
|
7
|
+
s.platform = Gem::Platform::RUBY
|
8
|
+
s.authors = ["Yann Azoury", "Félix Bellanger", "Julien Delporte"]
|
9
|
+
s.email = ["yann.azoury@faveod.com", "felix.bellanger@faveod.com", "julien.delporte@faveod.com"]
|
10
|
+
s.homepage = "https://github.com/Faveod/arel-extensions"
|
11
|
+
s.description = "Adds new features to Arel"
|
12
|
+
s.summary = "Extending Arel"
|
13
|
+
s.license = 'MIT'
|
14
|
+
|
15
|
+
s.rdoc_options = ["--main", "README.md"]
|
16
|
+
s.extra_rdoc_files = ["MIT-LICENSE.txt", "README.md", 'functions.html']
|
17
|
+
|
18
|
+
# Manifest
|
19
|
+
s.files = `git ls-files`.split("\n")
|
20
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
21
|
+
s.require_paths = ["lib"]
|
22
|
+
|
23
|
+
s.add_dependency('activerecord', '>= 6.0')
|
24
|
+
|
25
|
+
s.add_development_dependency('minitest', '~> 5.9')
|
26
|
+
s.add_development_dependency('rdoc', '~> 4.0')
|
27
|
+
s.add_development_dependency('rake', '~> 12.3.3')
|
28
|
+
end
|
data/generate_gems.sh
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
gem uninstall arel_extensions
|
3
|
+
|
4
|
+
# VERSION ~> 1
|
5
|
+
cp ./version_v1.rb lib/arel_extensions/version.rb
|
6
|
+
gem build ./arel_extensions.gemspec
|
7
|
+
|
8
|
+
# VERSION ~> 2
|
9
|
+
cp ./version_v2.rb lib/arel_extensions/version.rb
|
10
|
+
cp ./gemspec_v2/arel_extensions-v2.gemspec ./tmp.gemspec
|
11
|
+
gem build ./tmp.gemspec
|
12
|
+
cp ./version_v1.rb lib/arel_extensions/version.rb
|
13
|
+
rm tmp.gemspec
|
data/lib/arel_extensions.rb
CHANGED
@@ -118,9 +118,11 @@ Arel::Nodes::Function.class_eval do
|
|
118
118
|
include ArelExtensions::NullFunctions
|
119
119
|
include ArelExtensions::Predications
|
120
120
|
|
121
|
+
alias_method :old_as, :as
|
121
122
|
def as other
|
122
123
|
Arel::Nodes::As.new(self, Arel.sql(other))
|
123
124
|
end
|
125
|
+
|
124
126
|
end
|
125
127
|
|
126
128
|
Arel::Nodes::Unary.class_eval do
|
@@ -162,7 +164,8 @@ Arel::Nodes::As.class_eval do
|
|
162
164
|
end
|
163
165
|
|
164
166
|
Arel::Table.class_eval do
|
167
|
+
alias_method :old_alias, :alias
|
165
168
|
def alias(name = "#{self.name}_2")
|
166
|
-
name.blank? ? self :
|
169
|
+
name.blank? ? self : Arel::Nodes::TableAlias.new(self,name)
|
167
170
|
end
|
168
171
|
end
|
@@ -39,6 +39,7 @@ module ArelExtensions
|
|
39
39
|
|
40
40
|
def add_sql_functions(env_db = nil)
|
41
41
|
env_db ||= @cnx.adapter_name
|
42
|
+
env_db = 'mysql' if env_db =~ /mysql/i
|
42
43
|
if env_db =~ /sqlite/i
|
43
44
|
begin
|
44
45
|
add_sqlite_functions
|
@@ -52,10 +53,10 @@ module ArelExtensions
|
|
52
53
|
sql.split(/^GO\s*$/).each {|str|
|
53
54
|
@cnx.execute(str.strip) unless str.blank?
|
54
55
|
}
|
55
|
-
elsif env_db ==
|
56
|
-
|
57
|
-
|
58
|
-
|
56
|
+
elsif env_db =='mysql'
|
57
|
+
sql.split("$$")[1..-2].each { |str|
|
58
|
+
@cnx.execute(str.strip) unless str.strip.blank?
|
59
|
+
}
|
59
60
|
else
|
60
61
|
@cnx.execute(sql) unless sql.blank?
|
61
62
|
end
|
@@ -3,31 +3,31 @@ require 'arel'
|
|
3
3
|
module ArelExtensions
|
4
4
|
module InsertManager
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
6
|
+
def bulk_insert(cols, data)
|
7
|
+
case cols.first
|
8
|
+
when String, Symbol
|
9
|
+
cols.each { |c|
|
10
|
+
@ast.columns << @ast.relation[c]
|
11
|
+
}
|
12
|
+
when Array
|
13
|
+
if String === cols.first.first
|
14
|
+
@ast.columns = cols.map {|c| [@ast.relation[c.first]] }
|
15
|
+
elsif Arel::Attributes::Attribute == cols.first.first
|
16
|
+
@ast.columns = cols
|
17
|
+
end
|
18
|
+
when NilClass
|
19
|
+
@ast.columns = @ast.relation.columns
|
20
|
+
end
|
21
|
+
self.values = BulkValues.new(@ast.columns, data)
|
22
|
+
end
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
24
|
+
class BulkValues < Arel::Nodes::Node
|
25
|
+
attr_accessor :left, :cols
|
26
|
+
def initialize(cols, values)
|
27
|
+
@left = values
|
28
|
+
@cols = cols
|
29
|
+
end
|
30
|
+
end
|
31
31
|
|
32
32
|
end
|
33
33
|
end
|
data/lib/arel_extensions/math.rb
CHANGED
@@ -24,7 +24,7 @@ module ArelExtensions
|
|
24
24
|
else
|
25
25
|
return Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
26
26
|
end
|
27
|
-
when
|
27
|
+
when ArelExtensions::Nodes::Function,ArelExtensions::Nodes::Case
|
28
28
|
return case self.return_type
|
29
29
|
when :string, :text
|
30
30
|
self.concat(other)
|
@@ -35,7 +35,7 @@ module ArelExtensions
|
|
35
35
|
else
|
36
36
|
self.concat(other)
|
37
37
|
end
|
38
|
-
when
|
38
|
+
when Arel::Nodes::Function
|
39
39
|
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
40
40
|
else
|
41
41
|
begin
|
@@ -115,7 +115,7 @@ module ArelExtensions
|
|
115
115
|
end
|
116
116
|
when Arel::Nodes::Node, DateTime, Time, String, Date
|
117
117
|
ArelExtensions::Nodes::DateDiff.new [self, other]
|
118
|
-
when
|
118
|
+
when ArelExtensions::Nodes::Duration, Integer
|
119
119
|
ArelExtensions::Nodes::DateSub.new [self, other]
|
120
120
|
else # ActiveSupport::Duration
|
121
121
|
ArelExtensions::Nodes::DateAdd.new [self, -other]
|
@@ -63,15 +63,15 @@ module ArelExtensions
|
|
63
63
|
end
|
64
64
|
|
65
65
|
# Aggregate Functions
|
66
|
-
def std opts={unbiased: true}
|
66
|
+
def std opts = {unbiased: true}
|
67
67
|
ArelExtensions::Nodes::Std.new self, opts
|
68
68
|
end
|
69
69
|
|
70
|
-
def variance opts={unbiased: true}
|
70
|
+
def variance opts = {unbiased: true}
|
71
71
|
ArelExtensions::Nodes::Variance.new self, opts
|
72
72
|
end
|
73
73
|
|
74
|
-
def sum opts={unbiased: true}
|
74
|
+
def sum opts = {unbiased: true}
|
75
75
|
ArelExtensions::Nodes::Sum.new self, opts
|
76
76
|
end
|
77
77
|
|
@@ -91,7 +91,7 @@ module ArelExtensions
|
|
91
91
|
end
|
92
92
|
|
93
93
|
# function returning a number at a specific format
|
94
|
-
def format_number format_string, locale=nil
|
94
|
+
def format_number format_string, locale = nil
|
95
95
|
begin
|
96
96
|
sprintf(format_string,0) # this line is to get the right error message if the format_string is not correct
|
97
97
|
m = /^(.*)%([ #+\-0]*)([1-9][0-9]+|[1-9]?)[.]?([0-9]*)([a-zA-Z])(.*)$/.match(format_string)
|
@@ -136,7 +136,7 @@ module ArelExtensions
|
|
136
136
|
if ArelExtensions::Nodes::Duration === v
|
137
137
|
v.with_interval = true
|
138
138
|
case v.left
|
139
|
-
when
|
139
|
+
when 'd','m','y'
|
140
140
|
Arel.sql('day')
|
141
141
|
when 'h','mn','s'
|
142
142
|
Arel.sql('second')
|
@@ -145,8 +145,6 @@ module ArelExtensions
|
|
145
145
|
else
|
146
146
|
Arel.sql(Arel::Visitors::MSSQL::DATE_MAPPING[v.left])
|
147
147
|
end
|
148
|
-
else
|
149
|
-
nil
|
150
148
|
end
|
151
149
|
end
|
152
150
|
end
|