sparkql 1.2.5 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- ODQ4YzQ0YzQ1YmJkMDNlMmUxMmFiZTUyZWY2NTcwNjY0YTM2ZTE3OA==
5
- data.tar.gz: !binary |-
6
- NTEyZDlkMWVjY2RjZDY2ZTJlMTg3YjNjNTc4NmE2ZDc3ODdhNTAyYQ==
2
+ SHA256:
3
+ metadata.gz: 5988efc1b20cbe3cd2baec8537c3d9331564962a1d502d2ceaf63d78f520d218
4
+ data.tar.gz: e1b20183b39463bf221eeddbcbdbb32a3d06457f2108c5c2ae6da471fdfdebf3
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- MzMwODdhYTQ3NWQwYzlhYjQ5NWM2ZTNkZDlhMzczMWZmMDg1NDliZWMyOWJj
10
- MmQ3MzMwNjBiYjIzMzE3Y2JiNzk2YzQxMzgyM2EzZDM1MTc4OTVkYmM5YTQw
11
- YjQ3NDVjZWVmZjcyZDkxNzE3ZjI5NTFhODU4NWI5ZjZhYWU1YTA=
12
- data.tar.gz: !binary |-
13
- MmE5ODM3ODdmYTY3MGMxN2I2Mjc2MmQ2NjQwNDM0ZTNiYzU4YTkxYjVkNWE3
14
- YThkMmNlZDA3MjI0MWU0MDdkOTVmNzI4NDhkMmMzNTA5ZGYyNTM1ZGM4NDZm
15
- M2M2ZjdmYTBlMTEwODUxN2ZkMDIyYmQyZDFjNjNmNGU5YTU2MGQ=
6
+ metadata.gz: 707c7f59f776ff70d9c4d164c4177a4800a81da80b2a0b4c7a99fdf7f1c7e632a67e155f11ead5c836fb48cc2ceec364adb8d359ecea6d714cc86f2bea2e0c58
7
+ data.tar.gz: e74cf6657fd5e9cd81dbd23cbdb07c0506ac84280d7651d1b07e11dc8656f56105bde0b6273e7d4fdfd83a91edaa1742e77a4ce6717ca94daf60e5124c34f313
data/.rubocop.yml ADDED
@@ -0,0 +1,111 @@
1
+ AllCops:
2
+ NewCops: disable
3
+ Exclude:
4
+ - 'bin/*'
5
+ - 'config/**/*'
6
+ - 'Rakefile'
7
+ - 'Capfile'
8
+ - 'Gemfile'
9
+ - 'Guardfile'
10
+ - 'test/factories/*'
11
+ - 'test/support/*'
12
+ - 'config/routes.rb'
13
+ - 'script/*'
14
+ - 'db/**/*'
15
+ - 'vendor/**/*'
16
+
17
+ Style/FrozenStringLiteralComment:
18
+ Enabled: false
19
+
20
+ Style/Documentation:
21
+ Enabled: false
22
+
23
+ Metrics/AbcSize:
24
+ Enabled: false
25
+
26
+ Metrics/BlockLength:
27
+ Enabled: false
28
+
29
+ Metrics/ClassLength:
30
+ Enabled: false
31
+
32
+ Metrics/CyclomaticComplexity:
33
+ Enabled: false
34
+
35
+ Layout/LineLength:
36
+ Enabled: false
37
+
38
+ Metrics/MethodLength:
39
+ Enabled: false
40
+
41
+ Metrics/ModuleLength:
42
+ Enabled: false
43
+
44
+ Metrics/PerceivedComplexity:
45
+ Enabled: false
46
+
47
+ # "Favor `unless` over `if` for negative conditions."
48
+ Style/NegatedIf:
49
+ Enabled: false
50
+ # safe_yaml seems to break all the things.
51
+ Security/YAMLLoad:
52
+ Enabled: false
53
+
54
+ # "Use a guard clause (`return unless extra_types.any?`) instead
55
+ # of wrapping the code inside a conditional expression."
56
+ #
57
+ # Justification: guard clauses don't work very well with long lines.
58
+ # Also, when there's an if check that (say) adds an error to a model
59
+ # validation, it makes more sense to wrap the operation in an if block
60
+ # than to guard the error entry with a double negative.
61
+ Style/GuardClause:
62
+ Enabled: false
63
+
64
+ # Justification:
65
+ #
66
+ # `class MyModule::ClassName` is a lot more concise, especially for tests
67
+ # covering a class that is within a module, than having to wrap the whole
68
+ # class in a module, and indent.
69
+ #
70
+ # "Use nested module/class definitions instead of compact style."
71
+ Style/ClassAndModuleChildren:
72
+ Enabled: false
73
+
74
+ # Justification:
75
+ #
76
+ # A single-line guard clause isn't always a good thing.
77
+ Style/IfUnlessModifier:
78
+ Enabled: false
79
+
80
+ # Justification:
81
+ #
82
+ # Hundreds of existing infractions, and it's not really that confusion to
83
+ # see regex without parens around it.
84
+ Lint/AmbiguousRegexpLiteral:
85
+ Enabled: false
86
+
87
+ # Justification:
88
+ #
89
+ # Is it so wrong to have a variable named fgo_listing_1, instead
90
+ # of fgo_listing1?
91
+ Naming/VariableNumber:
92
+ Enabled: false
93
+
94
+ # Justification:
95
+ #
96
+ # Explicit else's are much clearer than
97
+ # a branch that ends with an `elsif`, and presumes
98
+ # a nil else.
99
+ Style/EmptyElse:
100
+ Enabled: false
101
+
102
+ # Justification:
103
+ #
104
+ # We've generally prefered this, and honestly, I find
105
+ # this often makes readability much clearer to include
106
+ # it.
107
+ Style/RedundantSelf:
108
+ Enabled: false
109
+
110
+ Style/StringLiterals:
111
+ Enabled: false
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 1.9.3
1
+ 2.5.8
data/CHANGELOG.md CHANGED
@@ -1,3 +1,19 @@
1
+ v1.3.0, 2022-02-01
2
+ -------------------
3
+ * [BUGFIX] Redesign FunctionResolver to better support other timezones
4
+
5
+ v1.2.8, 2021-08-11
6
+ -------------------
7
+ * [IMPROVEMENT] all() function
8
+
9
+ v1.2.7, 2021-05-06
10
+ -------------------
11
+ * [IMPROVEMENT] dayofweek(), dayofyear(), and weekdays() functions
12
+
13
+ v1.2.6, 2019-04-01
14
+ -------------------
15
+ * [IMPROVEMENT] hours(), minutes(), and seconds() functions
16
+
1
17
  v1.2.5, 2018-12-19
2
18
  -------------------
3
19
  * [BUGFIX] Correctly handle arithmetic grouping
data/Gemfile CHANGED
@@ -1,4 +1,3 @@
1
- source "http://rubygems.org"
1
+ source 'http://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in sparkapi_parser.gemspec
4
3
  gemspec
data/Rakefile CHANGED
@@ -15,7 +15,7 @@ rule '.rb' => '.y' do |t|
15
15
  end
16
16
 
17
17
  desc "Compile the racc parser from the grammar"
18
- task :compile => ["lib/sparkql/parser.rb", "grammar"]
18
+ task compile: ["lib/sparkql/parser.rb", "grammar"]
19
19
 
20
20
  desc "Generate grammar Documenation"
21
21
  task :grammar do
@@ -27,5 +27,4 @@ Rake::Task[:test].prerequisites.unshift "lib/sparkql/parser.rb"
27
27
  Rake::Task[:test].prerequisites.unshift "grammar"
28
28
 
29
29
  desc 'Default: run unit tests.'
30
- task :default => :test
31
-
30
+ task default: :test
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.2.5
1
+ 1.3.0
@@ -1,87 +1,84 @@
1
1
  module Sparkql
2
+ class ErrorsProcessor
3
+ attr_accessor :errors
2
4
 
3
- class ErrorsProcessor
4
- attr_accessor :errors
5
+ def initialize(errors = [])
6
+ @errors = Array(errors)
7
+ end
5
8
 
6
- def initialize( errors = [] )
7
- @errors = Array(errors)
8
- end
9
+ # true if the error stack contains at least one error
10
+ def errors?
11
+ @errors.size.positive?
12
+ end
9
13
 
10
- # true if the error stack contains at least one error
11
- def errors?
12
- @errors.size > 0
13
- end
14
+ # true if there is at least one error of status :status in the error stack
15
+ def errors_by_status?(status)
16
+ @errors.each do |error|
17
+ return true if status == error.status
18
+ end
19
+ false
20
+ end
14
21
 
15
- # true if there is at least one error of status :status in the error stack
16
- def errors_by_status?( status )
17
- @errors.each do | error |
18
- return true if status == error.status
22
+ # true if there is at least one :fatal error in the error stack
23
+ def fatal_errors?
24
+ errors_by_status? :fatal
19
25
  end
20
- false
21
- end
22
26
 
23
- # true if there is at least one :fatal error in the error stack
24
- def fatal_errors?
25
- errors_by_status? :fatal
26
- end
27
+ # true if there is at least one :dropped error in the error stack
28
+ def dropped_errors?
29
+ errors_by_status? :dropped
30
+ end
27
31
 
28
- # true if there is at least one :dropped error in the error stack
29
- def dropped_errors?
30
- errors_by_status? :dropped
32
+ # true if there is at least one :recovered error in the error stack
33
+ def recovered_errors?
34
+ errors_by_status? :recovered
35
+ end
31
36
  end
32
37
 
33
- # true if there is at least one :recovered error in the error stack
34
- def recovered_errors?
35
- errors_by_status? :recovered
36
- end
38
+ class ParserError
39
+ attr_accessor :token, :token_index, :expression, :message, :status, :recovered_as,
40
+ :sparkql, :nested_errors
41
+ attr_writer :syntax, :constraint
37
42
 
38
- end
43
+ def initialize(error_hash = {})
44
+ @token = error_hash[:token]
45
+ @token_index = error_hash[:token_index]
46
+ @expression = error_hash[:expression]
47
+ @message = error_hash[:message]
48
+ @status = error_hash[:status]
49
+ @recovered_as = error_hash[:recovered_as]
50
+ @recovered_as = error_hash[:recovered_as]
51
+ @sparkql = error_hash[:sparkql]
52
+ @nested_errors = error_hash[:nested_errors]
53
+ self.syntax = error_hash[:syntax] != false
54
+ self.constraint = error_hash[:constraint] == true
55
+ end
39
56
 
40
- class ParserError
41
- attr_accessor :token, :token_index, :expression, :message, :status, :recovered_as,
42
- :sparkql, :nested_errors
43
- attr_writer :syntax, :constraint
57
+ def syntax?
58
+ @syntax
59
+ end
44
60
 
45
- def initialize(error_hash={})
46
- @token = error_hash[:token]
47
- @token_index = error_hash[:token_index]
48
- @expression = error_hash[:expression]
49
- @message = error_hash[:message]
50
- @status = error_hash[:status]
51
- @recovered_as = error_hash[:recovered_as]
52
- @recovered_as = error_hash[:recovered_as]
53
- @sparkql = error_hash[:sparkql]
54
- @nested_errors = error_hash[:nested_errors]
55
- self.syntax= error_hash[:syntax] == false ? false : true
56
- self.constraint= error_hash[:constraint] == true
57
- end
58
-
59
- def syntax?
60
- @syntax
61
- end
62
-
63
- def constraint?
64
- @constraint
65
- end
61
+ def constraint?
62
+ @constraint
63
+ end
66
64
 
67
- def to_s
68
- str = case @status
69
- # Do nothing. Dropping the expressions isn't special
70
- when :dropped then "Dropped: "
71
- # Fatal errors cannot be recovered from, and should cause anaylisis or
72
- # compilation to stop.
73
- when :fatal then "Fatal: "
74
- # Recovered errors are those that are syntatically
75
- # or symantically incorrect, but are ones that we could "guess" at the
76
- # intention
77
- when :recovered then
78
- "Recovered as #{@recovered_as}: "
79
- else ""
80
- end
81
- str += "<#{@token}> in " unless @token.nil?
82
- str += "<#{@expression}>: #{@message}."
83
- str
65
+ def to_s
66
+ str = case @status
67
+ # Do nothing. Dropping the expressions isn't special
68
+ when :dropped then "Dropped: "
69
+ # Fatal errors cannot be recovered from, and should cause anaylisis or
70
+ # compilation to stop.
71
+ when :fatal then "Fatal: "
72
+ # Recovered errors are those that are syntatically
73
+ # or symantically incorrect, but are ones that we could "guess" at the
74
+ # intention
75
+ when :recovered
76
+ "Recovered as #{@recovered_as}: "
77
+ else ""
78
+ end
79
+ str += "<#{@token}> in " unless @token.nil?
80
+ str += "<#{@expression}>: #{@message}."
81
+ str
82
+ end
84
83
  end
85
84
  end
86
-
87
- end
@@ -4,7 +4,6 @@
4
4
  # fields. Plus, it has some optimizations built in to skip the processing for
5
5
  # any expressions that don't contribute to the net result of the filter.
6
6
  class Sparkql::Evaluator
7
-
8
7
  # The struct here mimics some of the parser information about an expression,
9
8
  # but should not be confused for an expression. Nodes reduce the expressions
10
9
  # to a result based on conjunction logic, and only one exists per block group.
@@ -16,15 +15,17 @@ class Sparkql::Evaluator
16
15
  :match,
17
16
  :good_ors,
18
17
  :expressions,
19
- :unary)
18
+ :unary
19
+ )
20
20
 
21
21
  attr_reader :processed_count
22
22
 
23
- def initialize expression_resolver
23
+ def initialize(expression_resolver)
24
24
  @resolver = expression_resolver
25
25
  end
26
26
 
27
27
  def evaluate(expressions)
28
+ @dropped_expression = nil
28
29
  @processed_count = 0
29
30
  @index = Node.new(0, 0, "And", 0, true, false, 0, nil)
30
31
  @groups = [@index]
@@ -33,10 +34,11 @@ class Sparkql::Evaluator
33
34
  adjust_expression_for_dropped_field(expression)
34
35
  check_for_good_ors(expression)
35
36
  next if skip?(expression)
37
+
36
38
  evaluate_expression(expression)
37
39
  end
38
40
  cleanup
39
- return @index[:match]
41
+ @index[:match]
40
42
  end
41
43
 
42
44
  private
@@ -58,9 +60,10 @@ class Sparkql::Evaluator
58
60
  # each block_group. This logic is re-used when merging the final result of one
59
61
  # block group with the previous.
60
62
  def evaluate_expression(expression)
61
- @processed_count += 1
63
+ @processed_count += 1
62
64
  evaluate_node(expression, @resolver.resolve(expression))
63
65
  end
66
+
64
67
  def evaluate_node(node, result)
65
68
  if result == :drop
66
69
  @dropped_expression = node
@@ -73,7 +76,7 @@ class Sparkql::Evaluator
73
76
  (node[:conjunction_level] == node[:level] ||
74
77
  node[:conjunction_level] == @index[:level])
75
78
  @index[:match] = !result if @index[:match]
76
- elsif node[:conjunction] == 'And' || @index[:expressions] == 0
79
+ elsif node[:conjunction] == 'And' || (@index[:expressions]).zero?
77
80
  @index[:match] = result if @index[:match]
78
81
  elsif node[:conjunction] == 'Or' && result
79
82
  @index[:match] = result
@@ -97,7 +100,7 @@ class Sparkql::Evaluator
97
100
  end
98
101
  end
99
102
  end
100
- if !good_index.nil? && good_index[:expressions] > 0 && good_index[:match]
103
+ if !good_index.nil? && (good_index[:expressions]).positive? && good_index[:match]
101
104
  good_index[:good_ors] = true
102
105
  end
103
106
  end
@@ -112,8 +115,8 @@ class Sparkql::Evaluator
112
115
 
113
116
  def new_group(expression)
114
117
  Node.new(expression[:level], expression[:block_group],
115
- expression[:conjunction], expression[:conjunction_level],
116
- true, false, 0, nil)
118
+ expression[:conjunction], expression[:conjunction_level],
119
+ true, false, 0, nil)
117
120
  end
118
121
 
119
122
  # When the last expression was dropped, we need to repair the filter by
@@ -125,6 +128,7 @@ class Sparkql::Evaluator
125
128
  expression[:conjunction] = @dropped_expression[:conjunction]
126
129
  expression[:conjunction_level] = @dropped_expression[:conjunction_level]
127
130
  end
131
+
128
132
  @dropped_expression = nil
129
133
  end
130
134
 
@@ -1,17 +1,16 @@
1
1
  # Base class for handling expression resolution
2
2
  class Sparkql::ExpressionResolver
3
-
4
3
  # Accepted results from the resolve method:
5
4
  # * true and false reflect the expression's boolean result (as all expressions
6
5
  # should).
7
6
  # * :drop is a special symbol indicating that the expression should be omitted
8
7
  # from the filter. Special rules apply for a dropped expression, such as
9
8
  # keeping the conjunction of the dropped expression.
10
- VALID_RESULTS = [true, false, :drop]
9
+ VALID_RESULTS = [true, false, :drop].freeze
11
10
 
12
11
  # Evaluate the result of this expression. Allows for any of the values in
13
12
  # VALID_RESULTS
14
- def resolve(expression)
13
+ def resolve(_expression)
15
14
  true
16
15
  end
17
16
  end
@@ -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