sparkql 1.2.8 → 1.3.1

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.
@@ -1,23 +1,21 @@
1
- # Custom fields need to add a table join to the customfieldsearch table when AND'd together,
1
+ # Custom fields need to add a table join to the customfieldsearch table when AND'd together,
2
2
  # but not when they are OR'd or nested. This class maintains the state for all custom field expressions
3
3
  # lets the parser know when to do either.
4
4
  class Sparkql::ExpressionState
5
-
6
5
  def initialize
7
- @expressions = {0=>[]}
6
+ @expressions = { 0 => [] }
8
7
  @last_conjunction = "And" # always start with a join
9
8
  @block_group = 0
10
9
  end
11
-
10
+
12
11
  def push(expression)
13
12
  @block_group = expression[:block_group]
14
- @expressions[@block_group] ||= []
13
+ @expressions[@block_group] ||= []
15
14
  @expressions[@block_group] << expression
16
15
  @last_conjunction = expression[:conjunction]
17
16
  end
18
-
17
+
19
18
  def needs_join?
20
- return @expressions[@block_group].size == 1 || ["Not", "And"].include?(@last_conjunction)
19
+ @expressions[@block_group].size == 1 || %w[Not And].include?(@last_conjunction)
21
20
  end
22
-
23
- end
21
+ end
@@ -225,14 +225,19 @@ module Sparkql
225
225
  }
226
226
  }.freeze
227
227
 
228
+ def self.lookup(function_name)
229
+ SUPPORTED_FUNCTIONS[function_name.to_sym]
230
+ end
231
+
228
232
  # Construct a resolver instance for a function
229
233
  # name: function name (String)
230
234
  # args: array of literal hashes of the format {:type=><literal_type>, :value=><escaped_literal_value>}.
231
235
  # Empty arry for functions that have no arguments.
232
- def initialize(name, args)
236
+ def initialize(name, args, options = {})
233
237
  @name = name
234
238
  @args = args
235
239
  @errors = []
240
+ @current_timestamp = options[:current_timestamp]
236
241
  end
237
242
 
238
243
  # Validate the function instance prior to calling it. All validation failures will show up in the
@@ -541,18 +546,16 @@ module Sparkql
541
546
  today += weeks * 7
542
547
 
543
548
  # Now iterate on the remaining weekdays
544
- remaining.times do |i|
549
+ remaining.times do |_i|
545
550
  today += direction
546
- while today.saturday? || today.sunday?
547
- today += direction
548
- end
551
+ today += direction while today.saturday? || today.sunday?
549
552
  end
550
553
 
551
554
  # If we end on the weekend, bump accordingly
552
555
  while today.saturday? || today.sunday?
553
556
  # If we start and end on the weekend, wind things back to the next
554
557
  # appropriate weekday.
555
- if weekend_start && remaining == 0
558
+ if weekend_start && remaining.zero?
556
559
  today -= direction
557
560
  else
558
561
  today += direction
@@ -637,7 +640,8 @@ module Sparkql
637
640
  end
638
641
 
639
642
  def months(num_months)
640
- d = current_timestamp >> num_months
643
+ # DateTime usage. There's a better means to do this with Time via rails
644
+ d = (current_timestamp.to_datetime >> num_months).to_time
641
645
  {
642
646
  type: :date,
643
647
  value: d.strftime(STRFTIME_DATE_FORMAT)
@@ -645,7 +649,8 @@ module Sparkql
645
649
  end
646
650
 
647
651
  def years(num_years)
648
- d = current_timestamp >> (num_years * 12)
652
+ # DateTime usage. There's a better means to do this with Time via rails
653
+ d = (current_timestamp.to_datetime >> (num_years * 12)).to_time
649
654
  {
650
655
  type: :date,
651
656
  value: d.strftime(STRFTIME_DATE_FORMAT)
@@ -832,11 +837,11 @@ module Sparkql
832
837
  end
833
838
 
834
839
  def current_time
835
- current_timestamp.to_time
840
+ current_timestamp
836
841
  end
837
842
 
838
843
  def current_timestamp
839
- @current_timestamp ||= DateTime.now
844
+ @current_timestamp ||= Time.now
840
845
  end
841
846
 
842
847
  private
@@ -1,7 +1,7 @@
1
1
  module Sparkql
2
2
  module Geo
3
3
  class RecordRadius
4
- RECORD_ID_REGEX = /\A[0-9]{26}\z/
4
+ RECORD_ID_REGEX = /\A[0-9]{26}\z/.freeze
5
5
 
6
6
  attr_accessor :record_id, :radius
7
7
 
data/lib/sparkql/lexer.rb CHANGED
@@ -2,9 +2,9 @@ require 'strscan'
2
2
 
3
3
  class Sparkql::Lexer < StringScanner
4
4
  include Sparkql::Token
5
-
5
+
6
6
  attr_accessor :level, :block_group_identifier
7
-
7
+
8
8
  attr_reader :last_field, :current_token_value, :token_index
9
9
 
10
10
  def initialize(str)
@@ -14,51 +14,50 @@ class Sparkql::Lexer < StringScanner
14
14
  @block_group_identifier = 0
15
15
  @expression_count = 0
16
16
  end
17
-
17
+
18
18
  # Lookup the next matching token
19
19
  def shift
20
20
  @token_index = self.pos
21
21
 
22
- token = case
23
- when @current_token_value = scan(SPACE)
24
- [:SPACE, @current_token_value]
25
- when @current_token_value = scan(LPAREN)
26
- levelup
27
- [:LPAREN, @current_token_value]
28
- when @current_token_value = scan(RPAREN)
29
- # leveldown: do this after parsing group
30
- [:RPAREN, @current_token_value]
31
- when @current_token_value = scan(/\,/)
32
- [:COMMA,@current_token_value]
33
- when @current_token_value = scan(NULL)
34
- literal :NULL, "NULL"
35
- when @current_token_value = scan(STANDARD_FIELD)
36
- check_standard_fields(@current_token_value)
37
- when @current_token_value = scan(DATETIME)
38
- literal :DATETIME, @current_token_value
39
- when @current_token_value = scan(DATE)
40
- literal :DATE, @current_token_value
41
- when @current_token_value = scan(TIME)
42
- literal :TIME, @current_token_value
43
- when @current_token_value = scan(DECIMAL)
44
- literal :DECIMAL, @current_token_value
45
- when @current_token_value = scan(INTEGER)
46
- literal :INTEGER, @current_token_value
47
- when @current_token_value = scan(/\-/)
48
- [:UMINUS, @current_token_value]
49
- when @current_token_value = scan(CHARACTER)
50
- literal :CHARACTER, @current_token_value
51
- when @current_token_value = scan(BOOLEAN)
52
- literal :BOOLEAN, @current_token_value
53
- when @current_token_value = scan(KEYWORD)
54
- check_keywords(@current_token_value)
55
- when @current_token_value = scan(CUSTOM_FIELD)
56
- [:CUSTOM_FIELD,@current_token_value]
57
- when eos?
58
- [false, false] # end of file, \Z don't work with StringScanner
59
- else
60
- [:UNKNOWN, "ERROR: '#{self.string}'"]
61
- end
22
+ token = if (@current_token_value = scan(SPACE))
23
+ [:SPACE, @current_token_value]
24
+ elsif (@current_token_value = scan(LPAREN))
25
+ levelup
26
+ [:LPAREN, @current_token_value]
27
+ elsif (@current_token_value = scan(RPAREN))
28
+ # leveldown: do this after parsing group
29
+ [:RPAREN, @current_token_value]
30
+ elsif (@current_token_value = scan(/,/))
31
+ [:COMMA, @current_token_value]
32
+ elsif (@current_token_value = scan(NULL))
33
+ literal :NULL, "NULL"
34
+ elsif (@current_token_value = scan(STANDARD_FIELD))
35
+ check_standard_fields(@current_token_value)
36
+ elsif (@current_token_value = scan(DATETIME))
37
+ literal :DATETIME, @current_token_value
38
+ elsif (@current_token_value = scan(DATE))
39
+ literal :DATE, @current_token_value
40
+ elsif (@current_token_value = scan(TIME))
41
+ literal :TIME, @current_token_value
42
+ elsif (@current_token_value = scan(DECIMAL))
43
+ literal :DECIMAL, @current_token_value
44
+ elsif (@current_token_value = scan(INTEGER))
45
+ literal :INTEGER, @current_token_value
46
+ elsif (@current_token_value = scan(/-/))
47
+ [:UMINUS, @current_token_value]
48
+ elsif (@current_token_value = scan(CHARACTER))
49
+ literal :CHARACTER, @current_token_value
50
+ elsif (@current_token_value = scan(BOOLEAN))
51
+ literal :BOOLEAN, @current_token_value
52
+ elsif (@current_token_value = scan(KEYWORD))
53
+ check_keywords(@current_token_value)
54
+ elsif (@current_token_value = scan(CUSTOM_FIELD))
55
+ [:CUSTOM_FIELD, @current_token_value]
56
+ elsif eos?
57
+ [false, false] # end of file, \Z don't work with StringScanner
58
+ else
59
+ [:UNKNOWN, "ERROR: '#{self.string}'"]
60
+ end
62
61
 
63
62
  token.freeze
64
63
  end
@@ -66,13 +65,13 @@ class Sparkql::Lexer < StringScanner
66
65
  def check_reserved_words(value)
67
66
  u_value = value.capitalize
68
67
  if OPERATORS.include?(u_value)
69
- [:OPERATOR,u_value]
68
+ [:OPERATOR, u_value]
70
69
  elsif RANGE_OPERATOR == u_value
71
- [:RANGE_OPERATOR,u_value]
70
+ [:RANGE_OPERATOR, u_value]
72
71
  elsif CONJUNCTIONS.include?(u_value)
73
- [:CONJUNCTION,u_value]
72
+ [:CONJUNCTION, u_value]
74
73
  elsif UNARY_CONJUNCTIONS.include?(u_value)
75
- [:UNARY_CONJUNCTION,u_value]
74
+ [:UNARY_CONJUNCTION, u_value]
76
75
  elsif ADD == u_value
77
76
  [:ADD, u_value]
78
77
  elsif SUB == u_value
@@ -87,12 +86,12 @@ class Sparkql::Lexer < StringScanner
87
86
  [:UNKNOWN, "ERROR: '#{self.string}'"]
88
87
  end
89
88
  end
90
-
89
+
91
90
  def check_standard_fields(value)
92
91
  result = check_reserved_words(value)
93
92
  if result.first == :UNKNOWN
94
93
  @last_field = value
95
- result = [:STANDARD_FIELD,value]
94
+ result = [:STANDARD_FIELD, value]
96
95
  end
97
96
  result
98
97
  end
@@ -100,26 +99,25 @@ class Sparkql::Lexer < StringScanner
100
99
  def check_keywords(value)
101
100
  result = check_reserved_words(value)
102
101
  if result.first == :UNKNOWN
103
- result = [:KEYWORD,value]
102
+ result = [:KEYWORD, value]
104
103
  end
105
104
  result
106
105
  end
107
-
106
+
108
107
  def levelup
109
108
  @level += 1
110
109
  @block_group_identifier += 1
111
110
  end
112
-
111
+
113
112
  def leveldown
114
113
  @level -= 1
115
114
  end
116
-
115
+
117
116
  def literal(symbol, value)
118
117
  node = {
119
- :type => symbol.to_s.downcase.to_sym,
120
- :value => value
118
+ type: symbol.to_s.downcase.to_sym,
119
+ value: value
121
120
  }
122
121
  [symbol, node]
123
122
  end
124
-
125
123
  end