arel_extensions 1.3.6 → 1.3.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ruby.yml +80 -65
- data/NEWS.md +20 -3
- data/README.md +34 -9
- data/gemfiles/rails6_1.gemfile +1 -1
- data/gemfiles/rails7.gemfile +1 -1
- data/lib/arel_extensions/date_duration.rb +5 -0
- data/lib/arel_extensions/nodes/formatted_date.rb +42 -0
- data/lib/arel_extensions/version.rb +1 -1
- data/lib/arel_extensions/visitors/mssql.rb +4 -0
- data/lib/arel_extensions/visitors/mysql.rb +28 -22
- data/lib/arel_extensions/visitors/oracle.rb +4 -0
- data/lib/arel_extensions/visitors/postgresql.rb +4 -0
- data/lib/arel_extensions/visitors/to_sql.rb +20 -0
- data/test/with_ar/all_agnostic_test.rb +141 -121
- data/version_v1.rb +1 -1
- data/version_v2.rb +1 -1
- metadata +4 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6d8d074334ab5ecab7fc6b0d4d9a24180b83d4d3c9a0e7c9237d9ec567146272
|
4
|
+
data.tar.gz: 0cf4c51ebd196eb2671506f0aef243c9cd6332bb5f55eac89c77024c105390ff
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 89ae8015b86e8ead47050f5af4dba33f851d02eeafa9a8123752fb24911ae46124391fdc7e3e5f09da41f0efc092ee4b7f084b6f01572e07ab5376d507c2741c
|
7
|
+
data.tar.gz: 988bef22406e320405f71dec5ca8e666de0acc8f87bc3b67f755951788ddca7fb92b65d2e313144413c3cde2adb4363e0e87aea418dfd691889a650e2fd57166
|
data/.github/workflows/ruby.yml
CHANGED
@@ -13,19 +13,21 @@ jobs:
|
|
13
13
|
fail-fast: false
|
14
14
|
matrix:
|
15
15
|
versions: [
|
16
|
-
{ruby: 3.
|
17
|
-
{ruby: 3.
|
18
|
-
{ruby: 3.
|
19
|
-
{ruby: 3.
|
20
|
-
{ruby:
|
21
|
-
{ruby:
|
22
|
-
{ruby: 2.7,
|
23
|
-
{ruby: 2.7,
|
24
|
-
{ruby: 2.7,
|
25
|
-
{ruby: 2.
|
26
|
-
{ruby: 2.
|
27
|
-
{ruby: 2.5,
|
28
|
-
{ruby: 2.5,
|
16
|
+
{ruby: '3.2', rails: 7, arelx: 2},
|
17
|
+
{ruby: '3.2', rails: 6_1, arelx: 2},
|
18
|
+
{ruby: '3.1', rails: 7, arelx: 2},
|
19
|
+
{ruby: '3.1', rails: 6_1, arelx: 2},
|
20
|
+
{ruby: '3.0', rails: 7, arelx: 2},
|
21
|
+
{ruby: '3.0', rails: 6_1, arelx: 2},
|
22
|
+
{ruby: '2.7', rails: 7, arelx: 2},
|
23
|
+
{ruby: '2.7', rails: 6_1, arelx: 2},
|
24
|
+
{ruby: '2.7', rails: 6, arelx: 2},
|
25
|
+
{ruby: '2.7', rails: 5_2, arelx: 1},
|
26
|
+
{ruby: '2.7', rails: 4_2, arelx: 1},
|
27
|
+
{ruby: '2.5', rails: 6_1, arelx: 2},
|
28
|
+
{ruby: '2.5', rails: 6, arelx: 2},
|
29
|
+
{ruby: '2.5', rails: 5_2, arelx: 1},
|
30
|
+
{ruby: '2.5', rails: 4_2, arelx: 1},
|
29
31
|
{ruby: jruby-9.2, rails: 6_1, arelx: 2},
|
30
32
|
{ruby: jruby-9.2, rails: 6, arelx: 2},
|
31
33
|
{ruby: jruby-9.2, rails: 5_2, arelx: 1},
|
@@ -44,6 +46,7 @@ jobs:
|
|
44
46
|
sudo apt-get update -q
|
45
47
|
sudo apt-get install -y freetds-dev
|
46
48
|
- name: Update system-wide gems
|
49
|
+
if: ${{ !contains(fromJson('["2.5", "jruby-9.2"]'), matrix.versions.ruby) }}
|
47
50
|
run: gem update --system --no-document
|
48
51
|
- name: Setup Gemfile for arelx 2.x
|
49
52
|
if: ${{ matrix.versions.arelx == 2 }}
|
@@ -65,19 +68,21 @@ jobs:
|
|
65
68
|
fail-fast: false
|
66
69
|
matrix:
|
67
70
|
versions: [
|
68
|
-
{ruby: 3.
|
69
|
-
{ruby: 3.
|
70
|
-
{ruby: 3.
|
71
|
-
{ruby: 3.
|
72
|
-
{ruby:
|
73
|
-
{ruby:
|
74
|
-
{ruby: 2.7,
|
75
|
-
{ruby: 2.7,
|
76
|
-
{ruby: 2.7,
|
77
|
-
{ruby: 2.
|
78
|
-
{ruby: 2.
|
79
|
-
{ruby: 2.5,
|
80
|
-
{ruby: 2.5,
|
71
|
+
{ruby: '3.2', rails: 7, arelx: 2},
|
72
|
+
{ruby: '3.2', rails: 6_1, arelx: 2},
|
73
|
+
{ruby: '3.1', rails: 7, arelx: 2},
|
74
|
+
{ruby: '3.1', rails: 6_1, arelx: 2},
|
75
|
+
{ruby: '3.0', rails: 7, arelx: 2},
|
76
|
+
{ruby: '3.0', rails: 6_1, arelx: 2},
|
77
|
+
{ruby: '2.7', rails: 7, arelx: 2},
|
78
|
+
{ruby: '2.7', rails: 6_1, arelx: 2},
|
79
|
+
{ruby: '2.7', rails: 6, arelx: 2},
|
80
|
+
{ruby: '2.7', rails: 5_2, arelx: 1},
|
81
|
+
{ruby: '2.7', rails: 4_2, arelx: 1},
|
82
|
+
{ruby: '2.5', rails: 6_1, arelx: 2},
|
83
|
+
{ruby: '2.5', rails: 6, arelx: 2},
|
84
|
+
{ruby: '2.5', rails: 5_2, arelx: 1},
|
85
|
+
{ruby: '2.5', rails: 4_2, arelx: 1},
|
81
86
|
{ruby: jruby-9.2, rails: 6_1, arelx: 2},
|
82
87
|
{ruby: jruby-9.2, rails: 6, arelx: 2},
|
83
88
|
{ruby: jruby-9.2, rails: 5_2, arelx: 1},
|
@@ -97,6 +102,7 @@ jobs:
|
|
97
102
|
sudo apt-get update -q
|
98
103
|
sudo apt-get install -y freetds-dev
|
99
104
|
- name: Update system-wide gems
|
105
|
+
if: ${{ !contains(fromJson('["2.5", "jruby-9.2"]'), matrix.versions.ruby) }}
|
100
106
|
run: gem update --system --no-document
|
101
107
|
- name: Setup Gemfile
|
102
108
|
if: ${{ matrix.versions.arelx == 2 }}
|
@@ -118,19 +124,21 @@ jobs:
|
|
118
124
|
fail-fast: false
|
119
125
|
matrix:
|
120
126
|
versions: [
|
121
|
-
{ruby: 3.
|
122
|
-
{ruby: 3.
|
123
|
-
{ruby: 3.
|
124
|
-
{ruby: 3.
|
125
|
-
{ruby:
|
126
|
-
{ruby:
|
127
|
-
{ruby: 2.7,
|
128
|
-
{ruby: 2.7,
|
129
|
-
{ruby: 2.7,
|
130
|
-
{ruby: 2.
|
131
|
-
{ruby: 2.
|
132
|
-
{ruby: 2.5,
|
133
|
-
{ruby: 2.5,
|
127
|
+
{ruby: '3.2', rails: 7, arelx: 2},
|
128
|
+
{ruby: '3.2', rails: 6_1, arelx: 2},
|
129
|
+
{ruby: '3.1', rails: 7, arelx: 2},
|
130
|
+
{ruby: '3.1', rails: 6_1, arelx: 2},
|
131
|
+
{ruby: '3.0', rails: 7, arelx: 2},
|
132
|
+
{ruby: '3.0', rails: 6_1, arelx: 2},
|
133
|
+
{ruby: '2.7', rails: 7, arelx: 2},
|
134
|
+
{ruby: '2.7', rails: 6_1, arelx: 2},
|
135
|
+
{ruby: '2.7', rails: 6, arelx: 2},
|
136
|
+
{ruby: '2.7', rails: 5_2, arelx: 1},
|
137
|
+
{ruby: '2.7', rails: 4_2, arelx: 1},
|
138
|
+
{ruby: '2.5', rails: 6_1, arelx: 2},
|
139
|
+
{ruby: '2.5', rails: 6, arelx: 2},
|
140
|
+
{ruby: '2.5', rails: 5_2, arelx: 1},
|
141
|
+
{ruby: '2.5', rails: 4_2, arelx: 1},
|
134
142
|
{ruby: jruby-9.2, rails: 6_1, arelx: 2},
|
135
143
|
{ruby: jruby-9.2, rails: 6, arelx: 2},
|
136
144
|
{ruby: jruby-9.2, rails: 5_2, arelx: 1},
|
@@ -172,6 +180,7 @@ jobs:
|
|
172
180
|
sudo apt-get update -q
|
173
181
|
sudo apt-get install -y freetds-dev
|
174
182
|
- name: Update system-wide gems
|
183
|
+
if: ${{ !contains(fromJson('["2.5", "jruby-9.2"]'), matrix.versions.ruby) }}
|
175
184
|
run: gem update --system --no-document
|
176
185
|
- name: Setup Gemfile
|
177
186
|
if: ${{ matrix.versions.arelx == 2 }}
|
@@ -196,19 +205,21 @@ jobs:
|
|
196
205
|
fail-fast: false
|
197
206
|
matrix:
|
198
207
|
versions: [
|
199
|
-
{ruby: 3.
|
200
|
-
{ruby: 3.
|
201
|
-
{ruby: 3.
|
202
|
-
{ruby: 3.
|
203
|
-
{ruby:
|
204
|
-
{ruby:
|
205
|
-
{ruby: 2.7,
|
206
|
-
{ruby: 2.7,
|
207
|
-
{ruby: 2.7,
|
208
|
-
{ruby: 2.
|
209
|
-
{ruby: 2.
|
210
|
-
{ruby: 2.5,
|
211
|
-
{ruby: 2.5,
|
208
|
+
{ruby: '3.2', rails: 7, arelx: 2},
|
209
|
+
{ruby: '3.2', rails: 6_1, arelx: 2},
|
210
|
+
{ruby: '3.1', rails: 7, arelx: 2},
|
211
|
+
{ruby: '3.1', rails: 6_1, arelx: 2},
|
212
|
+
{ruby: '3.0', rails: 7, arelx: 2},
|
213
|
+
{ruby: '3.0', rails: 6_1, arelx: 2},
|
214
|
+
{ruby: '2.7', rails: 7, arelx: 2},
|
215
|
+
{ruby: '2.7', rails: 6_1, arelx: 2},
|
216
|
+
{ruby: '2.7', rails: 6, arelx: 2},
|
217
|
+
{ruby: '2.7', rails: 5_2, arelx: 1},
|
218
|
+
{ruby: '2.7', rails: 4_2, arelx: 1},
|
219
|
+
{ruby: '2.5', rails: 6_1, arelx: 2},
|
220
|
+
{ruby: '2.5', rails: 6, arelx: 2},
|
221
|
+
{ruby: '2.5', rails: 5_2, arelx: 1},
|
222
|
+
{ruby: '2.5', rails: 4_2, arelx: 1},
|
212
223
|
{ruby: jruby-9.2, rails: 6_1, arelx: 2},
|
213
224
|
{ruby: jruby-9.2, rails: 6, arelx: 2},
|
214
225
|
{ruby: jruby-9.2, rails: 5_2, arelx: 1},
|
@@ -242,6 +253,7 @@ jobs:
|
|
242
253
|
sudo apt-get update -q
|
243
254
|
sudo apt-get install -y freetds-dev
|
244
255
|
- name: Update system-wide gems
|
256
|
+
if: ${{ !contains(fromJson('["2.5", "jruby-9.2"]'), matrix.versions.ruby) }}
|
245
257
|
run: gem update --system --no-document
|
246
258
|
- name: Setup Gemfile
|
247
259
|
if: ${{ matrix.versions.arelx == 2 }}
|
@@ -269,19 +281,21 @@ jobs:
|
|
269
281
|
fail-fast: false
|
270
282
|
matrix:
|
271
283
|
versions: [
|
272
|
-
# {ruby: 3.
|
273
|
-
{ruby: 3.
|
274
|
-
# {ruby: 3.
|
275
|
-
{ruby: 3.
|
276
|
-
# {ruby:
|
277
|
-
{ruby:
|
278
|
-
{ruby: 2.7,
|
279
|
-
{ruby: 2.7,
|
280
|
-
{ruby: 2.7,
|
281
|
-
{ruby: 2.
|
282
|
-
{ruby: 2.
|
283
|
-
{ruby: 2.5,
|
284
|
-
{ruby: 2.5,
|
284
|
+
# {ruby: '3.2', rails: 7, arelx: 2},
|
285
|
+
{ruby: '3.2', rails: 6_1, arelx: 2},
|
286
|
+
# {ruby: '3.1', rails: 7, arelx: 2},
|
287
|
+
{ruby: '3.1', rails: 6_1, arelx: 2},
|
288
|
+
# {ruby: '3.0', rails: 7, arelx: 2},
|
289
|
+
{ruby: '3.0', rails: 6_1, arelx: 2},
|
290
|
+
# {ruby: '2.7', rails: 7, arelx: 2},
|
291
|
+
{ruby: '2.7', rails: 6_1, arelx: 2},
|
292
|
+
{ruby: '2.7', rails: 6, arelx: 2},
|
293
|
+
{ruby: '2.7', rails: 5_2, arelx: 1},
|
294
|
+
{ruby: '2.7', rails: 4_2, arelx: 1},
|
295
|
+
{ruby: '2.5', rails: 6_1, arelx: 2},
|
296
|
+
{ruby: '2.5', rails: 6, arelx: 2},
|
297
|
+
{ruby: '2.5', rails: 5_2, arelx: 1},
|
298
|
+
{ruby: '2.5', rails: 4_2, arelx: 1},
|
285
299
|
# {ruby: jruby-9.2, rails: 6_1, arelx: 2},
|
286
300
|
# {ruby: jruby-9.2, rails: 6, arelx: 2},
|
287
301
|
{ruby: jruby-9.2, rails: 5_2, arelx: 1},
|
@@ -308,6 +322,7 @@ jobs:
|
|
308
322
|
install: sqlengine, sqlclient, sqlpackage, localdb
|
309
323
|
sa-password: Password12!
|
310
324
|
- name: Update system-wide gems
|
325
|
+
if: ${{ !contains(fromJson('["2.5", "jruby-9.2"]'), matrix.versions.ruby) }}
|
311
326
|
run: gem update --system --no-document
|
312
327
|
- name: Setup Gemfile
|
313
328
|
if: ${{ matrix.versions.arelx == 2 }}
|
data/NEWS.md
CHANGED
@@ -1,13 +1,30 @@
|
|
1
|
-
#
|
1
|
+
# News
|
2
2
|
|
3
|
-
##
|
3
|
+
## Current Release
|
4
|
+
|
5
|
+
### New Features
|
6
|
+
|
7
|
+
- `o.format_date` as an alternative to `o.format`
|
8
|
+
The actual behavior of `format` is inconsistent across DB vendors: in mysql we
|
9
|
+
can format dates and numbers with it, and in the other ones we only format
|
10
|
+
dates.
|
11
|
+
|
12
|
+
We're planning on normalizing this behavior. We want `format` to "cleverly"
|
13
|
+
format dates or numbers, and `format_date` / `format_number` to strictly
|
14
|
+
format dates / numbers.
|
15
|
+
|
16
|
+
The introduction of `format_date` is the first step in this direction.
|
17
|
+
|
18
|
+
## Release v2.1.6/v1.3.6
|
19
|
+
|
20
|
+
### Bug Fixes
|
4
21
|
|
5
22
|
- This used to fail.
|
6
23
|
```
|
7
24
|
Arel.when(a).then(b).format('%Y-%m-%d')
|
8
25
|
```
|
9
26
|
|
10
|
-
|
27
|
+
### New Features
|
11
28
|
|
12
29
|
- `o.present`, a synonym for `o.not_blank`
|
13
30
|
- `o.coalesce_blank(a, b, c)`
|
data/README.md
CHANGED
@@ -36,7 +36,8 @@ It will add common SQL features in your DB to align ti with current routines. Te
|
|
36
36
|
|
37
37
|
## Examples
|
38
38
|
|
39
|
-
|
39
|
+
In the following examples
|
40
|
+
`t` is an `Arel::Table` for table `my_table` (i.e., `t = Arel::Table.new('my_table')`).
|
40
41
|
|
41
42
|
## Comparators
|
42
43
|
|
@@ -50,7 +51,7 @@ t is an Arel::Table for table my_table
|
|
50
51
|
# => my_table.nb > 42
|
51
52
|
```
|
52
53
|
|
53
|
-
Other operators
|
54
|
+
Other operators: <, >=, <=, =~
|
54
55
|
|
55
56
|
|
56
57
|
## Maths
|
@@ -73,7 +74,7 @@ With Arel Extensions:
|
|
73
74
|
# => SUM(my_table.nb) + 42
|
74
75
|
```
|
75
76
|
|
76
|
-
Other functions
|
77
|
+
Other functions: ABS, RAND, ROUND, FLOOR, CEIL, FORMAT
|
77
78
|
|
78
79
|
For Example:
|
79
80
|
```ruby
|
@@ -94,14 +95,29 @@ t[:price].format_number("%07.2f €","fr_FR")
|
|
94
95
|
# => TRIM(TRIM(TRIM(COALESCE(my_table.name, '')), '\t'), '\n') = ''
|
95
96
|
|
96
97
|
(t[:name] =~ /\A[a-d_]+/).to_sql
|
97
|
-
# => my_table.name REGEXP '
|
98
|
+
# => my_table.name REGEXP '^[a-d_]+'
|
98
99
|
```
|
99
100
|
|
100
|
-
|
101
|
+
The `replace` function supports string and regex patterns.
|
102
|
+
For instance
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
t[:email].replace('@', ' at ').replace('.', ' dot ').to_sql
|
106
|
+
# => REPLACE(REPLACE(`my_table`.`email`, '@', ' at '), '.', ' dot ')
|
107
|
+
```
|
108
|
+
|
109
|
+
Captures are supported when using regex patterns. The replace string may then reference the capture groups using `\1`, `\2`, etc. For instance
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
t[:email].replace(/^(.*)@(.*)$/, 'user: \1, host: \2').to_sql
|
113
|
+
# => REGEXP_REPLACE(`my_table`.`email`, '(?-mix:^(.*)@(.*)$)', 'user: \\1, host: \\2')
|
114
|
+
```
|
115
|
+
|
116
|
+
Other functions: SOUNDEX, LENGTH, REPLACE, LOCATE, SUBSTRING, TRIM
|
101
117
|
|
102
118
|
### String Array operations
|
103
119
|
|
104
|
-
|
120
|
+
`t[:list]` is a classical varchar containing a comma separated list (`"1,2,3,4"`).
|
105
121
|
|
106
122
|
```ruby
|
107
123
|
(t[:list] & 3).to_sql
|
@@ -228,15 +244,15 @@ t[:id].cast('char').to_sql
|
|
228
244
|
## Stored Procedures and User-defined functions
|
229
245
|
|
230
246
|
To optimize queries, some classical functions are defined in databases missing any alternative native functions.
|
231
|
-
Examples
|
232
|
-
- FIND_IN_SET
|
247
|
+
Examples:
|
248
|
+
- `FIND_IN_SET`
|
233
249
|
|
234
250
|
## BULK INSERT / UPSERT
|
235
251
|
|
236
252
|
Arel Extensions improves InsertManager by adding bulk_insert method, which allows to insert multiple rows in one insert.
|
237
253
|
|
238
254
|
|
239
|
-
```
|
255
|
+
```ruby
|
240
256
|
@cols = ['id', 'name', 'comments', 'created_at']
|
241
257
|
@data = [
|
242
258
|
[23, 'name1', "sdfdsfdsfsdf", '2016-01-01'],
|
@@ -437,6 +453,15 @@ User.connection.execute(insert_manager.to_sql)
|
|
437
453
|
<td class="ok">✔</td>
|
438
454
|
<td class="ok">✔</td>
|
439
455
|
</tr>
|
456
|
+
<tr>
|
457
|
+
<td class="tg-yw4l">REPLACE<br>column.replace(/re/,"X")</td>
|
458
|
+
<td class="ok">✔</td>
|
459
|
+
<td class="ok">✔</td>
|
460
|
+
<td class="ok">✔</td>
|
461
|
+
<td class="ok">✔</td>
|
462
|
+
<td class="ok">✔</td>
|
463
|
+
<td class="ok">✔</td>
|
464
|
+
</tr>
|
440
465
|
<tr>
|
441
466
|
<td class="tg-yw4l">SOUNDEX<br>column.soundex</td>
|
442
467
|
<td class="ok">✔</td>
|
data/gemfiles/rails6_1.gemfile
CHANGED
@@ -9,7 +9,7 @@ group :development, :test do
|
|
9
9
|
gem 'activerecord', '~> 6.1.0'
|
10
10
|
|
11
11
|
gem 'sqlite3', '~> 1.4', platforms: [:mri]
|
12
|
-
gem 'mysql2', '0.5
|
12
|
+
gem 'mysql2', '~>0.5', platforms: [:mri]
|
13
13
|
gem 'pg', '~> 1.1', platforms: [:mri]
|
14
14
|
|
15
15
|
gem 'tiny_tds', platforms: %i[mri mingw x64_mingw mswin]
|
data/gemfiles/rails7.gemfile
CHANGED
@@ -9,7 +9,7 @@ group :development, :test do
|
|
9
9
|
gem 'activerecord', '~> 7.0.1'
|
10
10
|
|
11
11
|
gem 'sqlite3', '~> 1.4', platforms: [:mri]
|
12
|
-
gem 'mysql2', '0.5
|
12
|
+
gem 'mysql2', '~>0.5', platforms: [:mri]
|
13
13
|
gem 'pg', '~> 1.1', platforms: [:mri]
|
14
14
|
|
15
15
|
gem 'tiny_tds', platforms: %i[mri mingw x64_mingw mswin]
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'arel_extensions/nodes/format'
|
2
|
+
require 'arel_extensions/nodes/formatted_date'
|
2
3
|
require 'arel_extensions/nodes/duration'
|
3
4
|
require 'arel_extensions/nodes/wday'
|
4
5
|
|
@@ -43,5 +44,9 @@ module ArelExtensions
|
|
43
44
|
def format(tpl, time_zone = nil)
|
44
45
|
ArelExtensions::Nodes::Format.new [self, tpl, time_zone]
|
45
46
|
end
|
47
|
+
|
48
|
+
def format_date(tpl, time_zone = nil)
|
49
|
+
ArelExtensions::Nodes::FormattedDate.new [self, tpl, time_zone]
|
50
|
+
end
|
46
51
|
end
|
47
52
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'strscan'
|
2
|
+
|
3
|
+
module ArelExtensions
|
4
|
+
module Nodes
|
5
|
+
class FormattedDate < Function
|
6
|
+
RETURN_TYPE = :string
|
7
|
+
|
8
|
+
attr_accessor :col_type, :iso_format, :time_zone
|
9
|
+
|
10
|
+
def initialize expr
|
11
|
+
col = expr[0]
|
12
|
+
@iso_format = convert_format(expr[1])
|
13
|
+
@time_zone = expr[2]
|
14
|
+
@col_type = type_of_attribute(col)
|
15
|
+
super [col, convert_to_string_node(@iso_format)]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
# Address portability issues with some of the formats.
|
21
|
+
def convert_format(fmt)
|
22
|
+
s = StringScanner.new fmt
|
23
|
+
res = StringIO.new
|
24
|
+
while !s.eos?
|
25
|
+
res <<
|
26
|
+
case
|
27
|
+
when s.scan(/%D/) then '%m/%d/%y'
|
28
|
+
when s.scan(/%F/) then '%Y-%m-%d'
|
29
|
+
when s.scan(/%R/) then '%H:%M'
|
30
|
+
when s.scan(/%r/) then '%I:%M:%S %p'
|
31
|
+
when s.scan(/%T/) then '%H:%M:%S'
|
32
|
+
when s.scan(/%v/) then '%e-%b-%Y'
|
33
|
+
|
34
|
+
when s.scan(/[^%]+/) then s.matched
|
35
|
+
when s.scan(/./) then s.matched
|
36
|
+
end
|
37
|
+
end
|
38
|
+
res.string
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -355,6 +355,10 @@ module ArelExtensions
|
|
355
355
|
end
|
356
356
|
|
357
357
|
def visit_ArelExtensions_Nodes_Format o, collector
|
358
|
+
visit_ArelExtensions_Nodes_FormattedDate o, collector
|
359
|
+
end
|
360
|
+
|
361
|
+
def visit_ArelExtensions_Nodes_FormattedDate o, collector
|
358
362
|
f = ArelExtensions::Visitors::strftime_to_format(o.iso_format, LOADED_VISITOR::DATE_FORMAT_DIRECTIVES)
|
359
363
|
if fmt = LOADED_VISITOR::DATE_CONVERT_FORMATS[f]
|
360
364
|
collector << "CONVERT(VARCHAR(#{f.length})"
|
@@ -258,33 +258,16 @@ module ArelExtensions
|
|
258
258
|
# In this case, `o.col_type` is `nil` but we have a legitimate type in
|
259
259
|
# the expression to be formatted. The following is a best effort to
|
260
260
|
# infer the proper type.
|
261
|
+
first = o.expressions[0]
|
261
262
|
type =
|
262
|
-
o.col_type.nil?
|
263
|
-
|
263
|
+
o.col_type.nil? \
|
264
|
+
&& (first.respond_to?(:return_type) && !first&.return_type.nil?) \
|
265
|
+
? first&.return_type \
|
264
266
|
: o.col_type
|
265
267
|
|
266
268
|
case type
|
267
269
|
when :date, :datetime, :time
|
268
|
-
|
269
|
-
collector << 'DATE_FORMAT('
|
270
|
-
collector << 'CONVERT_TZ(' if o.time_zone
|
271
|
-
collector = visit o.left, collector
|
272
|
-
case o.time_zone
|
273
|
-
when Hash
|
274
|
-
src_tz, dst_tz = o.time_zone.first
|
275
|
-
collector << COMMA
|
276
|
-
collector = visit Arel.quoted(src_tz), collector
|
277
|
-
collector << COMMA
|
278
|
-
collector = visit Arel.quoted(dst_tz), collector
|
279
|
-
collector << ')'
|
280
|
-
when String
|
281
|
-
collector << COMMA << "'UTC'" << COMMA
|
282
|
-
collector = visit Arel.quoted(o.time_zone), collector
|
283
|
-
collector << ')'
|
284
|
-
end
|
285
|
-
collector << COMMA
|
286
|
-
collector = visit Arel.quoted(fmt), collector
|
287
|
-
collector << ')'
|
270
|
+
visit_ArelExtensions_Nodes_FormattedDate o, collector
|
288
271
|
when :integer, :float, :decimal
|
289
272
|
collector << 'FORMAT('
|
290
273
|
collector = visit o.left, collector
|
@@ -299,6 +282,29 @@ module ArelExtensions
|
|
299
282
|
collector
|
300
283
|
end
|
301
284
|
|
285
|
+
def visit_ArelExtensions_Nodes_FormattedDate o, collector
|
286
|
+
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
287
|
+
collector << 'DATE_FORMAT('
|
288
|
+
collector << 'CONVERT_TZ(' if o.time_zone
|
289
|
+
collector = visit o.left, collector
|
290
|
+
case o.time_zone
|
291
|
+
when Hash
|
292
|
+
src_tz, dst_tz = o.time_zone.first
|
293
|
+
collector << COMMA
|
294
|
+
collector = visit Arel.quoted(src_tz), collector
|
295
|
+
collector << COMMA
|
296
|
+
collector = visit Arel.quoted(dst_tz), collector
|
297
|
+
collector << ')'
|
298
|
+
when String
|
299
|
+
collector << COMMA << "'UTC'" << COMMA
|
300
|
+
collector = visit Arel.quoted(o.time_zone), collector
|
301
|
+
collector << ')'
|
302
|
+
end
|
303
|
+
collector << COMMA
|
304
|
+
collector = visit Arel.quoted(fmt), collector
|
305
|
+
collector << ')'
|
306
|
+
end
|
307
|
+
|
302
308
|
def visit_ArelExtensions_Nodes_DateDiff o, collector
|
303
309
|
case o.right_node_type
|
304
310
|
when :ruby_date, :ruby_time, :date, :datetime, :time
|
@@ -451,6 +451,10 @@ module ArelExtensions
|
|
451
451
|
end
|
452
452
|
|
453
453
|
def visit_ArelExtensions_Nodes_Format o, collector
|
454
|
+
visit_ArelExtensions_Nodes_FormattedDate o, collector
|
455
|
+
end
|
456
|
+
|
457
|
+
def visit_ArelExtensions_Nodes_FormattedDate o, collector
|
454
458
|
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
455
459
|
collector << 'TO_CHAR('
|
456
460
|
collector << 'CAST(' if o.time_zone
|
@@ -174,6 +174,10 @@ module ArelExtensions
|
|
174
174
|
end
|
175
175
|
|
176
176
|
def visit_ArelExtensions_Nodes_Format o, collector
|
177
|
+
visit_ArelExtensions_Nodes_FormattedDate o, collector
|
178
|
+
end
|
179
|
+
|
180
|
+
def visit_ArelExtensions_Nodes_FormattedDate o, collector
|
177
181
|
fmt = ArelExtensions::Visitors::strftime_to_format(o.iso_format, DATE_FORMAT_DIRECTIVES)
|
178
182
|
collector << 'TO_CHAR('
|
179
183
|
collector << '(' if o.time_zone
|
@@ -289,6 +289,26 @@ module ArelExtensions
|
|
289
289
|
collector
|
290
290
|
end
|
291
291
|
|
292
|
+
def visit_ArelExtensions_Nodes_FormattedDate o, collector
|
293
|
+
case o.col_type
|
294
|
+
when :date, :datetime, :time
|
295
|
+
collector << 'STRFTIME('
|
296
|
+
collector = visit o.right, collector
|
297
|
+
collector << COMMA
|
298
|
+
collector = visit o.left, collector
|
299
|
+
collector << ')'
|
300
|
+
when :integer, :float, :decimal
|
301
|
+
collector << 'FORMAT('
|
302
|
+
collector = visit o.left, collector
|
303
|
+
collector << COMMA
|
304
|
+
collector = visit o.right, collector
|
305
|
+
collector << ')'
|
306
|
+
else
|
307
|
+
collector = visit o.left, collector
|
308
|
+
end
|
309
|
+
collector
|
310
|
+
end
|
311
|
+
|
292
312
|
# comparators
|
293
313
|
|
294
314
|
def visit_ArelExtensions_Nodes_Cast o, collector
|
@@ -437,123 +437,134 @@ module ArelExtensions
|
|
437
437
|
end
|
438
438
|
|
439
439
|
def test_format
|
440
|
-
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
465
|
-
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
tz = ENV['DB'] == 'mssql' ? time_zones['mssql'] : time_zones['posix']
|
492
|
-
|
493
|
-
assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S', tz['utc']))
|
494
|
-
assert_equal '2014/03/03 09:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['sao_paulo']}))
|
495
|
-
assert_equal '2014/03/03 02:42:00', t(@lucas, @updated_at.format('%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['tahiti']}))
|
440
|
+
%i[format format_date].each do |method|
|
441
|
+
assert_equal '2016-05-23', t(@lucas, @created_at.send(method, '%Y-%m-%d'))
|
442
|
+
assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S'))
|
443
|
+
assert_equal '12:42%', t(@lucas, @updated_at.send(method, '%R%%'))
|
444
|
+
|
445
|
+
# The following tests will ensure proper conversion of timestamps to
|
446
|
+
# requested timezones.
|
447
|
+
#
|
448
|
+
# The names of the timezones is highly dependant on the underlying
|
449
|
+
# operating system, and this is why we need to handle each database
|
450
|
+
# separately: the images we're using to test these databases are
|
451
|
+
# different. So don't rely on the provided examples. Your setup is your
|
452
|
+
# reference.
|
453
|
+
#
|
454
|
+
# One could always have portable code if s/he uses standard
|
455
|
+
# abbreviations, like:
|
456
|
+
#
|
457
|
+
# 1. CET => Central European Time
|
458
|
+
# 2. CEST => Central European Summer Time
|
459
|
+
#
|
460
|
+
# Which implies that the caller should handle daylight saving detection.
|
461
|
+
# In fact, CET will handle daylight saving in MySQL but not Postgres.
|
462
|
+
#
|
463
|
+
# It looks like the posix convention is supported by mysql and
|
464
|
+
# postgresql, e.g.:
|
465
|
+
#
|
466
|
+
# posix/Europe/Paris
|
467
|
+
# posix/America/Nipigon
|
468
|
+
#
|
469
|
+
# so it looks like a more reliably portable way of specifying it.
|
470
|
+
time_zones = {
|
471
|
+
'mssql' => {
|
472
|
+
'utc' => 'UTC',
|
473
|
+
'sao_paulo' => 'Argentina Standard Time',
|
474
|
+
'tahiti' => 'Hawaiian Standard Time',
|
475
|
+
'paris' => 'Central European Standard Time'
|
476
|
+
},
|
477
|
+
'posix' => {
|
478
|
+
'utc' => 'UTC',
|
479
|
+
'sao_paulo' => 'America/Sao_Paulo',
|
480
|
+
'tahiti' => 'Pacific/Tahiti',
|
481
|
+
'paris' => 'Europe/Paris'
|
482
|
+
}
|
483
|
+
}
|
484
|
+
|
485
|
+
skip "Unsupported timezone conversion for DB=#{ENV['DB']}" if !%w[mssql mysql oracle postgresql].include?(ENV['DB'])
|
486
|
+
# TODO: Standarize timezone conversion across all databases.
|
487
|
+
# This test case will be refactored and should work the same across all vendors.
|
488
|
+
if ENV['DB'] == 'mssql' && /Microsoft SQL Server (\d+)/.match(ActiveRecord::Base.connection.select_value('SELECT @@version'))[1].to_i < 2016
|
489
|
+
skip "SQL Server < 2016 is not currently supported"
|
490
|
+
end
|
496
491
|
|
497
|
-
|
498
|
-
|
499
|
-
|
500
|
-
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
assert_equal '
|
509
|
-
|
510
|
-
|
511
|
-
|
512
|
-
assert_equal '
|
492
|
+
tz = ENV['DB'] == 'mssql' ? time_zones['mssql'] : time_zones['posix']
|
493
|
+
|
494
|
+
assert_equal '2014/03/03 12:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', tz['utc']))
|
495
|
+
assert_equal '2014/03/03 09:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['sao_paulo']}))
|
496
|
+
assert_equal '2014/03/03 02:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['tahiti']}))
|
497
|
+
|
498
|
+
# Skipping conversion from UTC to the desired timezones fails in SQL
|
499
|
+
# Server and Postgres. This is mainly due to the fact that timezone
|
500
|
+
# information is not preserved in the column itself.
|
501
|
+
#
|
502
|
+
# MySQL is happy to consider that times by default are in UTC.
|
503
|
+
assert_equal '2014/03/03 13:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['paris']}))
|
504
|
+
refute_equal '2014/03/03 13:42:00', t(@lucas, @updated_at.send(method, '%Y/%m/%d %H:%M:%S', tz['paris'])) if !['mysql'].include?(ENV['DB'])
|
505
|
+
|
506
|
+
# Winter/Summer time
|
507
|
+
assert_equal '2014/08/03 14:42:00', t(@lucas, (@updated_at + 5.months).send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['paris']}))
|
508
|
+
if ENV['DB'] == 'mssql'
|
509
|
+
assert_equal '2022/02/01 11:42:00', t(@lucas, Arel.quoted('2022-02-01 10:42:00').cast(:datetime).send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['paris']}))
|
510
|
+
assert_equal '2022/08/01 12:42:00', t(@lucas, Arel.quoted('2022-08-01 10:42:00').cast(:datetime).send(method, '%Y/%m/%d %H:%M:%S', {tz['utc'] => tz['paris']}))
|
511
|
+
else
|
512
|
+
assert_equal '2022/02/01 11:42:00', t(@lucas, Arel.quoted('2022-02-01 10:42:00').cast(:datetime).send(method, '%Y/%m/%d %H:%M:%S', tz['paris']))
|
513
|
+
assert_equal '2022/08/01 12:42:00', t(@lucas, Arel.quoted('2022-08-01 10:42:00').cast(:datetime).send(method, '%Y/%m/%d %H:%M:%S', tz['paris']))
|
514
|
+
end
|
513
515
|
end
|
514
516
|
end
|
515
517
|
|
516
518
|
def test_format_iso_week
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
519
|
+
%i[format format_date].each do |method|
|
520
|
+
skip "Unsupported ISO week number for DB=#{ENV['DB']}" if ['sqlite'].include?(ENV['DB'])
|
521
|
+
assert_equal '10', t(@lucas, @updated_at.send(method, '%V'))
|
522
|
+
{
|
523
|
+
'2024-01-01 10:42:00' => '01', # Monday
|
524
|
+
'2030-01-01 10:42:00' => '01', # Tuesday
|
525
|
+
'2025-01-01 10:42:00' => '01', # Wednesday
|
526
|
+
'2026-01-01 10:42:00' => '01', # Thursday
|
527
|
+
'2027-01-01 10:42:00' => '53', # Friday
|
528
|
+
'2028-01-01 10:42:00' => '52', # Saturday
|
529
|
+
'2034-01-01 10:42:00' => '52', # Sunday
|
530
|
+
}.each do |date, exp|
|
531
|
+
assert_equal exp, t(@lucas, Arel.quoted(date).cast(:datetime).send(method, '%V'))
|
532
|
+
end
|
529
533
|
end
|
530
534
|
end
|
531
535
|
|
532
536
|
def test_format_iso_year_of_week
|
533
537
|
skip "Unsupported ISO year of week for DB=#{ENV['DB']}" if %w[mssql sqlite].include?(ENV['DB'])
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
|
545
|
-
|
538
|
+
%i[format format_date].each do |method|
|
539
|
+
assert_equal '2014', t(@lucas, @updated_at.send(method, '%G'))
|
540
|
+
|
541
|
+
{
|
542
|
+
'2024-01-01 10:42:00' => '2024', # Monday
|
543
|
+
'2030-01-01 10:42:00' => '2030', # Tuesday
|
544
|
+
'2025-01-01 10:42:00' => '2025', # Wednesday
|
545
|
+
'2026-01-01 10:42:00' => '2026', # Thursday
|
546
|
+
'2027-01-01 10:42:00' => '2026', # Friday
|
547
|
+
'2028-01-01 10:42:00' => '2027', # Saturday
|
548
|
+
'2034-01-01 10:42:00' => '2033', # Sunday
|
549
|
+
}.each do |date, exp|
|
550
|
+
assert_equal exp, t(@lucas, Arel.quoted(date).cast(:datetime).send(method, '%G'))
|
551
|
+
end
|
546
552
|
end
|
547
553
|
end
|
548
554
|
|
549
555
|
def test_format_date_with_names
|
550
556
|
skip "#{ENV['DB']} does not support a variety of word-based formatting for month and day names" if %w[mssql sqlite].include?(ENV['DB'])
|
551
|
-
|
552
|
-
|
557
|
+
%i[format format_date].each do |method|
|
558
|
+
assert_equal 'Mon, 03 Mar 14', t(@lucas, @updated_at.send(method, '%a, %d %b %y'))
|
559
|
+
assert_equal 'Monday, 03 March 14', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
|
560
|
+
end
|
553
561
|
|
554
562
|
skip "#{ENV['DB']} does not support ALLCAPS month and day names" if ['mysql'].include?(ENV['DB'])
|
555
|
-
|
556
|
-
|
563
|
+
%i[format format_date].each do |method|
|
564
|
+
|
565
|
+
assert_equal 'Mon, 03 MAR 14', t(@lucas, @updated_at.send(method, '%a, %d %^b %y'))
|
566
|
+
assert_equal 'Monday, 03 MARCH 14', t(@lucas, @updated_at.send(method, '%A, %d %^B %y'))
|
567
|
+
end
|
557
568
|
end
|
558
569
|
|
559
570
|
def switch_to_lang(lang)
|
@@ -580,28 +591,30 @@ module ArelExtensions
|
|
580
591
|
#
|
581
592
|
# Tests should assert one single thing in principle, but until we
|
582
593
|
# refactor this whole thing, we'll have to do tricks of this sort.
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
591
|
-
|
592
|
-
|
593
|
-
|
594
|
-
|
595
|
-
|
596
|
-
|
597
|
-
|
598
|
-
|
599
|
-
|
600
|
-
|
601
|
-
|
594
|
+
%i[format format_date].each do |method|
|
595
|
+
begin
|
596
|
+
switch_to_lang(:en)
|
597
|
+
case ENV['DB']
|
598
|
+
when 'mysql', 'postgresql'
|
599
|
+
assert_equal 'Mon, 03 Mar 14', t(@lucas, @updated_at.send(method, '%a, %d %b %y'))
|
600
|
+
assert_equal 'Monday, 03 March 14', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
|
601
|
+
when 'mssql'
|
602
|
+
assert_equal 'Monday, 03 March 2014', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
|
603
|
+
end
|
604
|
+
switch_to_lang(:fr)
|
605
|
+
case ENV['DB']
|
606
|
+
when 'mysql'
|
607
|
+
assert_equal 'lun, 03 mar 14', t(@lucas, @updated_at.send(method, '%a, %d %b %y'))
|
608
|
+
assert_equal 'lundi, 03 mars 14', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
|
609
|
+
when 'postgresql'
|
610
|
+
assert_equal 'Lun., 03 Mars 14', t(@lucas, @updated_at.send(method, '%a, %d %b %y'))
|
611
|
+
assert_equal 'Lundi, 03 Mars 14', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
|
612
|
+
when 'mssql'
|
613
|
+
assert_equal 'lundi, 03 mars 2014', t(@lucas, @updated_at.send(method, '%A, %d %B %y'))
|
614
|
+
end
|
615
|
+
ensure
|
616
|
+
switch_to_lang(:en)
|
602
617
|
end
|
603
|
-
ensure
|
604
|
-
switch_to_lang(:en)
|
605
618
|
end
|
606
619
|
end
|
607
620
|
|
@@ -632,6 +645,7 @@ module ArelExtensions
|
|
632
645
|
assert_equal 'Myung', t(@myung, @comments.coalesce_blank('', ' ', ' ').coalesce_blank('Myung'))
|
633
646
|
assert_equal 'Myung', t(@myung, @comments.coalesce_blank('', ' ', ' ', 'Myung'))
|
634
647
|
assert_equal '2016-05-23', t(@myung, @created_at.coalesce_blank(Date.new(2022, 1, 1)).format('%Y-%m-%d'))
|
648
|
+
assert_equal '2016-05-23', t(@myung, @created_at.coalesce_blank(Date.new(2022, 1, 1)).format_date('%Y-%m-%d'))
|
635
649
|
assert_equal 'Laure', t(@laure, @comments.coalesce_blank('Laure'))
|
636
650
|
assert_equal 100, t(@test, @age.coalesce_blank(100))
|
637
651
|
assert_equal 20, t(@test, @age.coalesce_blank(20))
|
@@ -734,8 +748,10 @@ module ArelExtensions
|
|
734
748
|
t(@lucas, (@updated_at + Arel.duration('mn', (@updated_at.hour * 60 + @updated_at.minute))))
|
735
749
|
|
736
750
|
assert_includes ['2024-03-03'], t(@lucas, (@updated_at + durPos).format('%Y-%m-%d'))
|
751
|
+
assert_includes ['2024-03-03'], t(@lucas, (@updated_at + durPos).format_date('%Y-%m-%d'))
|
737
752
|
# puts (@updated_at - durPos).to_sql
|
738
753
|
assert_includes ['2004-03-03'], t(@lucas, (@updated_at - durPos).format('%Y-%m-%d'))
|
754
|
+
assert_includes ['2004-03-03'], t(@lucas, (@updated_at - durPos).format_date('%Y-%m-%d'))
|
739
755
|
|
740
756
|
|
741
757
|
# we test with the ruby object or the string because some adapters don't return an object Date
|
@@ -775,9 +791,11 @@ module ArelExtensions
|
|
775
791
|
assert_equal 0, t(@myung, @comments.if_present.count)
|
776
792
|
assert_equal 20.16, t(@myung, @score.if_present)
|
777
793
|
assert_equal '2016-05-23', t(@myung, @created_at.if_present.format('%Y-%m-%d'))
|
794
|
+
assert_equal '2016-05-23', t(@myung, @created_at.if_present.format_date('%Y-%m-%d'))
|
778
795
|
assert_nil t(@laure, @comments.if_present)
|
779
796
|
|
780
797
|
assert_nil t(@nilly, @duration.if_present.format('%Y-%m-%d'))
|
798
|
+
assert_nil t(@nilly, @duration.if_present.format_date('%Y-%m-%d'))
|
781
799
|
|
782
800
|
# NOTE: here we're testing the capacity to format a nil value,
|
783
801
|
# however, @comments is a text field, and not a date/datetime field,
|
@@ -785,8 +803,10 @@ module ArelExtensions
|
|
785
803
|
# we need to cast it first.
|
786
804
|
if @env_db == 'postgresql'
|
787
805
|
assert_nil t(@laure, @comments.cast(:date).if_present.format('%Y-%m-%d'))
|
806
|
+
assert_nil t(@laure, @comments.cast(:date).if_present.format_date('%Y-%m-%d'))
|
788
807
|
else
|
789
808
|
assert_nil t(@laure, @comments.if_present.format('%Y-%m-%d'))
|
809
|
+
assert_nil t(@laure, @comments.if_present.format_date('%Y-%m-%d'))
|
790
810
|
end
|
791
811
|
end
|
792
812
|
|
data/version_v1.rb
CHANGED
data/version_v2.rb
CHANGED
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: 1.3.
|
4
|
+
version: 1.3.7
|
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:
|
13
|
+
date: 2023-01-27 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: arel
|
@@ -123,6 +123,7 @@ files:
|
|
123
123
|
- lib/arel_extensions/nodes/find_in_set.rb
|
124
124
|
- lib/arel_extensions/nodes/floor.rb
|
125
125
|
- lib/arel_extensions/nodes/format.rb
|
126
|
+
- lib/arel_extensions/nodes/formatted_date.rb
|
126
127
|
- lib/arel_extensions/nodes/formatted_number.rb
|
127
128
|
- lib/arel_extensions/nodes/function.rb
|
128
129
|
- lib/arel_extensions/nodes/is_null.rb
|
@@ -207,7 +208,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
207
208
|
- !ruby/object:Gem::Version
|
208
209
|
version: '0'
|
209
210
|
requirements: []
|
210
|
-
rubygems_version: 3.
|
211
|
+
rubygems_version: 3.3.5
|
211
212
|
signing_key:
|
212
213
|
specification_version: 4
|
213
214
|
summary: Extending Arel
|