arel_extensions 0.9.7.3 → 0.9.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 +4 -4
- data/.rubocop.yml +40 -0
- data/.travis/sqlite3/extension-functions.sh +6 -0
- data/.travis.yml +21 -0
- data/Gemfile +14 -15
- data/README.md +14 -3
- data/Rakefile +1 -1
- data/SQL_Challenges.md +0 -2
- data/TODO +4 -1
- data/arel_extensions.gemspec +0 -1
- data/gemfiles/rails5.gemfile +2 -2
- data/gemfiles/rails5_0.gemfile +29 -0
- data/lib/arel_extensions/attributes.rb +1 -1
- data/lib/arel_extensions/boolean_functions.rb +1 -1
- data/lib/arel_extensions/common_sql_functions.rb +62 -0
- data/lib/arel_extensions/date_duration.rb +1 -1
- data/lib/arel_extensions/insert_manager.rb +1 -1
- data/lib/arel_extensions/math.rb +4 -4
- data/lib/arel_extensions/nodes/blank.rb +1 -1
- data/lib/arel_extensions/nodes/coalesce.rb +1 -1
- data/lib/arel_extensions/nodes/date_diff.rb +5 -5
- data/lib/arel_extensions/nodes/format.rb +1 -1
- data/lib/arel_extensions/nodes/function.rb +6 -6
- data/lib/arel_extensions/nodes/length.rb +1 -1
- data/lib/arel_extensions/nodes.rb +1 -1
- data/lib/arel_extensions/null_functions.rb +1 -1
- data/lib/arel_extensions/railtie.rb +1 -1
- data/lib/arel_extensions/string_functions.rb +1 -1
- data/lib/arel_extensions/tasks.rb +8 -14
- data/lib/arel_extensions/version.rb +1 -2
- data/lib/arel_extensions/visitors/ibm_db.rb +3 -3
- data/lib/arel_extensions/visitors/mssql.rb +17 -24
- data/lib/arel_extensions/visitors/mysql.rb +5 -5
- data/lib/arel_extensions/visitors/oracle.rb +32 -1
- data/lib/arel_extensions/visitors/postgresql.rb +5 -5
- data/lib/arel_extensions/visitors/sqlite.rb +35 -5
- data/lib/arel_extensions/visitors/to_sql.rb +29 -2
- data/lib/arel_extensions/visitors.rb +1 -1
- data/lib/arel_extensions.rb +3 -1
- data/test/with_ar/all_agnostic_test.rb +24 -37
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 37c0984cf29025e6a939c3c414c8adc08ed35fa2
|
4
|
+
data.tar.gz: 4344e373d9059ea8517db8f1dc8a41e9176358cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f53b62f6ab162cd2e9b36dd5989117e7faea7da8febb6c6419f42c164afd6af97a782fd3c58f4097a1a86fed470af5efff3b1615b673c6b3f914ca0c831efd9
|
7
|
+
data.tar.gz: 567ec3f76cc130715855dbb0a674b3e0a89291f1945fd100c297ba7864b3473adc25bce974af00c272786fc14f5c5630adc0b7209bc41550ef42d7628970f5be
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
AllCops:
|
2
|
+
DisabledByDefault: true
|
3
|
+
Exclude:
|
4
|
+
- "test/**/*"
|
5
|
+
|
6
|
+
Layout/EndOfLine:
|
7
|
+
Enabled: true
|
8
|
+
|
9
|
+
Layout/ExtraSpacing:
|
10
|
+
Enabled: true
|
11
|
+
|
12
|
+
Layout/SpaceAroundEqualsInParameterDefault:
|
13
|
+
Enabled: true
|
14
|
+
|
15
|
+
Layout/TrailingBlankLines:
|
16
|
+
Enabled: true
|
17
|
+
|
18
|
+
Style/CollectionMethods:
|
19
|
+
Enabled: true
|
20
|
+
|
21
|
+
Style/CommandLiteral:
|
22
|
+
Enabled: true
|
23
|
+
|
24
|
+
Style/CommentAnnotation:
|
25
|
+
Enabled: true
|
26
|
+
|
27
|
+
Style/ConditionalAssignment:
|
28
|
+
Enabled: true
|
29
|
+
|
30
|
+
Style/EmptyElse:
|
31
|
+
Enabled: true
|
32
|
+
|
33
|
+
Style/Encoding:
|
34
|
+
Enabled: true
|
35
|
+
|
36
|
+
Style/FileName:
|
37
|
+
Enabled: true
|
38
|
+
|
39
|
+
Style/MethodCallWithArgsParentheses:
|
40
|
+
Enabled: false
|
data/.travis.yml
CHANGED
@@ -5,10 +5,13 @@ cache:
|
|
5
5
|
directories:
|
6
6
|
- $ORACLE_DOWNLOAD_DIR
|
7
7
|
before_install:
|
8
|
+
- chmod +x .travis/sqlite3/extension-functions.sh
|
8
9
|
- chmod +x .travis/oracle/download.sh
|
9
10
|
- chmod +x .travis/oracle/install.sh
|
10
11
|
- chmod +x .travis/setup_accounts.sh
|
11
12
|
install:
|
13
|
+
- sudo apt-get install -y sqlite3-pcre curl
|
14
|
+
- .travis/sqlite3/extension-functions.sh
|
12
15
|
- .travis/oracle/download.sh
|
13
16
|
- .travis/oracle/install.sh
|
14
17
|
- .travis/setup_accounts.sh
|
@@ -16,6 +19,7 @@ install:
|
|
16
19
|
- bundle install
|
17
20
|
gemfile:
|
18
21
|
- gemfiles/rails4.gemfile
|
22
|
+
- gemfiles/rails5_0.gemfile
|
19
23
|
- gemfiles/rails5.gemfile
|
20
24
|
services:
|
21
25
|
- mysql
|
@@ -48,6 +52,7 @@ rvm:
|
|
48
52
|
- 2.1
|
49
53
|
- 2.2.5
|
50
54
|
- 2.3.1
|
55
|
+
- 2.4.0
|
51
56
|
- rbx-2
|
52
57
|
- jruby-9.0.5.0
|
53
58
|
- jruby-head
|
@@ -79,6 +84,10 @@ matrix:
|
|
79
84
|
jdk: openjdk7
|
80
85
|
- rvm: 2.3.1
|
81
86
|
jdk: oraclejdk7
|
87
|
+
- rvm: 2.4.0
|
88
|
+
jdk: openjdk7
|
89
|
+
- rvm: 2.4.0
|
90
|
+
jdk: oraclejdk7
|
82
91
|
- rvm: ruby-head
|
83
92
|
jdk: openjdk7
|
84
93
|
- rvm: ruby-head
|
@@ -91,9 +100,21 @@ matrix:
|
|
91
100
|
gemfile: gemfiles/rails5.gemfile
|
92
101
|
- rvm: ruby-head
|
93
102
|
gemfile: gemfiles/rails4.gemfile
|
103
|
+
- rvm: 2.0.0
|
104
|
+
gemfile: gemfiles/rails5_0.gemfile
|
105
|
+
- rvm: 2.1
|
106
|
+
gemfile: gemfiles/rails5_0.gemfile
|
107
|
+
- rvm: rbx-2
|
108
|
+
gemfile: gemfiles/rails5_0.gemfile
|
94
109
|
allow_failures:
|
95
110
|
- rvm: rbx-2
|
96
111
|
gemfile: gemfiles/rails4.gemfile
|
112
|
+
- rvm: rbx-2
|
113
|
+
gemfile: gemfiles/rails5_0.gemfile
|
114
|
+
- rvm: jruby-9.0.5.0
|
115
|
+
gemfile: gemfiles/rails5_0.gemfile
|
116
|
+
- rvm: jruby-head
|
117
|
+
gemfile: gemfiles/rails5_0.gemfile
|
97
118
|
- rvm: rbx-2
|
98
119
|
gemfile: gemfiles/rails5.gemfile
|
99
120
|
- rvm: jruby-9.0.5.0
|
data/Gemfile
CHANGED
@@ -3,21 +3,20 @@ source "https://rubygems.org"
|
|
3
3
|
gemspec
|
4
4
|
|
5
5
|
group :development, :test do
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
gem "sqlite3", :platforms => [:mri, :mswin, :x64_mingw, :mingw]
|
7
|
+
gem "mysql2", :platforms => [:mri, :mswin, :x64_mingw, :mingw]
|
8
|
+
gem "pg", :platforms => [:mri, :mingw, :x64_mingw, :mswin]
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
gem "jdbc-sqlite3", :platforms => :jruby
|
11
|
+
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
12
|
+
gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
|
13
|
+
gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
15
|
+
|
16
|
+
gem "tiny_tds", :require => false, :platforms => [:mingw, :x64_mingw, :mswin]
|
17
|
+
gem "activerecord-sqlserver-adapter", '~> 4.2.0', :platforms => [:mingw, :x64_mingw, :mswin]
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
19
|
+
gem 'activesupport', '~> 4.0'
|
20
|
+
gem 'activemodel', '~> 4.0'
|
21
|
+
gem 'activerecord', '~> 4.0'
|
22
|
+
end
|
data/README.md
CHANGED
@@ -14,6 +14,17 @@ It allows to use more advanced SQL functions for any supported RDBMS.
|
|
14
14
|
## Requirements
|
15
15
|
|
16
16
|
Arel 6 (Rails 4) or Arel 7+ (Rails 5).
|
17
|
+
[Arel Repository](http://github.com/rails/arel)
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
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:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
ArelExtensions::CommonSqlFunctions.new(ActiveRecord::Base.connection).add_sql_functions()
|
25
|
+
```
|
26
|
+
|
27
|
+
It will add common SQL features in your DB to align ti with current routines. Technically, it will execute SQL scripts from init folder.
|
17
28
|
|
18
29
|
|
19
30
|
## Examples
|
@@ -212,7 +223,7 @@ User.connection.execute(insert_manager.to_sql)
|
|
212
223
|
<td class="ok">✔</td>
|
213
224
|
</tr>
|
214
225
|
<tr>
|
215
|
-
<th class="tg-ffjm" rowspan="
|
226
|
+
<th class="tg-ffjm" rowspan="13"><div>String functions</div></th>
|
216
227
|
<td class="tg-yw4l">CONCAT<br>column + "string"</td>
|
217
228
|
<td class="ok">✔</td>
|
218
229
|
<td class="ok">✔</td>
|
@@ -234,7 +245,7 @@ User.connection.execute(insert_manager.to_sql)
|
|
234
245
|
<td class="tg-yw4l">LOCATE<br>column.locate("string")</td>
|
235
246
|
<td class="ok">✔</td>
|
236
247
|
<td class="ok">✔</td>
|
237
|
-
<td class="tg-j6lv">INSTR()</td>
|
248
|
+
<td class="tg-j6lv">INSTR() or Ruby function</td>
|
238
249
|
<td class="ok">✔</td>
|
239
250
|
<td class="tg-j6lv">CHARINDEX()</td>
|
240
251
|
<td class="ok">✔</td>
|
@@ -252,7 +263,7 @@ User.connection.execute(insert_manager.to_sql)
|
|
252
263
|
<td class="tg-yw4l">FIND_IN_SET<br>column & ("l")</td>
|
253
264
|
<td class="ok">✔</td>
|
254
265
|
<td class="ok">✔</td>
|
255
|
-
<td class="tg-orpl">
|
266
|
+
<td class="tg-orpl">Ruby function</td>
|
256
267
|
<td class="ok">✔</td>
|
257
268
|
<td class="ok">✔</td>
|
258
269
|
<td class="ok">✔</td>
|
data/Rakefile
CHANGED
data/SQL_Challenges.md
CHANGED
data/TODO
CHANGED
@@ -15,11 +15,14 @@ Code quality:
|
|
15
15
|
[](https://hakiri.io/github/faveod/arel_extensions/master)
|
16
16
|
[](https://codebeat.co/projects/github-com-faveod-arel_extensions)
|
17
17
|
|
18
|
+
TODO:
|
19
|
+
- all skips in tests
|
18
20
|
|
19
21
|
New features:
|
20
|
-
- POSIX format numbers (%.2f)
|
22
|
+
- POSIX format numbers (%.2f), dates (man 3 printf)
|
21
23
|
- easy unions
|
22
24
|
- cast, to_char
|
25
|
+
- avoid incompatible queries in PgSQL/Oracle/SQLServer when columns are used outside of group by columns (in select or order by)
|
23
26
|
|
24
27
|
Tests improvements:
|
25
28
|
- SQL Server
|
data/arel_extensions.gemspec
CHANGED
data/gemfiles/rails5.gemfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
source "https://rubygems.org"
|
2
2
|
|
3
|
-
gem 'arel', '~>
|
3
|
+
gem 'arel', '~> 8'
|
4
4
|
|
5
5
|
group :development, :test do
|
6
6
|
gem 'activesupport', '~> 5'
|
@@ -15,7 +15,7 @@ group :development, :test do
|
|
15
15
|
# gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
|
16
16
|
|
17
17
|
gem 'ruby-oci8', :platforms => [:mri, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
|
18
|
-
gem 'activerecord-oracle_enhanced-adapter', '~> 1.
|
18
|
+
gem 'activerecord-oracle_enhanced-adapter', '~> 1.8' if ENV.has_key? 'ORACLE_HOME'
|
19
19
|
|
20
20
|
# for JRuby
|
21
21
|
gem 'activerecord-jdbc-adapter', :platforms => :jruby
|
@@ -0,0 +1,29 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem 'arel', '~> 7.0'
|
4
|
+
|
5
|
+
group :development, :test do
|
6
|
+
gem 'activesupport', '~> 5.0'
|
7
|
+
gem 'activemodel', '~> 5.0'
|
8
|
+
gem 'activerecord', '~> 5.0'
|
9
|
+
|
10
|
+
gem "sqlite3", :platforms => [:mri, :mswin, :mingw]
|
11
|
+
gem "mysql2", :platforms => [:mri, :mswin, :mingw]
|
12
|
+
gem "pg", :platforms => [:mri, :mingw]
|
13
|
+
|
14
|
+
gem "tiny_tds", :platforms => [:mri, :mingw]
|
15
|
+
# gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw]
|
16
|
+
|
17
|
+
gem 'ruby-oci8', :platforms => [:mri, :mswin, :mingw] if ENV.has_key? 'ORACLE_HOME'
|
18
|
+
gem 'activerecord-oracle_enhanced-adapter', '~> 1.7' if ENV.has_key? 'ORACLE_HOME'
|
19
|
+
|
20
|
+
# for JRuby
|
21
|
+
gem 'activerecord-jdbc-adapter', :platforms => :jruby
|
22
|
+
gem "jdbc-sqlite3", :platforms => :jruby
|
23
|
+
gem "activerecord-jdbcsqlite3-adapter", :platforms => :jruby
|
24
|
+
gem "activerecord-jdbcmysql-adapter", :platforms => :jruby
|
25
|
+
gem "activerecord-jdbcpostgresql-adapter", :platforms => :jruby
|
26
|
+
gem "activerecord-jdbcmssql-adapter", :platforms => :jruby
|
27
|
+
end
|
28
|
+
|
29
|
+
gemspec :path => "../"
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module ArelExtensions
|
2
|
+
class CommonSqlFunctions
|
3
|
+
|
4
|
+
def initialize(cnx)
|
5
|
+
@cnx = cnx
|
6
|
+
if cnx && cnx.adapter_name =~ /sqlite/i && !$load_extension_disabled
|
7
|
+
begin
|
8
|
+
db = cnx.raw_connection
|
9
|
+
db.enable_load_extension(1)
|
10
|
+
db.load_extension("/usr/lib/sqlite3/pcre.so")
|
11
|
+
db.load_extension("/usr/lib/sqlite3/extension-functions.so")
|
12
|
+
db.enable_load_extension(0)
|
13
|
+
rescue => e
|
14
|
+
$load_extension_disabled = true
|
15
|
+
puts "can not load extensions #{e.inspect}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_sqlite_functions
|
21
|
+
db = @cnx.raw_connection
|
22
|
+
db.create_function("find_in_set", 1) do |func, val, list|
|
23
|
+
case list
|
24
|
+
when String
|
25
|
+
i = list.split(',').index(val.to_s)
|
26
|
+
func.result = i ? (i+1) : 0
|
27
|
+
when NilClass
|
28
|
+
func.result = nil
|
29
|
+
else
|
30
|
+
i = list.to_s.split(',').index(val.to_s)
|
31
|
+
func.result = i ? (i+1) : 0
|
32
|
+
end
|
33
|
+
end
|
34
|
+
db.create_function("instr", 1) do |func, value1, value2|
|
35
|
+
i = value1.to_s.index(value2.to_s)
|
36
|
+
func.result = i ? (i+1) : 0
|
37
|
+
end rescue "function instr already here (>= 3.8.5)"
|
38
|
+
end
|
39
|
+
|
40
|
+
def add_sql_functions(env_db = nil)
|
41
|
+
env_db ||= @cnx.adapter_name
|
42
|
+
if env_db =~ /sqlite/i
|
43
|
+
begin
|
44
|
+
add_sqlite_functions
|
45
|
+
rescue => e
|
46
|
+
puts "can not add sqlite functions #{e.inspect}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
if File.exist?("init/#{env_db}.sql")
|
50
|
+
sql = File.read("init/#{env_db}.sql")
|
51
|
+
if env_db == 'mssql'
|
52
|
+
sql.split(/^GO\s*$/).each {|str|
|
53
|
+
@cnx.execute(str.strip) unless str.blank?
|
54
|
+
}
|
55
|
+
else
|
56
|
+
@cnx.execute(sql) unless sql.blank?
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
data/lib/arel_extensions/math.rb
CHANGED
@@ -34,7 +34,7 @@ module ArelExtensions
|
|
34
34
|
other = other.to_i if other.is_a?(String)
|
35
35
|
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
36
36
|
elsif arg == :decimal || arg == :float
|
37
|
-
other = Arel.sql(other) if other.is_a?(String)
|
37
|
+
other = Arel.sql(other) if other.is_a?(String) # Arel should accept Float & BigDecimal!
|
38
38
|
Arel::Nodes::Grouping.new(Arel::Nodes::Addition.new self, other)
|
39
39
|
elsif arg == :datetime || arg == :date
|
40
40
|
ArelExtensions::Nodes::DateAdd.new [self, other]
|
@@ -44,7 +44,7 @@ module ArelExtensions
|
|
44
44
|
end
|
45
45
|
|
46
46
|
#function returns the time between two dates
|
47
|
-
#function returns the
|
47
|
+
#function returns the substraction between two ints
|
48
48
|
def -(other)
|
49
49
|
return case self.class.return_type
|
50
50
|
when :string, :text # ???
|
@@ -68,12 +68,12 @@ module ArelExtensions
|
|
68
68
|
end
|
69
69
|
when Arel::Nodes::Node, DateTime, Time, String, Date
|
70
70
|
ArelExtensions::Nodes::DateDiff.new [self, other]
|
71
|
-
when
|
71
|
+
when Integer
|
72
72
|
ArelExtensions::Nodes::DateSub.new [self, other]
|
73
73
|
end
|
74
74
|
else
|
75
75
|
case other
|
76
|
-
when
|
76
|
+
when Integer, Float, BigDecimal
|
77
77
|
Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, Arel.sql(other.to_s)))
|
78
78
|
when String
|
79
79
|
Arel::Nodes::Grouping.new(Arel::Nodes::Subtraction.new(self, Arel.sql(other)))
|
@@ -12,7 +12,7 @@ module ArelExtensions
|
|
12
12
|
case expr.first
|
13
13
|
when String
|
14
14
|
@left_node_type = :string
|
15
|
-
when Integer,
|
15
|
+
when Integer, Float
|
16
16
|
@left_node_type = :number
|
17
17
|
when ArelExtensions::Nodes::Coalesce, ArelExtensions::Nodes::Function
|
18
18
|
@left_node_type = expr.first.try(:left_node_type)
|
@@ -129,14 +129,14 @@ module ArelExtensions
|
|
129
129
|
case object
|
130
130
|
when Arel::Attributes::Attribute, Arel::Nodes::Node, ActiveSupport::Duration
|
131
131
|
object
|
132
|
-
when
|
132
|
+
when Integer
|
133
133
|
object.days
|
134
134
|
when DateTime, Time, Date
|
135
|
-
raise(ArgumentError, "#{object.class} can not be converted to
|
135
|
+
raise(ArgumentError, "#{object.class} can not be converted to Integer")
|
136
136
|
when String
|
137
137
|
Arel::Nodes.build_quoted(object)
|
138
138
|
else
|
139
|
-
raise(ArgumentError, "#{object.class} can not be converted to
|
139
|
+
raise(ArgumentError, "#{object.class} can not be converted to Integer")
|
140
140
|
end
|
141
141
|
end
|
142
142
|
end
|
@@ -150,7 +150,7 @@ module ArelExtensions
|
|
150
150
|
|
151
151
|
def convert_number(object)
|
152
152
|
case object
|
153
|
-
when Arel::Attributes::Attribute, Arel::Nodes::Node,
|
153
|
+
when Arel::Attributes::Attribute, Arel::Nodes::Node, Integer
|
154
154
|
object
|
155
155
|
when String
|
156
156
|
object.to_i
|
@@ -162,4 +162,4 @@ module ArelExtensions
|
|
162
162
|
end
|
163
163
|
|
164
164
|
end
|
165
|
-
end
|
165
|
+
end
|
@@ -31,14 +31,14 @@ module ArelExtensions
|
|
31
31
|
Arel::Table.engine.connection.schema_cache.columns_hash(att.relation.table_name)[att.name.to_s].type
|
32
32
|
when ArelExtensions::Nodes::Function
|
33
33
|
att.class.return_type
|
34
|
-
else
|
35
|
-
nil
|
34
|
+
# else
|
35
|
+
# nil
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
39
39
|
def convert_to_node(object)
|
40
40
|
case object
|
41
|
-
when Arel::Attributes::Attribute, Arel::Nodes::Node,
|
41
|
+
when Arel::Attributes::Attribute, Arel::Nodes::Node, Integer
|
42
42
|
object
|
43
43
|
when DateTime, Time
|
44
44
|
Arel::Nodes.build_quoted(Date.new(object.year, object.month, object.day), self)
|
@@ -59,7 +59,7 @@ module ArelExtensions
|
|
59
59
|
case object
|
60
60
|
when Arel::Nodes::Node
|
61
61
|
object
|
62
|
-
when
|
62
|
+
when Integer
|
63
63
|
Arel::Nodes.build_quoted(object.to_s)
|
64
64
|
when Arel::Attributes::Attribute
|
65
65
|
case self.type_of_attribute(object)
|
@@ -117,7 +117,7 @@ module ArelExtensions
|
|
117
117
|
case object
|
118
118
|
when Arel::Attributes::Attribute, Arel::Nodes::Node
|
119
119
|
object
|
120
|
-
when
|
120
|
+
when Integer
|
121
121
|
object.to_i.abs
|
122
122
|
when DateTime, Date, Time, String, ActiveSupport::Duration
|
123
123
|
object.to_i.abs
|
@@ -130,4 +130,4 @@ module ArelExtensions
|
|
130
130
|
|
131
131
|
end
|
132
132
|
end
|
133
|
-
end
|
133
|
+
end
|
@@ -1 +1 @@
|
|
1
|
-
require 'arel_extensions/nodes/function'
|
1
|
+
require 'arel_extensions/nodes/function'
|
@@ -1,18 +1,12 @@
|
|
1
1
|
namespace :arel_extensions do
|
2
2
|
desc 'Install DB functions into current DB'
|
3
3
|
task :install_functions => :environment do
|
4
|
-
if ENV['DB'] == 'oracle' && ((defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx") || (RUBY_PLATFORM == 'java')) # not supported
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
if File.exist?("init/#{@env_db}.sql")
|
12
|
-
sql = File.read("init/#{@env_db}.sql")
|
13
|
-
unless sql.blank?
|
14
|
-
@cnx.execute(sql) rescue $stderr << "can't create functions\n"
|
15
|
-
end
|
16
|
-
end
|
4
|
+
@env_db = if ENV['DB'] == 'oracle' && ((defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx") || (RUBY_PLATFORM == 'java')) # not supported
|
5
|
+
(RUBY_PLATFORM == 'java' ? "jdbc-sqlite" : 'sqlite')
|
6
|
+
else
|
7
|
+
ENV['DB'] || ActiveRecord::Base.connection.adapter_name
|
8
|
+
end
|
9
|
+
ActiveRecord::Base.establish_connection(Rails.env)
|
10
|
+
CommonSqlFunctions.new(ActiveRecord::Base.connection).add_sql_functions(@env_db)
|
17
11
|
end
|
18
|
-
end
|
12
|
+
end
|
@@ -12,7 +12,7 @@ module ArelExtensions
|
|
12
12
|
def visit_ArelExtensions_Nodes_Trim o, collector
|
13
13
|
collector << "LTRIM(RTRIM("
|
14
14
|
o.expressions.each_with_index { |arg, i|
|
15
|
-
collector << Arel::Visitors::
|
15
|
+
collector << Arel::Visitors::IBM_DB::COMMA unless i == 0
|
16
16
|
collector = visit arg, collector
|
17
17
|
}
|
18
18
|
collector << "))"
|
@@ -20,7 +20,7 @@ module ArelExtensions
|
|
20
20
|
end
|
21
21
|
|
22
22
|
|
23
|
-
def visit_ArelExtensions_Nodes_DateDiff
|
23
|
+
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
24
24
|
collector << "DAY("
|
25
25
|
collector = visit o.left, collector
|
26
26
|
collector << ","
|
@@ -34,7 +34,7 @@ module ArelExtensions
|
|
34
34
|
end
|
35
35
|
|
36
36
|
|
37
|
-
def visit_ArelExtensions_Nodes_Duration o
|
37
|
+
def visit_ArelExtensions_Nodes_Duration o, collector
|
38
38
|
#visit left for period
|
39
39
|
if o.left == "d"
|
40
40
|
collector << "DAY("
|
@@ -3,12 +3,12 @@ module ArelExtensions
|
|
3
3
|
module MSSQL
|
4
4
|
Arel::Visitors::MSSQL::DATE_MAPPING = {'d' => 'day', 'm' => 'month', 'y' => 'year', 'wd' => 'weekday', 'w' => 'week', 'h' => 'hour', 'mn' => 'minute', 's' => 'second'}
|
5
5
|
Arel::Visitors::MSSQL::DATE_FORMAT_DIRECTIVES = {
|
6
|
-
'%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => '', '%b' => '', '%^b' => '',
|
7
|
-
'%d' => 'DD', '%e' => '', '%j' => '', '%w' => 'dw', '%A' => '',
|
8
|
-
'%H' => 'hh', '%k' => '', '%I' => '', '%l' => '', '%P' => '', '%p' => '',
|
6
|
+
'%Y' => 'YYYY', '%C' => '', '%y' => 'YY', '%m' => 'MM', '%B' => '', '%b' => '', '%^b' => '', # year, month
|
7
|
+
'%d' => 'DD', '%e' => '', '%j' => '', '%w' => 'dw', '%A' => '', # day, weekday
|
8
|
+
'%H' => 'hh', '%k' => '', '%I' => '', '%l' => '', '%P' => '', '%p' => '', # hours
|
9
9
|
'%M' => 'mi', '%S' => 'ss', '%L' => 'ms', '%N' => 'ns', '%z' => 'tz'
|
10
10
|
}
|
11
|
-
# TODO all others... http://www.sql-server-helper.com/tips/date-formats.aspx
|
11
|
+
# TODO; all others... http://www.sql-server-helper.com/tips/date-formats.aspx
|
12
12
|
Arel::Visitors::MSSQL::DATE_CONVERT_FORMATS = {
|
13
13
|
'YYYY-MM-DD' => 120,
|
14
14
|
'YY-MM-DD' => 120,
|
@@ -71,16 +71,16 @@ module ArelExtensions
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
74
|
-
if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
74
|
+
collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
75
|
+
'DATEDIFF(second'
|
76
|
+
else
|
77
|
+
'DATEDIFF(day'
|
78
|
+
end
|
79
79
|
collector << Arel::Visitors::MSSQL::COMMA
|
80
80
|
collector = visit o.right, collector
|
81
81
|
collector << Arel::Visitors::MSSQL::COMMA
|
82
82
|
collector = visit o.left, collector
|
83
|
-
collector <<
|
83
|
+
collector << ')'
|
84
84
|
collector
|
85
85
|
end
|
86
86
|
|
@@ -138,17 +138,13 @@ module ArelExtensions
|
|
138
138
|
end
|
139
139
|
|
140
140
|
def visit_ArelExtensions_Nodes_Substring o, collector
|
141
|
-
collector <<
|
141
|
+
collector << 'SUBSTRING('
|
142
142
|
collector = visit o.expressions[0], collector
|
143
143
|
collector << Arel::Visitors::MSSQL::COMMA
|
144
144
|
collector = visit o.expressions[1], collector
|
145
145
|
collector << Arel::Visitors::MSSQL::COMMA
|
146
|
-
|
147
|
-
|
148
|
-
else
|
149
|
-
collector = visit o.expressions[2], collector
|
150
|
-
end
|
151
|
-
collector << ")"
|
146
|
+
collector = o.expressions[2] ? visit(o.expressions[2], collector) : visit(o.expressions[0].length, collector)
|
147
|
+
collector << ')'
|
152
148
|
collector
|
153
149
|
end
|
154
150
|
|
@@ -273,8 +269,7 @@ module ArelExtensions
|
|
273
269
|
collector
|
274
270
|
end
|
275
271
|
|
276
|
-
|
277
|
-
# TODO manage case insensitivity
|
272
|
+
# TODO; manage case insensitivity
|
278
273
|
def visit_ArelExtensions_Nodes_IMatches o, collector
|
279
274
|
collector = infix_value o, collector, ' LIKE '
|
280
275
|
if o.escape
|
@@ -285,7 +280,7 @@ module ArelExtensions
|
|
285
280
|
end
|
286
281
|
end
|
287
282
|
|
288
|
-
# TODO manage case insensitivity
|
283
|
+
# TODO; manage case insensitivity
|
289
284
|
def visit_ArelExtensions_Nodes_IDoesNotMatch o, collector
|
290
285
|
collector = infix_value o, collector, ' NOT LIKE '
|
291
286
|
if o.escape
|
@@ -308,7 +303,7 @@ module ArelExtensions
|
|
308
303
|
collector
|
309
304
|
end
|
310
305
|
|
311
|
-
# TODO
|
306
|
+
# TODO;
|
312
307
|
def visit_ArelExtensions_Nodes_GroupConcat o, collector
|
313
308
|
collector << "(LISTAGG("
|
314
309
|
collector = visit o.left, collector
|
@@ -322,8 +317,6 @@ module ArelExtensions
|
|
322
317
|
collector
|
323
318
|
end
|
324
319
|
|
325
|
-
|
326
|
-
|
327
320
|
end
|
328
321
|
end
|
329
|
-
end
|
322
|
+
end
|
@@ -105,11 +105,11 @@ module ArelExtensions
|
|
105
105
|
end
|
106
106
|
|
107
107
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
108
|
-
if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
108
|
+
collector << if o.left_node_type == :ruby_time || o.left_node_type == :datetime || o.left_node_type == :time
|
109
|
+
'TIMESTAMPDIFF(SECOND, '
|
110
|
+
else
|
111
|
+
'DATEDIFF('
|
112
|
+
end
|
113
113
|
collector = visit o.right, collector
|
114
114
|
collector << Arel::Visitors::MySQL::COMMA
|
115
115
|
collector = visit o.left, collector
|
@@ -266,6 +266,7 @@ module ArelExtensions
|
|
266
266
|
collector
|
267
267
|
end
|
268
268
|
|
269
|
+
if Arel::VERSION.to_i < 7
|
269
270
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
270
271
|
table = collector.value.sub(/\AINSERT INTO/, '')
|
271
272
|
into = " INTO#{table}"
|
@@ -289,6 +290,36 @@ module ArelExtensions
|
|
289
290
|
collector << ' SELECT 1 FROM dual'
|
290
291
|
collector
|
291
292
|
end
|
293
|
+
else
|
294
|
+
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
295
|
+
table = collector.value.sub(/\AINSERT INTO/, '')
|
296
|
+
into = " INTO#{table}"
|
297
|
+
collector = Arel::Collectors::SQLString.new
|
298
|
+
collector << "INSERT ALL\n"
|
299
|
+
o.left.each_with_index do |row, idx|
|
300
|
+
collector << "#{into} VALUES ("
|
301
|
+
v = Arel::Nodes::Values.new(row, o.cols)
|
302
|
+
len = v.expressions.length - 1
|
303
|
+
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
304
|
+
case value
|
305
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
306
|
+
collector = visit value, collector
|
307
|
+
else
|
308
|
+
if attr && attr.able_to_type_cast?
|
309
|
+
collector << quote(attr.type_cast_for_database(value))
|
310
|
+
else
|
311
|
+
collector << quote(value).to_s
|
312
|
+
end
|
313
|
+
end
|
314
|
+
collector << Arel::Visitors::Oracle::COMMA unless i == len
|
315
|
+
}
|
316
|
+
collector << ')'
|
317
|
+
end
|
318
|
+
collector << ' SELECT 1 FROM dual'
|
319
|
+
collector
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
292
323
|
end
|
293
324
|
end
|
294
|
-
end
|
325
|
+
end
|
@@ -4,9 +4,9 @@ module ArelExtensions
|
|
4
4
|
Arel::Visitors::PostgreSQL::DATE_MAPPING = {'d' => 'DAY', 'm' => 'MONTH', 'w' => 'WEEK', 'y' => 'YEAR', 'wd' => 'DOW', 'h' => 'HOUR', 'mn' => 'MINUTE', 's' => 'SECOND'}
|
5
5
|
Arel::Visitors::PostgreSQL::DATE_FORMAT_DIRECTIVES = {
|
6
6
|
'%Y' => 'IYYY', '%C' => 'CC', '%y' => 'YY', '%m' => 'MM', '%B' => 'Month', '%^B' => 'MONTH', '%b' => 'Mon', '%^b' => 'MON',
|
7
|
-
'%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day',
|
8
|
-
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM',
|
9
|
-
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz'
|
7
|
+
'%d' => 'DD', '%e' => 'FMDD', '%j' => 'DDD', '%w' => '', '%A' => 'Day', # day, weekday
|
8
|
+
'%H' => 'HH24', '%k' => '', '%I' => 'HH', '%l' => '', '%P' => 'am', '%p' => 'AM', # hours
|
9
|
+
'%M' => 'MI', '%S' => 'SS', '%L' => 'MS', '%N' => 'US', '%z' => 'tz' # seconds, subseconds
|
10
10
|
}
|
11
11
|
|
12
12
|
def visit_ArelExtensions_Nodes_Rand o, collector
|
@@ -155,10 +155,10 @@ module ArelExtensions
|
|
155
155
|
def visit_ArelExtensions_Nodes_Wday o, collector
|
156
156
|
collector << "EXRTACT(DOW, "
|
157
157
|
collector = visit o.date, collector
|
158
|
-
collector <<
|
158
|
+
collector << ')'
|
159
159
|
collector
|
160
160
|
end
|
161
161
|
|
162
162
|
end
|
163
163
|
end
|
164
|
-
end
|
164
|
+
end
|
@@ -3,10 +3,10 @@ module ArelExtensions
|
|
3
3
|
Arel::Visitors::SQLite.class_eval do
|
4
4
|
Arel::Visitors::SQLite::DATE_MAPPING = {'d' => '%d', 'm' => '%m', 'w' => '%W', 'y' => '%Y', 'wd' => '%w', 'M' => '%M', 'h' => '%H', 'mn' => '%M', 's' => '%S'}
|
5
5
|
Arel::Visitors::SQLite::DATE_FORMAT_DIRECTIVES = { # ISO C / POSIX
|
6
|
-
'%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b',
|
7
|
-
'%d' => '%d', '%e' => '%e', '%j' => '%j', '%w' => '%w', '%A' => '%W',
|
8
|
-
'%H' => '%H', '%k' => '%k', '%I' => '%I', '%l' => '%l', '%P' => '%p', '%p' => '%p',
|
9
|
-
'%M' => '%M', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => ''
|
6
|
+
'%Y' => '%Y', '%C' => '', '%y' => '%y', '%m' => '%m', '%B' => '%M', '%b' => '%b', '%^b' => '%b', # year, month
|
7
|
+
'%d' => '%d', '%e' => '%e', '%j' => '%j', '%w' => '%w', '%A' => '%W', # day, weekday
|
8
|
+
'%H' => '%H', '%k' => '%k', '%I' => '%I', '%l' => '%l', '%P' => '%p', '%p' => '%p', # hours
|
9
|
+
'%M' => '%M', '%S' => '%S', '%L' => '', '%N' => '%f', '%z' => '' # seconds, subseconds
|
10
10
|
}
|
11
11
|
|
12
12
|
#String functions
|
@@ -153,6 +153,7 @@ module ArelExtensions
|
|
153
153
|
collector
|
154
154
|
end
|
155
155
|
|
156
|
+
if Arel::VERSION.to_i < 7
|
156
157
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
157
158
|
o.left.each_with_index do |row, idx|
|
158
159
|
collector << 'SELECT '
|
@@ -175,7 +176,36 @@ module ArelExtensions
|
|
175
176
|
end
|
176
177
|
collector
|
177
178
|
end
|
179
|
+
else
|
180
|
+
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
181
|
+
o.left.each_with_index do |row, idx|
|
182
|
+
collector << 'SELECT '
|
183
|
+
v = Arel::Nodes::Values.new(row, o.cols)
|
184
|
+
len = v.expressions.length - 1
|
185
|
+
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
186
|
+
case value
|
187
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
188
|
+
collector = visit value.as(attr.name), collector
|
189
|
+
else
|
190
|
+
if attr && attr.able_to_type_cast?
|
191
|
+
collector << quote(attr.type_cast_for_database(value))
|
192
|
+
else
|
193
|
+
# collector << quote(value, column_for(attr))
|
194
|
+
collector << quote(value).to_s
|
195
|
+
end
|
196
|
+
if idx == 0
|
197
|
+
collector << " AS "
|
198
|
+
collector << quote(attr.name)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
collector << Arel::Visitors::SQLite::COMMA unless i == len
|
202
|
+
}
|
203
|
+
collector << ' UNION ALL ' unless idx == o.left.length - 1
|
204
|
+
end
|
205
|
+
collector
|
206
|
+
end
|
207
|
+
end
|
178
208
|
|
179
209
|
end
|
180
210
|
end
|
181
|
-
end
|
211
|
+
end
|
@@ -335,7 +335,7 @@ module ArelExtensions
|
|
335
335
|
collector
|
336
336
|
end
|
337
337
|
|
338
|
-
|
338
|
+
if Arel::VERSION.to_i < 7
|
339
339
|
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
340
340
|
collector << "VALUES "
|
341
341
|
row_nb = o.left.length
|
@@ -356,8 +356,35 @@ module ArelExtensions
|
|
356
356
|
end
|
357
357
|
collector
|
358
358
|
end
|
359
|
+
else
|
360
|
+
def visit_ArelExtensions_InsertManager_BulkValues o, collector
|
361
|
+
collector << "VALUES "
|
362
|
+
row_nb = o.left.length
|
363
|
+
o.left.each_with_index do |row, idx|
|
364
|
+
collector << '('
|
365
|
+
v = Arel::Nodes::Values.new(row, o.cols)
|
366
|
+
len = v.expressions.length - 1
|
367
|
+
v.expressions.zip(v.columns).each_with_index { |(value, attr), i|
|
368
|
+
case value
|
369
|
+
when Arel::Nodes::SqlLiteral, Arel::Nodes::BindParam
|
370
|
+
collector = visit value, collector
|
371
|
+
else
|
372
|
+
if attr && attr.able_to_type_cast?
|
373
|
+
collector << quote(attr.type_cast_for_database(value))
|
374
|
+
else
|
375
|
+
collector << quote(value).to_s
|
376
|
+
end
|
377
|
+
end
|
378
|
+
collector << Arel::Visitors::ToSql::COMMA unless i == len
|
379
|
+
}
|
380
|
+
collector << (idx == row_nb-1 ? ')' : '), ')
|
381
|
+
end
|
382
|
+
collector
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
359
386
|
|
360
387
|
end
|
361
388
|
|
362
389
|
end
|
363
|
-
end
|
390
|
+
end
|
data/lib/arel_extensions.rb
CHANGED
@@ -42,6 +42,8 @@ require 'arel_extensions/string_functions'
|
|
42
42
|
|
43
43
|
require 'arel_extensions/insert_manager'
|
44
44
|
|
45
|
+
require 'arel_extensions/common_sql_functions'
|
46
|
+
|
45
47
|
module Arel
|
46
48
|
def self.rand
|
47
49
|
ArelExtensions::Nodes::Rand.new
|
@@ -87,4 +89,4 @@ end
|
|
87
89
|
|
88
90
|
Arel::InsertManager.class_eval do
|
89
91
|
include ArelExtensions::InsertManager
|
90
|
-
end
|
92
|
+
end
|
@@ -6,7 +6,7 @@ module ArelExtensions
|
|
6
6
|
|
7
7
|
class ListTest < Minitest::Test
|
8
8
|
require 'minitest/pride'
|
9
|
-
def
|
9
|
+
def connect_db
|
10
10
|
ActiveRecord::Base.configurations = YAML.load_file('test/database.yml')
|
11
11
|
if ENV['DB'] == 'oracle' && ((defined?(RUBY_ENGINE) && RUBY_ENGINE == "rbx") || (RUBY_PLATFORM == 'java')) # not supported
|
12
12
|
@env_db = (RUBY_PLATFORM == 'java' ? "jdbc-sqlite" : 'sqlite')
|
@@ -17,37 +17,13 @@ module ArelExtensions
|
|
17
17
|
ActiveRecord::Base.establish_connection(@env_db.try(:to_sym) || (RUBY_PLATFORM == 'java' ? :"jdbc-sqlite" : :sqlite))
|
18
18
|
ActiveRecord::Base.default_timezone = :utc
|
19
19
|
@cnx = ActiveRecord::Base.connection
|
20
|
-
$sqlite
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
db.create_function("find_in_set", 1) do |func, value1, value2|
|
28
|
-
func.result = value1.index(value2)
|
29
|
-
end
|
30
|
-
db.enable_load_extension(1)
|
31
|
-
db.load_extension("/usr/lib/sqlite3/pcre.so")
|
32
|
-
db.load_extension("/usr/lib/sqlite3/extension-functions.so")
|
33
|
-
db.enable_load_extension(0)
|
34
|
-
#function find_in_set
|
35
|
-
rescue => e
|
36
|
-
$load_extension_disabled = true
|
37
|
-
puts "can not load extensions #{e.inspect}"
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
if File.exist?("init/#{@env_db}.sql")
|
42
|
-
sql = File.read("init/#{@env_db}.sql")
|
43
|
-
if @env_db == 'mssql'
|
44
|
-
sql.split(/^GO\s*$/).each {|str|
|
45
|
-
@cnx.execute(str.strip) unless str.blank?
|
46
|
-
}
|
47
|
-
else
|
48
|
-
@cnx.execute(sql) unless sql.blank?
|
49
|
-
end
|
50
|
-
end
|
20
|
+
$sqlite = @cnx.adapter_name =~ /sqlite/i
|
21
|
+
$load_extension_disabled ||= false
|
22
|
+
csf = CommonSqlFunctions.new(@cnx)
|
23
|
+
csf.add_sql_functions(@env_db)
|
24
|
+
end
|
25
|
+
|
26
|
+
def setup_db
|
51
27
|
@cnx.drop_table(:user_tests) rescue nil
|
52
28
|
@cnx.create_table :user_tests do |t|
|
53
29
|
t.column :age, :integer
|
@@ -72,6 +48,7 @@ module ArelExtensions
|
|
72
48
|
|
73
49
|
def setup
|
74
50
|
d = Date.new(2016, 5, 23)
|
51
|
+
connect_db
|
75
52
|
setup_db
|
76
53
|
u = User.create :age => 5, :name => "Lucas", :created_at => d, :score => 20.16, :updated_at => Time.utc(2014, 3, 3, 12, 42, 0)
|
77
54
|
@lucas = User.where(:id => u.id)
|
@@ -192,12 +169,20 @@ module ArelExtensions
|
|
192
169
|
|
193
170
|
def test_substring
|
194
171
|
assert_equal 'C', t(@camille, @name.substring(1, 1))
|
195
|
-
|
172
|
+
if @env_db == 'oracle'
|
173
|
+
assert_nil(t(@lucas, @name.substring(42)))
|
174
|
+
else
|
175
|
+
assert_equal('', t(@lucas, @name.substring(42)))
|
176
|
+
end
|
196
177
|
assert_equal 'Lu', t(@lucas, @name.substring(1,2))
|
197
178
|
|
198
179
|
assert_equal 'C', t(@camille, @name[0, 1])
|
199
180
|
assert_equal 'C', t(@camille, @name[0])
|
200
|
-
|
181
|
+
if @env_db == 'oracle'
|
182
|
+
assert_nil(t(@lucas, @name[42]))
|
183
|
+
else
|
184
|
+
assert_equal('', t(@lucas, @name[42]))
|
185
|
+
end
|
201
186
|
assert_equal 'Lu', t(@lucas, @name[0,2])
|
202
187
|
assert_equal 'Lu', t(@lucas, @name[0..1])
|
203
188
|
end
|
@@ -367,9 +352,11 @@ module ArelExtensions
|
|
367
352
|
else
|
368
353
|
assert_equal 42, t(@lucas, @updated_at - Time.utc(2014, 3, 3, 12, 41, 18)).to_i
|
369
354
|
assert_equal(-3600, t(@lucas, @updated_at - Time.utc(2014, 3, 3, 13, 42)).to_i)
|
370
|
-
|
371
|
-
|
372
|
-
|
355
|
+
if @env_db == 'mssql'
|
356
|
+
assert_equal 0, @lucas.where((@updated_at - Time.utc(2014, 3, 3, 12, 41, 18)) < -1).count
|
357
|
+
else
|
358
|
+
assert_includes [nil, 0, 'f', false], t(@lucas, (@updated_at - Time.utc(2014, 3, 3, 12, 41, 18)) < -1)
|
359
|
+
end
|
373
360
|
end
|
374
361
|
end
|
375
362
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: arel_extensions
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yann Azoury
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2017-
|
13
|
+
date: 2017-06-02 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: arel
|
@@ -81,12 +81,14 @@ extra_rdoc_files:
|
|
81
81
|
- functions.html
|
82
82
|
files:
|
83
83
|
- ".gitignore"
|
84
|
+
- ".rubocop.yml"
|
84
85
|
- ".travis.yml"
|
85
86
|
- ".travis/oracle/download.js"
|
86
87
|
- ".travis/oracle/download.sh"
|
87
88
|
- ".travis/oracle/download_ojdbc.js"
|
88
89
|
- ".travis/oracle/install.sh"
|
89
90
|
- ".travis/setup_accounts.sh"
|
91
|
+
- ".travis/sqlite3/extension-functions.sh"
|
90
92
|
- Gemfile
|
91
93
|
- MIT-LICENSE.txt
|
92
94
|
- README.md
|
@@ -99,6 +101,7 @@ files:
|
|
99
101
|
- gemfiles/rails3.gemfile
|
100
102
|
- gemfiles/rails4.gemfile
|
101
103
|
- gemfiles/rails5.gemfile
|
104
|
+
- gemfiles/rails5_0.gemfile
|
102
105
|
- init/mssql.sql
|
103
106
|
- init/mysql.sql
|
104
107
|
- init/oracle.sql
|
@@ -107,6 +110,7 @@ files:
|
|
107
110
|
- lib/arel_extensions.rb
|
108
111
|
- lib/arel_extensions/attributes.rb
|
109
112
|
- lib/arel_extensions/boolean_functions.rb
|
113
|
+
- lib/arel_extensions/common_sql_functions.rb
|
110
114
|
- lib/arel_extensions/comparators.rb
|
111
115
|
- lib/arel_extensions/date_duration.rb
|
112
116
|
- lib/arel_extensions/insert_manager.rb
|