sqlite3_extend_function 0.2.0 → 0.3.0

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.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +15 -0
  3. data/.rubocop.yml +36 -0
  4. data/CHANGELOG.md +17 -0
  5. data/Gemfile +10 -0
  6. data/README.md +32 -3
  7. data/bin/console +15 -0
  8. data/bin/setup +8 -0
  9. data/lib/sqlite3_extend_function.rb +7 -9
  10. data/lib/sqlite3_extend_function/function.rb +20 -555
  11. data/lib/sqlite3_extend_function/functions.rb +17 -0
  12. data/lib/sqlite3_extend_function/functions/acos.rb +19 -0
  13. data/lib/sqlite3_extend_function/functions/ascii.rb +20 -0
  14. data/lib/sqlite3_extend_function/functions/asin.rb +19 -0
  15. data/lib/sqlite3_extend_function/functions/atan.rb +19 -0
  16. data/lib/sqlite3_extend_function/functions/atan2.rb +20 -0
  17. data/lib/sqlite3_extend_function/functions/bit_length.rb +21 -0
  18. data/lib/sqlite3_extend_function/functions/btrim.rb +21 -0
  19. data/lib/sqlite3_extend_function/functions/cbrt.rb +22 -0
  20. data/lib/sqlite3_extend_function/functions/ceil.rb +21 -0
  21. data/lib/sqlite3_extend_function/functions/char_length.rb +20 -0
  22. data/lib/sqlite3_extend_function/functions/chr.rb +20 -0
  23. data/lib/sqlite3_extend_function/functions/concat.rb +20 -0
  24. data/lib/sqlite3_extend_function/functions/concat_ws.rb +21 -0
  25. data/lib/sqlite3_extend_function/functions/cos.rb +19 -0
  26. data/lib/sqlite3_extend_function/functions/cot.rb +19 -0
  27. data/lib/sqlite3_extend_function/functions/decode.rb +29 -0
  28. data/lib/sqlite3_extend_function/functions/degrees.rb +19 -0
  29. data/lib/sqlite3_extend_function/functions/div.rb +20 -0
  30. data/lib/sqlite3_extend_function/functions/encode.rb +29 -0
  31. data/lib/sqlite3_extend_function/functions/exp.rb +22 -0
  32. data/lib/sqlite3_extend_function/functions/floor.rb +19 -0
  33. data/lib/sqlite3_extend_function/functions/format.rb +17 -0
  34. data/lib/sqlite3_extend_function/functions/initcap.rb +24 -0
  35. data/lib/sqlite3_extend_function/functions/ln.rb +22 -0
  36. data/lib/sqlite3_extend_function/functions/log.rb +24 -0
  37. data/lib/sqlite3_extend_function/functions/md5.rb +20 -0
  38. data/lib/sqlite3_extend_function/functions/mod.rb +21 -0
  39. data/lib/sqlite3_extend_function/functions/now.rb +15 -0
  40. data/lib/sqlite3_extend_function/functions/octet_length.rb +20 -0
  41. data/lib/sqlite3_extend_function/functions/pi.rb +15 -0
  42. data/lib/sqlite3_extend_function/functions/power.rb +23 -0
  43. data/lib/sqlite3_extend_function/functions/radians.rb +22 -0
  44. data/lib/sqlite3_extend_function/functions/sign.rb +22 -0
  45. data/lib/sqlite3_extend_function/functions/sin.rb +19 -0
  46. data/lib/sqlite3_extend_function/functions/sqrt.rb +22 -0
  47. data/lib/sqlite3_extend_function/functions/tan.rb +19 -0
  48. data/lib/sqlite3_extend_function/functions/trunc.rb +25 -0
  49. data/lib/sqlite3_extend_function/functions/width_bucket.rb +27 -0
  50. data/lib/sqlite3_extend_function/version.rb +1 -1
  51. data/sqlite3_extend_function.gemspec +25 -0
  52. metadata +52 -62
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b370727ad3e7fe4e4dbce17de3372fb15fff6c2193f2400563c1a7a1e9e6fc88
4
- data.tar.gz: d66b7180e476b6154ff201b82424df92f0e28572643e7de869ddd842a9707159
3
+ metadata.gz: 80bfa77fec9b09e2cf91f422d457b75f4d4a29f477a34b677ce33252b8a4c02a
4
+ data.tar.gz: e4bd09974e3c5353c622a3adbdf8b6c3f03040ff1128db0e495569bb769e6a29
5
5
  SHA512:
6
- metadata.gz: b52dc19acdd7720c481acdc73ba8390aaad68f79181f0d9ce4f0fff87bd6c4b512e01bd2faa7141461b6efc4b9909a3b306ff0544c3b233c8b833c5183750940
7
- data.tar.gz: d2f10a203913bbdcf6bf7d1c85e48b0be609cf158ae08209dbe6016561e28653350092f2d7b487a486c05680133b52c847b60073a5b3dd89550518ec26cf633c
6
+ metadata.gz: 01a2867fe5fc9ae7b005eec2ab1310938338fb323fb2336f2f11155a3af60cb79b3ef5215e85e2303c478d31e3b15416a2bba0d5fe51cc9bebe87c0593d718d1
7
+ data.tar.gz: ffd1a7a02b6db7e1e4fede1c2dc33676d496af8e5b278a45f1eaea5758edd240117bfbec9b35f65721f340366df366e43bc42472417545c04f95946549c5ce8e
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ /vendor
10
+ .DS_Store
11
+ Gemfile.lock
12
+ .rspec
13
+
14
+ # rspec failure tracking
15
+ .rspec_status
@@ -0,0 +1,36 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+ NewCops: enable
4
+ Lint/DuplicateBranch:
5
+ Enabled: true
6
+ Lint/DuplicateRegexpCharacterClassElement:
7
+ Enabled: true
8
+ Lint/EmptyBlock:
9
+ Enabled: true
10
+ Lint/EmptyClass:
11
+ Enabled: true
12
+ Lint/NoReturnInBeginEndBlocks:
13
+ Enabled: true
14
+ Lint/ToEnumArguments:
15
+ Enabled: true
16
+ Lint/UnmodifiedReduceAccumulator:
17
+ Enabled: true
18
+ Naming/MethodParameterName:
19
+ Enabled: false
20
+ Metrics/BlockLength:
21
+ Exclude:
22
+ - spec/**/*
23
+ Style/ArgumentsForwarding:
24
+ Enabled: true
25
+ Style/CollectionCompact:
26
+ Enabled: true
27
+ Style/DocumentDynamicEvalDefinition:
28
+ Enabled: true
29
+ Style/NegatedIfElseCondition:
30
+ Enabled: true
31
+ Style/NilLambda:
32
+ Enabled: true
33
+ Style/RedundantArgument:
34
+ Enabled: true
35
+ Style/SwapValues:
36
+ Enabled: true
@@ -0,0 +1,17 @@
1
+ # CHANGELOG
2
+
3
+ ## 0.3.0 / 2020-12-20
4
+ ### Modified
5
+ - Added specification to add extend function
6
+ - Remove SQLite3 from dependency
7
+ - Abolished automatic include of extend function
8
+ - Ruby version changed to 2.4 or higher
9
+
10
+ ## 0.2.0 / 2019-12-05
11
+ ### Modified
12
+ - Remove ActiveRecord from dependency
13
+ - Add function
14
+
15
+ ## 0.1.0 / 2019-12-03
16
+ ### Modified
17
+ - Create ceil and floor functions
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in qlite3_extend_function.gemspec
6
+ gemspec
7
+
8
+ gem 'rake', '~> 13.0'
9
+ gem 'rspec', '~> 3.10'
10
+ gem 'sqlite3', '~> 1.4'
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # SQLite3ExtendFunction
2
2
 
3
- Add some user-defined function to SQL when using SQLie3.
3
+ Add some user-defined function to SQL when using SQLite3.
4
4
 
5
5
  ## Functions
6
6
 
@@ -47,8 +47,9 @@ The following PostgreSQL functions are supported.
47
47
 
48
48
  See [PostgreSQL Document](https://www.postgresql.org/docs/12/functions.html)
49
49
 
50
- ```
50
+ ```ruby
51
51
  # check
52
+ SQLite3::Database.include(SQLite3ExtendFunction)
52
53
  db = SQLite3::Database.new(':memory:')
53
54
 
54
55
  db.execute("select ceil(0.1)")[0][0]
@@ -62,7 +63,7 @@ db.execute("select floor(1.1)")[0][0]
62
63
  Add this line to your application's Gemfile:
63
64
 
64
65
  ```ruby
65
- gem 'sqlite3_extend_function', '~> 0.2'
66
+ gem 'sqlite3_extend_function', '~> 0.3'
66
67
 
67
68
  # master branch
68
69
  gem 'sqlite3_extend_function',
@@ -75,5 +76,33 @@ And then execute:
75
76
  $ bundle
76
77
  ```
77
78
 
79
+ ## Enable extend functions
80
+
81
+ ```ruby
82
+ SQLite3::Database.include(SQLite3ExtendFunction)
83
+ ```
84
+
85
+ ## Add extend function
86
+
87
+ Extend function can be added by defining modules such as:
88
+
89
+ ```ruby
90
+ module SQLite3ExtendFunction
91
+ module Functions
92
+ module FunctionName
93
+ class << self
94
+ def call(arg1)
95
+ # ...
96
+ rescue StandardError
97
+ raise SQLite3::SQLException, 'error message'
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ ```
104
+
105
+ Extend function name is "FunctionName" as the snake case.
106
+
78
107
  ## License
79
108
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'sqlite3_extend_function'
6
+
7
+ # You can add fixtures and/or initialization code here to make experimenting
8
+ # with your gem easier. You can also use a different console, if you like.
9
+
10
+ # (If you use this, don't forget to add pry to your Gemfile!)
11
+ # require "pry"
12
+ # Pry.start
13
+
14
+ require 'irb'
15
+ IRB.start(__FILE__)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -1,27 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'sqlite3'
3
+ require 'bigdecimal'
4
+ require 'base64'
5
+ require 'digest/md5'
4
6
  require 'sqlite3_extend_function/version'
5
7
  require 'sqlite3_extend_function/function'
8
+ require 'sqlite3_extend_function/functions'
6
9
 
7
10
  # SQLite3ExtendFunction
8
11
  module SQLite3ExtendFunction
12
+ # @param [Class] base
13
+ # @return [void]
9
14
  def self.included(base)
10
15
  base.class_eval do
11
16
  original_method = instance_method(:initialize)
12
17
  define_method(:initialize) do |*args, &block|
13
18
  result = original_method.bind(self).call(*args)
14
- SQLite3ExtendFunction::Function.singleton_methods.each do |func|
15
- lmd = Function.send(func)
16
- create_function(func.to_s, (lmd.parameters.size - 1), &lmd)
17
- end
18
- # frozen_string_literal: true
19
- # SQLite3ExtendFunction
19
+ Functions.each { |func| create_function(func.name, func.arity, &func.to_proc) }
20
20
  block&.call(self)
21
21
  result
22
22
  end
23
23
  end
24
24
  end
25
25
  end
26
-
27
- SQLite3::Database.include(SQLite3ExtendFunction)
@@ -1,565 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'bigdecimal'
4
- require 'base64'
5
- require 'digest/md5'
6
3
  module SQLite3ExtendFunction
7
4
  # SQLite3ExtendFunction::Function
8
- module Function
9
- class << self
10
- # @return [Proc]
11
- def ceil
12
- lambda do |func, dp|
13
- return if dp.nil?
14
-
15
- begin
16
- func.result = Kernel.Float(dp).ceil.to_i
17
- rescue ArgumentError
18
- raise SQLite3::SQLException,
19
- "invalid input syntax for type double precision: \"#{dp}\""
20
- end
21
- end
22
- end
23
-
24
- # @return [Proc]
25
- def floor
26
- lambda do |func, dp|
27
- return if dp.nil?
28
-
29
- begin
30
- func.result = Kernel.Float(dp).floor.to_i
31
- rescue ArgumentError
32
- raise SQLite3::SQLException,
33
- "invalid input syntax for type double precision: \"#{dp}\""
34
- end
35
- end
36
- end
37
-
38
- # cube root
39
- # @return [Proc]
40
- def cbrt
41
- lambda do |func, dp|
42
- return if dp.nil?
43
-
44
- begin
45
- result = Math.cbrt(Kernel.Float(dp))
46
- func.result = result.to_i == result ? result.to_i : result
47
- rescue ArgumentError
48
- raise SQLite3::SQLException,
49
- "invalid input syntax for type double precision: \"#{dp}\""
50
- end
51
- end
52
- end
53
-
54
- # radians to degrees
55
- # @return [Proc]
56
- def degrees
57
- lambda do |func, dp|
58
- return if dp.nil?
59
-
60
- begin
61
- func.result = Kernel.Float(dp) * 180 / Math::PI
62
- rescue ArgumentError
63
- raise SQLite3::SQLException,
64
- "invalid input syntax for type double precision: \"#{dp}\""
65
- end
66
- end
67
- end
68
-
69
- # integer quotient of y/x
70
- # @return [Proc]
71
- def div
72
- lambda do |func, y, x|
73
- return if y.nil? || x.nil?
74
-
75
- begin
76
- func.result = Kernel.Float(y).div(Kernel.Float(x))
77
- rescue ArgumentError
78
- raise SQLite3::SQLException,
79
- 'invalid input syntax for type numeric'
80
- end
81
- end
82
- end
83
-
84
- # exponential
85
- # @return [Proc]
86
- def exp
87
- lambda do |func, dp|
88
- return if dp.nil?
89
-
90
- begin
91
- result = Math.exp(Kernel.Float(dp))
92
- func.result = result.to_i == result ? result.to_i : result
93
- rescue ArgumentError
94
- raise SQLite3::SQLException,
95
- "invalid input syntax for type double precision: \"#{dp}\""
96
- end
97
- end
98
- end
99
-
100
- # natural logarithm
101
- # @return [Proc]
102
- def ln
103
- lambda do |func, dp|
104
- return if dp.nil?
105
-
106
- begin
107
- result = Math.log(Kernel.Float(dp))
108
- func.result = result.to_i == result ? result.to_i : result
109
- rescue ArgumentError
110
- raise SQLite3::SQLException,
111
- 'cannot take logarithm of a negative number'
112
- end
113
- end
114
- end
115
-
116
- # base 10 logarithm
117
- # @return [Proc]
118
- def log
119
- lambda do |func, y, x = nil|
120
- if x.nil?
121
- return if y.nil?
122
-
123
- result = Math.log10(Kernel.Float(y))
124
- func.result = result.to_i == result ? result.to_i : result
125
- else
126
- return if y.nil? || x.nil?
127
-
128
- func.result = Math.log(x, y)
129
- end
130
- rescue ArgumentError
131
- raise SQLite3::SQLException,
132
- 'invalid input syntax for type numeric'
133
- end
134
- end
135
-
136
- # remainder of y/x
137
- # @return [Proc]
138
- def mod
139
- lambda do |func, y, x|
140
- func.result = Kernel.Float(y).modulo(Kernel.Float(x)).to_i
141
- rescue ArgumentError
142
- raise SQLite3::SQLException,
143
- 'Could not choose a best candidate function. You might need to add explicit type casts.'
144
- end
145
- end
146
-
147
- # "π" constant
148
- # @return [Proc]
149
- def pi
150
- lambda do |func|
151
- func.result = Math::PI
152
- end
153
- end
154
-
155
- # a raised to the power of b
156
- # @return [Proc]
157
- def power
158
- lambda do |func, a, b|
159
- return if a.nil? || b.nil?
160
-
161
- begin
162
- result = Kernel.Float(a)**Kernel.Float(b)
163
- func.result = result.to_i == result ? result.to_i : result
164
- rescue ArgumentError
165
- raise SQLite3::SQLException,
166
- 'invalid input syntax for type double precision'
167
- end
168
- end
169
- end
170
-
171
- # degrees to radians
172
- # @return [Proc]
173
- def radians
174
- lambda do |func, dp|
175
- return if dp.nil?
176
-
177
- begin
178
- result = Kernel.Float(dp) * Math::PI / 180
179
- func.result = result.to_i == result ? result.to_i : result
180
- rescue ArgumentError
181
- raise SQLite3::SQLException,
182
- "invalid input syntax for type double precision: \"#{dp}\""
183
- end
184
- end
185
- end
186
-
187
- # sign of the argument (-1, 0, +1)
188
- # @return [Proc]
189
- def sign
190
- lambda do |func, dp|
191
- return if dp.nil?
192
-
193
- begin
194
- value = Kernel.Float(dp)
195
- func.result = if value.zero?
196
- 0
197
- elsif value.positive?
198
- 1
199
- else
200
- -1
201
- end
202
- rescue ArgumentError
203
- raise SQLite3::SQLException,
204
- "invalid input syntax for type double precision: \"#{dp}\""
205
- end
206
- end
207
- end
208
-
209
- # square root
210
- # @return [Proc]
211
- def sqrt
212
- lambda do |func, dp|
213
- return if dp.nil?
214
-
215
- begin
216
- result = Math.sqrt(Kernel.Float(dp))
217
- func.result = result.to_i == result ? result.to_i : result
218
- rescue ArgumentError
219
- raise SQLite3::SQLException,
220
- "invalid input syntax for type double precision: \"#{dp}\""
221
- end
222
- end
223
- end
224
-
225
- # truncate toward zero
226
- # @return [Proc]
227
- def trunc
228
- lambda do |func, dp, s = 0|
229
- return if dp.nil?
230
-
231
- begin
232
- ss = BigDecimal(Kernel.Float(s).to_s)
233
- dec = if ss.zero?
234
- BigDecimal('1.0')
235
- else
236
- BigDecimal((1.0 / (10**ss).to_f).to_s)
237
- end
238
- result = (BigDecimal(Kernel.Float(dp).to_s) / dec).to_i * dec
239
- func.result = result.to_i == result ? result.to_i : result.to_f
240
- rescue ArgumentError
241
- raise SQLite3::SQLException,
242
- 'invalid input syntax for type double precision'
243
- end
244
- end
245
- end
246
-
247
- # return the bucket number to which operand would be assigned input
248
- # a histogram having count equal-width buckets spanning the range b1 to b2;
249
- # returns 0 or count+1 for an input outside the range
250
- # @return [Proc]
251
- def width_bucket
252
- lambda do |func, operand, b1, b2, count|
253
- begin
254
- operand = Kernel.Float(operand)
255
- b1 = Kernel.Float(b1)
256
- b2 = Kernel.Float(b2)
257
- count = Kernel.Float(count)
258
-
259
- raise ArgumentError unless count.positive?
260
- result = (operand / ((b2 - b1) / count)).ceil
261
- result = count + 1 if result > count
262
- result = 0 if result.negative?
263
- func.result = result.to_i
264
- rescue ArgumentError
265
- raise SQLite3::SQLException,
266
- 'ArgumentError'
267
- end
268
- end
269
- end
270
-
271
- # @return [Proc]
272
- def acos
273
- lambda do |func, x|
274
- begin
275
- func.result = Math.acos(Kernel.Float(x))
276
- rescue ArgumentError
277
- raise SQLite3::SQLException,
278
- "invalid input syntax for type double precision: #{x}"
279
- end
280
- end
281
- end
282
-
283
- # @return [Proc]
284
- def asin
285
- lambda do |func, x|
286
- begin
287
- func.result = Math.asin(Kernel.Float(x))
288
- rescue ArgumentError
289
- raise SQLite3::SQLException,
290
- "invalid input syntax for type double precision: #{x}"
291
- end
292
- end
293
- end
294
-
295
- # @return [Proc]
296
- def atan
297
- lambda do |func, x|
298
- begin
299
- func.result = Math.atan(Kernel.Float(x))
300
- rescue ArgumentError
301
- raise SQLite3::SQLException,
302
- "invalid input syntax for type double precision: #{x}"
303
- end
304
- end
305
- end
306
-
307
- # @return [Proc]
308
- def atan2
309
- lambda do |func, y, x|
310
- begin
311
- func.result = Math.atan2(Kernel.Float(y), Kernel.Float(x))
312
- rescue ArgumentError
313
- raise SQLite3::SQLException,
314
- "invalid input syntax for type double precision"
315
- end
316
- end
317
- end
318
-
319
- # @return [Proc]
320
- def cos
321
- lambda do |func, x|
322
- begin
323
- func.result = Math.cos(Kernel.Float(x))
324
- rescue ArgumentError
325
- raise SQLite3::SQLException,
326
- "invalid input syntax for type double precision: #{x}"
327
- end
328
- end
329
- end
330
-
331
- # @return [Proc]
332
- def cot
333
- lambda do |func, x|
334
- begin
335
- func.result = 1 / Math.tan(Kernel.Float(x))
336
- rescue ArgumentError
337
- raise SQLite3::SQLException,
338
- "invalid input syntax for type double precision: #{x}"
339
- end
340
- end
341
- end
342
-
343
- # @return [Proc]
344
- def sin
345
- lambda do |func, x|
346
- begin
347
- func.result = Math.sin(Kernel.Float(x))
348
- rescue ArgumentError
349
- raise SQLite3::SQLException,
350
- "invalid input syntax for type double precision: #{x}"
351
- end
352
- end
353
- end
354
-
355
- # @return [Proc]
356
- def tan
357
- lambda do |func, x|
358
- begin
359
- func.result = Math.tan(Kernel.Float(x))
360
- rescue ArgumentError
361
- raise SQLite3::SQLException,
362
- "invalid input syntax for type double precision: #{x}"
363
- end
364
- end
365
- end
366
-
367
- # Number of bits in string
368
- # @return [Proc]
369
- def bit_length
370
- lambda do |func, str|
371
- begin
372
- func.result = str.bytesize * 8
373
- rescue ArgumentError
374
- raise SQLite3::SQLException,
375
- "No function matches the given name and argument types. You might need to add explicit type casts."
376
- end
377
- end
378
- end
379
-
380
- # Number of characters in string
381
- # @return [Proc]
382
- def char_length
383
- lambda do |func, str|
384
- begin
385
- func.result = str.length
386
- rescue ArgumentError
387
- raise SQLite3::SQLException,
388
- "No function matches the given name and argument types. You might need to add explicit type casts."
389
- end
390
- end
391
- end
392
-
393
- # octet_length
394
- # @return [Proc]
395
- def octet_length
396
- lambda do |func, str|
397
- begin
398
- func.result = str.bytesize
399
- rescue ArgumentError
400
- raise SQLite3::SQLException,
401
- "No function matches the given name and argument types. You might need to add explicit type casts."
402
- end
403
- end
404
- end
405
-
406
- # @return [Proc]
407
- def ascii
408
- lambda do |func, str|
409
- begin
410
- raise ArgumentError if str.is_a? String
411
-
412
- func.result = str.ord
413
- rescue ArgumentError
414
- raise SQLite3::SQLException,
415
- "No function matches the given name and argument types. You might need to add explicit type casts."
416
- end
417
- end
418
- end
419
-
420
- # @return [Proc]
421
- def btrim
422
- lambda do |func, text, chrs = ''|
423
- begin
424
- func.result = text.sub(/\A[#{chrs}]*/, '').sub(/[#{chrs}]*\z/, '')
425
- rescue ArgumentError
426
- raise SQLite3::SQLException,
427
- "No function matches the given name and argument types. You might need to add explicit type casts."
428
- end
429
- end
430
- end
431
-
432
- # @return [Proc]
433
- def chr
434
- lambda do |func, int|
435
- begin
436
- func.result = int.chr
437
- rescue ArgumentError
438
- raise SQLite3::SQLException,
439
- "No function matches the given name and argument types. You might need to add explicit type casts."
440
- end
441
- end
442
- end
443
-
444
- # @return [Proc]
445
- def concat
446
- lambda do |func, *args|
447
- begin
448
- func.result = args.compact.join
449
- rescue ArgumentError
450
- raise SQLite3::SQLException,
451
- "No function matches the given name and argument types. You might need to add explicit type casts."
452
- end
453
- end
454
- end
455
-
456
- # @return [Proc]
457
- def concat_ws
458
- lambda do |func, sep, *args|
459
- begin
460
- func.result = args.compact.join(sep)
461
- rescue ArgumentError
462
- raise SQLite3::SQLException,
463
- "No function matches the given name and argument types. You might need to add explicit type casts."
464
- end
465
- end
466
- end
467
-
468
- # @return [Proc]
469
- def decode
470
- lambda do |func, str, format|
471
- return if data.nil?
472
-
473
- begin
474
- raise ArgumentError if data.is_a? String
475
-
476
- func.result = case format
477
- when 'base64'
478
- Base64.decode64(str)
479
- when 'hex'
480
- str.scan(/.{2}/).map(&:hex).map(&:chr).join
481
- when 'escape'
482
- raise ArgumentError
483
- else
484
- raise ArgumentError
485
- end
486
- rescue ArgumentError
487
- raise SQLite3::SQLException,
488
- "No function matches the given name and argument types. You might need to add explicit type casts."
489
- end
490
- end
491
- end
492
-
493
- # @return [Proc]
494
- def encode
495
- lambda do |func, data, format|
496
- return if data.nil?
497
-
498
- begin
499
- raise ArgumentError if data.is_a? String
500
-
501
- func.result = case format
502
- when 'base64'
503
- Base64.encode64(data)
504
- when 'hex'
505
- data.unpack("C*").map { |c| c.to_s(16) }.join
506
- when 'escape'
507
- raise ArgumentError
508
- else
509
- raise ArgumentError
510
- end
511
- rescue ArgumentError
512
- raise SQLite3::SQLException,
513
- "No function matches the given name and argument types. You might need to add explicit type casts."
514
- end
515
- end
516
- end
517
-
518
- # @return [Proc]
519
- def format
520
- lambda do |func, formartstr, *args|
521
- func.result = formartstr % args
522
- end
523
- end
524
-
525
- # @return [Proc]
526
- def initcap
527
- lambda do |func, str|
528
- return if str.nil?
529
-
530
- begin
531
- regexp = /([a-zA-Z0-9]*|[^a-zA-Z0-9]*)/
532
- func.result = str.split(regexp).map.with_index { |s, i|
533
- i.odd? ? s.downcase.capitalize : s
534
- }.join
535
- rescue
536
- raise SQLite3::SQLException,
537
- "No function matches the given name and argument types. You might need to add explicit type casts."
538
- end
539
- end
540
- end
5
+ class Function
6
+ # @param [Class] mod
7
+ # @return [void]
8
+ def initialize(mod)
9
+ @mod = mod
10
+ end
541
11
 
542
- # @return [Proc]
543
- def md5
544
- lambda do |func, str|
545
- return if str.nil?
12
+ # @return [String]
13
+ def name
14
+ @mod.name.split('::').last
15
+ .gsub(/([A-Z\d]+)([A-Z][a-z])/, '\1_\2')
16
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
17
+ .tr('-', '_').downcase
18
+ end
546
19
 
547
- begin
548
- func.result = Digest::MD5.hexdigest(str)
549
- rescue
550
- raise SQLite3::SQLException,
551
- "No function matches the given name and argument types. You might need to add explicit type casts."
552
- end
553
- end
554
- end
20
+ # @return [Proc]
21
+ def to_proc
22
+ ->(func, *argv) { func.result = @mod.call(*argv) }
23
+ end
555
24
 
556
- # Current date and time (start of current transaction)
557
- # @return [Proc]
558
- def now
559
- lambda do |func|
560
- func.result = Time.now.strftime('%Y-%m-%d %H:%M:%S.%6N%:z')
561
- end
562
- end
25
+ # @return [Integer]
26
+ def arity
27
+ @mod.method(:call).parameters.size
563
28
  end
564
29
  end
565
30
  end