sparkql 1.2.5 → 1.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ODQ4YzQ0YzQ1YmJkMDNlMmUxMmFiZTUyZWY2NTcwNjY0YTM2ZTE3OA==
4
+ MzM0ZTA3ZTIxNjlkMzY5YmFiMGM4MGFkOTA2NWZlNzMzZWQxNTQxMw==
5
5
  data.tar.gz: !binary |-
6
- NTEyZDlkMWVjY2RjZDY2ZTJlMTg3YjNjNTc4NmE2ZDc3ODdhNTAyYQ==
6
+ ZmE5ZTQwZDc1YzI0YTJmZTRjYzMxMGY3ZDZmYmFmNzkxMWRmNTBiMg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzMwODdhYTQ3NWQwYzlhYjQ5NWM2ZTNkZDlhMzczMWZmMDg1NDliZWMyOWJj
10
- MmQ3MzMwNjBiYjIzMzE3Y2JiNzk2YzQxMzgyM2EzZDM1MTc4OTVkYmM5YTQw
11
- YjQ3NDVjZWVmZjcyZDkxNzE3ZjI5NTFhODU4NWI5ZjZhYWU1YTA=
9
+ Mjc0NjNjNGVkYWE1ZDVlNzIwNTY3ZDNjZmFiZDc2NGI5MmNlNGU5MjYzN2Yy
10
+ NTc1ZTMwYTVmNmM5Nzk2Mjk5OTk2Nzc5ZmYyNTA3Njc2ZmU0NjkzM2I2ZmQx
11
+ YTQxMzIzZjBjNDU0NTc1Y2VmYzMyNGRmZDNmNWFlNTFmYzFiZjg=
12
12
  data.tar.gz: !binary |-
13
- MmE5ODM3ODdmYTY3MGMxN2I2Mjc2MmQ2NjQwNDM0ZTNiYzU4YTkxYjVkNWE3
14
- YThkMmNlZDA3MjI0MWU0MDdkOTVmNzI4NDhkMmMzNTA5ZGYyNTM1ZGM4NDZm
15
- M2M2ZjdmYTBlMTEwODUxN2ZkMDIyYmQyZDFjNjNmNGU5YTU2MGQ=
13
+ MzczODc4ZTAyOTRkNDlhNzZiYTQxYjUyM2FlMTQ0ZmU3NmMyZmY2Y2Q2YmFj
14
+ MTk0ODFmMTFmZmI4MTQ2MzkxOTFiYjkwYmM1NGQ1NzdmZjNiMjZmYjQ4MGJi
15
+ ODY1NmM3NWJhNTFmMzgxY2EwZGU5NWY1ZGVmYTVkZTBjMGZlNmU=
@@ -1,3 +1,7 @@
1
+ v1.2.6, 2019-04-01
2
+ -------------------
3
+ * [IMPROVEMENT] hours(), minutes(), and seconds() functions
4
+
1
5
  v1.2.5, 2018-12-19
2
6
  -------------------
3
7
  * [BUGFIX] Correctly handle arithmetic grouping
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.5
1
+ 1.2.6
@@ -10,7 +10,9 @@ require 'sparkql/geo'
10
10
  # Name and argument requirements for the function should match the function declaration in
11
11
  # SUPPORTED_FUNCTIONS which will run validation on the function syntax prior to execution.
12
12
  class Sparkql::FunctionResolver
13
- SECONDS_IN_DAY = 60 * 60 * 24
13
+ SECONDS_IN_MINUTE = 60
14
+ SECONDS_IN_HOUR = SECONDS_IN_MINUTE * 60
15
+ SECONDS_IN_DAY = SECONDS_IN_HOUR * 24
14
16
  STRFTIME_DATE_FORMAT = '%Y-%m-%d'
15
17
  STRFTIME_TIME_FORMAT = '%H:%M:%S.%N'
16
18
  VALID_REGEX_FLAGS = ["", "i"]
@@ -111,6 +113,18 @@ class Sparkql::FunctionResolver
111
113
  :args => [:character],
112
114
  :return_type => :shape
113
115
  },
116
+ :seconds => {
117
+ :args => [:integer],
118
+ :return_type => :datetime
119
+ },
120
+ :minutes => {
121
+ :args => [:integer],
122
+ :return_type => :datetime
123
+ },
124
+ :hours => {
125
+ :args => [:integer],
126
+ :return_type => :datetime
127
+ },
114
128
  :days => {
115
129
  :args => [:integer],
116
130
  :return_type => :datetime
@@ -464,6 +478,33 @@ class Sparkql::FunctionResolver
464
478
  }
465
479
  end
466
480
 
481
+ # Offset the current timestamp by a number of seconds
482
+ def seconds(num)
483
+ t = Time.now + num
484
+ {
485
+ :type => :datetime,
486
+ :value => t.iso8601
487
+ }
488
+ end
489
+
490
+ # Offset the current timestamp by a number of minutes
491
+ def minutes(num)
492
+ t = Time.now + num * SECONDS_IN_MINUTE
493
+ {
494
+ :type => :datetime,
495
+ :value => t.iso8601
496
+ }
497
+ end
498
+
499
+ # Offset the current timestamp by a number of hours
500
+ def hours(num)
501
+ t = Time.now + num * SECONDS_IN_HOUR
502
+ {
503
+ :type => :datetime,
504
+ :value => t.iso8601
505
+ }
506
+ end
507
+
467
508
  # Offset the current timestamp by a number of days
468
509
  def days(num)
469
510
  # date calculated as the offset from midnight tommorrow. Zero will provide values for all times
@@ -1,6 +1,6 @@
1
1
  #
2
2
  # DO NOT MODIFY!!!!
3
- # This file is automatically generated by Racc 1.4.14
3
+ # This file is automatically generated by Racc 1.4.15
4
4
  # from Racc grammer file "".
5
5
  #
6
6
 
@@ -279,6 +279,175 @@ class FunctionResolverTest < Test::Unit::TestCase
279
279
  assert_equal "ListPrice", value[:args].first[:value]
280
280
  end
281
281
 
282
+ test "seconds()" do
283
+ dt = Time.new(2019, 4, 1, 8, 30, 20, 0)
284
+
285
+ Time.expects(:now).returns(dt).times(3)
286
+
287
+ f = FunctionResolver.new('seconds', [{:type=>:integer, :value => 7}])
288
+ f.validate
289
+ assert !f.errors?, "Errors #{f.errors.inspect}"
290
+ value = f.call
291
+
292
+ assert_equal :datetime, value[:type]
293
+ d = DateTime.parse(value[:value])
294
+ assert_equal dt.year, d.year
295
+ assert_equal dt.month, d.month
296
+ assert_equal dt.mday, d.mday
297
+ assert_equal dt.hour, d.hour
298
+ assert_equal dt.min, d.min
299
+ assert_equal dt.sec + 7, d.sec
300
+
301
+ f = FunctionResolver.new('seconds', [{:type=>:integer, :value => -21}])
302
+ f.validate
303
+ assert !f.errors?, "Errors #{f.errors.inspect}"
304
+ value = f.call
305
+
306
+ assert_equal :datetime, value[:type]
307
+ d = DateTime.parse(value[:value])
308
+ assert_equal dt.year, d.year
309
+ assert_equal dt.month, d.month
310
+ assert_equal dt.mday, d.mday
311
+ assert_equal dt.hour, d.hour
312
+ assert_equal dt.min - 1, d.min
313
+ assert_equal 29, d.min
314
+ assert_equal 59, d.sec
315
+
316
+ f = FunctionResolver.new('seconds', [{:type=>:integer,
317
+ :value => -Sparkql::FunctionResolver::SECONDS_IN_DAY}])
318
+ f.validate
319
+ assert !f.errors?, "Errors #{f.errors.inspect}"
320
+ value = f.call
321
+
322
+ assert_equal :datetime, value[:type]
323
+ d = DateTime.parse(value[:value])
324
+ assert_equal dt.year, d.year
325
+ assert_equal dt.month - 1, d.month
326
+ assert_equal 31, d.mday
327
+ assert_equal dt.hour, d.hour
328
+ assert_equal dt.min, d.min
329
+ assert_equal dt.min, d.min
330
+ assert_equal dt.sec, d.sec
331
+ end
332
+
333
+ test "minutes()" do
334
+ dt =Time.new(2019, 4, 1, 8, 30, 20, 0)
335
+
336
+ Time.expects(:now).returns(dt).times(3)
337
+
338
+ f = FunctionResolver.new('minutes', [{:type=>:integer, :value => 7}])
339
+ f.validate
340
+ assert !f.errors?, "Errors #{f.errors.inspect}"
341
+ value = f.call
342
+
343
+ assert_equal :datetime, value[:type]
344
+ d = DateTime.parse(value[:value])
345
+ assert_equal dt.year, d.year
346
+ assert_equal dt.month, d.month
347
+ assert_equal dt.mday, d.mday
348
+ assert_equal dt.hour, d.hour
349
+ assert_equal dt.min + 7, d.min
350
+ assert_equal dt.sec, d.sec
351
+
352
+ f = FunctionResolver.new('minutes', [{:type=>:integer, :value => -37}])
353
+ f.validate
354
+ assert !f.errors?, "Errors #{f.errors.inspect}"
355
+ value = f.call
356
+
357
+ assert_equal :datetime, value[:type]
358
+ d = DateTime.parse(value[:value])
359
+ assert_equal dt.year, d.year
360
+ assert_equal dt.month, d.month
361
+ assert_equal dt.mday, d.mday
362
+ assert_equal dt.hour-1, d.hour
363
+ assert_equal 53, d.min
364
+
365
+ f = FunctionResolver.new('minutes', [{:type=>:integer,
366
+ :value => -1440}])
367
+ f.validate
368
+ assert !f.errors?, "Errors #{f.errors.inspect}"
369
+ value = f.call
370
+
371
+ assert_equal :datetime, value[:type]
372
+ d = DateTime.parse(value[:value])
373
+ assert_equal dt.year, d.year
374
+ assert_equal dt.month - 1, d.month
375
+ assert_equal 31, d.mday
376
+ assert_equal dt.hour, d.hour
377
+ assert_equal dt.min, d.min
378
+ end
379
+
380
+ test "hours(), same day" do
381
+ dt =Time.new(2019, 4, 1, 8, 30, 20, 0)
382
+
383
+ tests = [1, -1, 5, -5, 12]
384
+ Time.expects(:now).returns(dt).times(tests.count)
385
+
386
+ tests.each do |offset|
387
+ f = FunctionResolver.new('hours', [{:type=>:integer,
388
+ :value => offset}])
389
+ f.validate
390
+ assert !f.errors?, "Errors #{f.errors.inspect}"
391
+ value = f.call
392
+
393
+ assert_equal :datetime, value[:type]
394
+ d = DateTime.parse(value[:value])
395
+ assert_equal dt.year, d.year
396
+ assert_equal dt.month, d.month
397
+ assert_equal dt.mday, d.mday
398
+ assert_equal dt.hour + offset, d.hour
399
+ assert_equal dt.min, d.min
400
+ assert_equal dt.sec, d.sec
401
+ end
402
+ end
403
+
404
+ test "hours(), wrap day" do
405
+ dt =Time.new(2019, 4, 1, 8, 30, 20, 0)
406
+ Time.expects(:now).returns(dt).times(3)
407
+
408
+ # Jump forward a few days, and a few hours.
409
+ f = FunctionResolver.new('hours', [{:type=>:integer, :value => 52}])
410
+ f.validate
411
+ assert !f.errors?, "Errors #{f.errors.inspect}"
412
+ value = f.call
413
+
414
+ assert_equal :datetime, value[:type]
415
+ d = DateTime.parse(value[:value])
416
+ assert_equal dt.year, d.year
417
+ assert_equal dt.month, d.month
418
+ assert_equal dt.mday + 2, d.mday
419
+ assert_equal dt.hour + 4, d.hour
420
+ assert_equal dt.min, d.min
421
+
422
+ # Drop back to the previous day, which'll also hit the previous month
423
+ f = FunctionResolver.new('hours', [{:type=>:integer, :value => -24}])
424
+ f.validate
425
+ assert !f.errors?, "Errors #{f.errors.inspect}"
426
+ value = f.call
427
+
428
+ assert_equal :datetime, value[:type]
429
+ d = DateTime.parse(value[:value])
430
+ assert_equal dt.year, d.year
431
+ assert_equal dt.month - 1, d.month
432
+ assert_equal 31, d.mday
433
+ assert_equal dt.hour, d.hour
434
+ assert_equal dt.min, d.min
435
+
436
+ # Drop back one full year's worth of hours.
437
+ f = FunctionResolver.new('hours', [{:type=>:integer, :value => -8760}])
438
+ f.validate
439
+ assert !f.errors?, "Errors #{f.errors.inspect}"
440
+ value = f.call
441
+
442
+ assert_equal :datetime, value[:type]
443
+ d = DateTime.parse(value[:value])
444
+ assert_equal dt.year - 1, d.year
445
+ assert_equal dt.month, d.month
446
+ assert_equal dt.mday, d.mday
447
+ assert_equal dt.hour, d.hour
448
+ assert_equal dt.min, d.min
449
+ end
450
+
282
451
  test "days()" do
283
452
  d = Date.new(2012,10,20)
284
453
  Date.expects(:today).returns(d)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sparkql
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.5
4
+ version: 1.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wade McEwen
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-12-19 00:00:00.000000000 Z
11
+ date: 2019-04-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: georuby