From b60ac1a8fecab6b24df13f0329c39eed7bc1e1bd Mon Sep 17 00:00:00 2001 From: Matthew Hirst Date: Fri, 20 Nov 2020 13:43:06 +0200 Subject: [PATCH 1/5] Initial work on allowing different evaluators. --- lib/jquery_query_builder/evaluator.rb | 27 +------ .../evaluators/boolean.rb | 30 ++++++++ .../evaluators/boolean/operator.rb | 52 +++++++++++++ .../boolean/operators/begins_with.rb | 13 ++++ .../evaluators/boolean/operators/between.rb | 13 ++++ .../evaluators/boolean/operators/contains.rb | 14 ++++ .../evaluators/boolean/operators/ends_with.rb | 13 ++++ .../evaluators/boolean/operators/equal.rb | 13 ++++ .../evaluators/boolean/operators/greater.rb | 13 ++++ .../boolean/operators/greater_or_equal.rb | 13 ++++ .../evaluators/boolean/operators/in.rb | 13 ++++ .../evaluators/boolean/operators/is_empty.rb | 13 ++++ .../boolean/operators/is_not_empty.rb | 13 ++++ .../boolean/operators/is_not_null.rb | 13 ++++ .../evaluators/boolean/operators/is_null.rb | 13 ++++ .../evaluators/boolean/operators/less.rb | 13 ++++ .../boolean/operators/less_or_equal.rb | 13 ++++ .../boolean/operators/not_begins_with.rb | 13 ++++ .../boolean/operators/not_between.rb | 13 ++++ .../boolean/operators/not_contains.rb | 13 ++++ .../boolean/operators/not_ends_with.rb | 13 ++++ .../evaluators/boolean/operators/not_equal.rb | 13 ++++ .../evaluators/boolean/operators/not_in.rb | 13 ++++ .../evaluators/boolean/rule.rb | 73 +++++++++++++++++++ .../evaluators/boolean/rule_group.rb | 30 ++++++++ lib/jquery_query_builder/evaluators/sql.rb | 7 ++ lib/jquery_query_builder/operator.rb | 48 ------------ .../operators/begins_with.rb | 9 --- lib/jquery_query_builder/operators/between.rb | 9 --- .../operators/contains.rb | 10 --- .../operators/ends_with.rb | 9 --- lib/jquery_query_builder/operators/equal.rb | 9 --- lib/jquery_query_builder/operators/greater.rb | 9 --- .../operators/greater_or_equal.rb | 9 --- lib/jquery_query_builder/operators/in.rb | 9 --- .../operators/is_empty.rb | 9 --- .../operators/is_not_empty.rb | 9 --- .../operators/is_not_null.rb | 9 --- lib/jquery_query_builder/operators/is_null.rb | 9 --- lib/jquery_query_builder/operators/less.rb | 9 --- .../operators/less_or_equal.rb | 9 --- .../operators/not_begins_with.rb | 9 --- .../operators/not_between.rb | 9 --- .../operators/not_contains.rb | 9 --- .../operators/not_ends_with.rb | 9 --- .../operators/not_equal.rb | 9 --- lib/jquery_query_builder/operators/not_in.rb | 9 --- lib/jquery_query_builder/rule.rb | 69 ------------------ lib/jquery_query_builder/rule_group.rb | 26 ------- 49 files changed, 455 insertions(+), 349 deletions(-) create mode 100644 lib/jquery_query_builder/evaluators/boolean.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operator.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/begins_with.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/between.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/contains.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/ends_with.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/equal.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/greater.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/greater_or_equal.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/in.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/is_empty.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/is_not_empty.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/is_not_null.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/is_null.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/less.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/less_or_equal.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/not_begins_with.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/not_between.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/not_contains.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/not_ends_with.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/not_equal.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/operators/not_in.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/rule.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/rule_group.rb create mode 100644 lib/jquery_query_builder/evaluators/sql.rb delete mode 100644 lib/jquery_query_builder/operator.rb delete mode 100644 lib/jquery_query_builder/operators/begins_with.rb delete mode 100644 lib/jquery_query_builder/operators/between.rb delete mode 100644 lib/jquery_query_builder/operators/contains.rb delete mode 100644 lib/jquery_query_builder/operators/ends_with.rb delete mode 100644 lib/jquery_query_builder/operators/equal.rb delete mode 100644 lib/jquery_query_builder/operators/greater.rb delete mode 100644 lib/jquery_query_builder/operators/greater_or_equal.rb delete mode 100644 lib/jquery_query_builder/operators/in.rb delete mode 100644 lib/jquery_query_builder/operators/is_empty.rb delete mode 100644 lib/jquery_query_builder/operators/is_not_empty.rb delete mode 100644 lib/jquery_query_builder/operators/is_not_null.rb delete mode 100644 lib/jquery_query_builder/operators/is_null.rb delete mode 100644 lib/jquery_query_builder/operators/less.rb delete mode 100644 lib/jquery_query_builder/operators/less_or_equal.rb delete mode 100644 lib/jquery_query_builder/operators/not_begins_with.rb delete mode 100644 lib/jquery_query_builder/operators/not_between.rb delete mode 100644 lib/jquery_query_builder/operators/not_contains.rb delete mode 100644 lib/jquery_query_builder/operators/not_ends_with.rb delete mode 100644 lib/jquery_query_builder/operators/not_equal.rb delete mode 100644 lib/jquery_query_builder/operators/not_in.rb delete mode 100644 lib/jquery_query_builder/rule.rb delete mode 100644 lib/jquery_query_builder/rule_group.rb diff --git a/lib/jquery_query_builder/evaluator.rb b/lib/jquery_query_builder/evaluator.rb index 8cb6489..bb55115 100644 --- a/lib/jquery_query_builder/evaluator.rb +++ b/lib/jquery_query_builder/evaluator.rb @@ -1,30 +1,7 @@ -require 'active_support/core_ext/hash/indifferent_access' -require 'active_support/core_ext/object/blank' -require 'active_support/core_ext/string/inflections' -require 'jquery_query_builder/operator' -require 'jquery_query_builder/rule_group' -require 'jquery_query_builder/rule' -require 'json' +require 'jquery_query_builder/evaluators/boolean' module JqueryQueryBuilder - class Evaluator - attr_accessor :parsed_rule_set - def initialize(rule_set) - if rule_set.is_a? String - #assuming the json was passed in - self.parsed_rule_set = JSON.parse(rule_set) - else - self.parsed_rule_set = rule_set - end - end - - def get_matching_objects(objects) - objects.select{|o| object_matches_rules?(o)} - end - - def object_matches_rules?(object) - RuleGroup.new(parsed_rule_set).evaluate(object) - end + class Evaluator < Evaluators::Boolean end end diff --git a/lib/jquery_query_builder/evaluators/boolean.rb b/lib/jquery_query_builder/evaluators/boolean.rb new file mode 100644 index 0000000..89dea94 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean.rb @@ -0,0 +1,30 @@ +require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/string/inflections' +require 'jquery_query_builder/evaluators/boolean/operator' +require 'jquery_query_builder/evaluators/boolean/rule_group' +require 'jquery_query_builder/evaluators/boolean/rule' + +module JqueryQueryBuilder + module Evaluators + class Boolean < JqueryQueryBuilder::Evaluator + attr_accessor :parsed_rule_set + def initialize(rule_set) + if rule_set.is_a? String + #assuming the json was passed in + self.parsed_rule_set = JSON.parse(rule_set) + else + self.parsed_rule_set = rule_set + end + end + + def get_matching_objects(objects) + objects.select{|o| object_matches_rules?(o)} + end + + def object_matches_rules?(object) + RuleGroup.new(parsed_rule_set).evaluate(object) + end + end + end +end \ No newline at end of file diff --git a/lib/jquery_query_builder/evaluators/boolean/operator.rb b/lib/jquery_query_builder/evaluators/boolean/operator.rb new file mode 100644 index 0000000..7b5e945 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operator.rb @@ -0,0 +1,52 @@ +#require all the operators +Dir[File.join(File.dirname(__FILE__) + '/operators', "**/*.rb")].each do |f| + require f +end + +module JqueryQueryBuilder + module Evaluators + module Boolean + class Operator + SPECIAL_CASE_MAP = { + } + + def self.get_operator_class(operator) + operator_class = SPECIAL_CASE_MAP[operator] || operator.camelize + + begin + operator_class = "#{operator_module}::#{operator_class}".constantize + rescue NameError + raise "Unknown operator #{operator} used." + end + end + + def self.operator_module + "JqueryQueryBuilder::Operators" + end + end + end + end +end + +__END__ + +equal +not_equal +in +not_in +less +less_or_equal +greater +greater_or_equal +between +not_between +begins_with +not_begins_with +contains +not_contains +ends_with +not_ends_with +is_empty +is_not_empty +is_null +is_not_null diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/begins_with.rb b/lib/jquery_query_builder/evaluators/boolean/operators/begins_with.rb new file mode 100644 index 0000000..91640ac --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/begins_with.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class BeginsWith + def evaluate(left, right) + left.start_with?(right) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/between.rb b/lib/jquery_query_builder/evaluators/boolean/operators/between.rb new file mode 100644 index 0000000..a9ae3c3 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/between.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class Between + def evaluate(input, bounds) + input > bounds[0] && input < bounds[1] + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/contains.rb b/lib/jquery_query_builder/evaluators/boolean/operators/contains.rb new file mode 100644 index 0000000..53188d0 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/contains.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class Contains + def evaluate(left, right) + return false if left.nil? + left.include?(right) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/ends_with.rb b/lib/jquery_query_builder/evaluators/boolean/operators/ends_with.rb new file mode 100644 index 0000000..2b944ff --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/ends_with.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class EndsWith + def evaluate(left, right) + left.end_with?(right) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/equal.rb b/lib/jquery_query_builder/evaluators/boolean/operators/equal.rb new file mode 100644 index 0000000..709aea2 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/equal.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class Equal + def evaluate(left, right) + left == right + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/greater.rb b/lib/jquery_query_builder/evaluators/boolean/operators/greater.rb new file mode 100644 index 0000000..67787e3 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/greater.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class Greater + def evaluate(left, right) + left > right + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/greater_or_equal.rb b/lib/jquery_query_builder/evaluators/boolean/operators/greater_or_equal.rb new file mode 100644 index 0000000..6caf193 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/greater_or_equal.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class GreaterOrEqual + def evaluate(left, right) + left >= right + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/in.rb b/lib/jquery_query_builder/evaluators/boolean/operators/in.rb new file mode 100644 index 0000000..c85b98a --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/in.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class In + def evaluate(left, right) + right.include?(left) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/is_empty.rb b/lib/jquery_query_builder/evaluators/boolean/operators/is_empty.rb new file mode 100644 index 0000000..cdefb3a --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/is_empty.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class IsEmpty + def evaluate(input, value) + input.blank? + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/is_not_empty.rb b/lib/jquery_query_builder/evaluators/boolean/operators/is_not_empty.rb new file mode 100644 index 0000000..f89a5e4 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/is_not_empty.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class IsNotEmpty + def evaluate(input, value) + input.present? + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/is_not_null.rb b/lib/jquery_query_builder/evaluators/boolean/operators/is_not_null.rb new file mode 100644 index 0000000..8c04a88 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/is_not_null.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class IsNotNull + def evaluate(input, value) + !input.nil? + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/is_null.rb b/lib/jquery_query_builder/evaluators/boolean/operators/is_null.rb new file mode 100644 index 0000000..fec176c --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/is_null.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class IsNull + def evaluate(input, value) + input.nil? + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/less.rb b/lib/jquery_query_builder/evaluators/boolean/operators/less.rb new file mode 100644 index 0000000..170103d --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/less.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class Less + def evaluate(left, right) + left < right + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/less_or_equal.rb b/lib/jquery_query_builder/evaluators/boolean/operators/less_or_equal.rb new file mode 100644 index 0000000..0615c26 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/less_or_equal.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class LessOrEqual + def evaluate(left, right) + left <= right + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/not_begins_with.rb b/lib/jquery_query_builder/evaluators/boolean/operators/not_begins_with.rb new file mode 100644 index 0000000..4b3e0d6 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/not_begins_with.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class NotBeginsWith + def evaluate(left, right) + !left.start_with?(right) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/not_between.rb b/lib/jquery_query_builder/evaluators/boolean/operators/not_between.rb new file mode 100644 index 0000000..bc5fdae --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/not_between.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class NotBetween + def evaluate(input, bounds) + input <= bounds[0] || input >= bounds[1] + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/not_contains.rb b/lib/jquery_query_builder/evaluators/boolean/operators/not_contains.rb new file mode 100644 index 0000000..597ded6 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/not_contains.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class NotContains + def evaluate(left, right) + !left.include?(right) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/not_ends_with.rb b/lib/jquery_query_builder/evaluators/boolean/operators/not_ends_with.rb new file mode 100644 index 0000000..563bf2c --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/not_ends_with.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class NotEndsWith + def evaluate(left, right) + !left.end_with?(right) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/not_equal.rb b/lib/jquery_query_builder/evaluators/boolean/operators/not_equal.rb new file mode 100644 index 0000000..e187051 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/not_equal.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class NotEqual + def evaluate(left, right) + left != right + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/operators/not_in.rb b/lib/jquery_query_builder/evaluators/boolean/operators/not_in.rb new file mode 100644 index 0000000..c6eaa33 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/operators/not_in.rb @@ -0,0 +1,13 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + module Operators + class NotIn + def evaluate(left, right) + !right.include?(left) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/rule.rb b/lib/jquery_query_builder/evaluators/boolean/rule.rb new file mode 100644 index 0000000..ddf3477 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/rule.rb @@ -0,0 +1,73 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + class Rule + attr_accessor :id, :field, :type, :input, :operator, :value + def initialize(rule_hash) + self.id = rule_hash['id'] + self.field = rule_hash['field'] + self.type = rule_hash['type'] + self.input = rule_hash['input'] + self.operator = rule_hash['operator'] + self.value = rule_hash['value'] + end + + def evaluate(object) + get_operator.evaluate(get_input(object), get_value) + end + + def get_operator + JqueryQueryBuilder::Operator.get_operator_class(operator).new + end + + def get_input(object) + fields = field.split('.') + result = object + steps = fields.length + fields.each_with_index do |field, i| + last_step = i == steps - 1 + result = result[field] + result = result.first if(result.is_a?(Array) && !last_step) + break if result.nil? + end + if result.is_a? Array + result.map{|v| typecast_value(v)} + else + typecast_value(result) + end + end + + def get_value + if value.is_a? Array + value.map{|v| typecast_value(v)} + else + typecast_value(value) + end + end + + def typecast_value(value_to_cast) + return nil if value_to_cast.nil? + + case type + when 'string' + value_to_cast.to_s + when 'integer' + value_to_cast.to_i + when 'double' + value_to_cast.to_f + when 'date' + value_to_cast.is_a?(String) ? Date.parse(value_to_cast) : value_to_cast + when 'time' + value_to_cast.is_a?(String) ? Time.parse(value_to_cast) : value_to_cast + when 'datetime' + value_to_cast.is_a?(String) ? DateTime.parse(value_to_cast) : value_to_cast + when 'boolean' + value_to_cast == 'Yes' || value_to_cast == 'yes' || value_to_cast == 'True' || value_to_cast == 'true' || value_to_cast == true + else + value_to_cast + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/boolean/rule_group.rb b/lib/jquery_query_builder/evaluators/boolean/rule_group.rb new file mode 100644 index 0000000..87045e4 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/rule_group.rb @@ -0,0 +1,30 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + class RuleGroup + attr_accessor :condition, :rules + def initialize(rule_group_hash) + self.condition = rule_group_hash['condition'] + self.rules = rule_group_hash['rules'] + end + + def evaluate(object) + case condition + when "AND" + rules.all?{|rule| get_rule_object(rule).evaluate(object) } + when "OR" + rules.any?{|rule| get_rule_object(rule).evaluate(object) } + end + end + + def get_rule_object(rule) + if rule['rules'].present? + RuleGroup.new(rule) + else + Rule.new(rule) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/evaluators/sql.rb b/lib/jquery_query_builder/evaluators/sql.rb new file mode 100644 index 0000000..1d3e407 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/sql.rb @@ -0,0 +1,7 @@ +module JqueryQueryBuilder + module Evaluators + class Sql < JqueryQueryBuilder::Evaluator + + end + end +end \ No newline at end of file diff --git a/lib/jquery_query_builder/operator.rb b/lib/jquery_query_builder/operator.rb deleted file mode 100644 index 4033f2e..0000000 --- a/lib/jquery_query_builder/operator.rb +++ /dev/null @@ -1,48 +0,0 @@ -#require all the operators -Dir[File.join(File.dirname(__FILE__) + '/operators', "**/*.rb")].each do |f| - require f -end - -module JqueryQueryBuilder - class Operator - SPECIAL_CASE_MAP = { - } - - def self.get_operator_class(operator) - operator_class = SPECIAL_CASE_MAP[operator] || operator.camelize - - begin - operator_class = "#{operator_module}::#{operator_class}".constantize - rescue NameError - raise "Unknown operator #{operator} used." - end - end - - def self.operator_module - "JqueryQueryBuilder::Operators" - end - end -end - -__END__ - -equal -not_equal -in -not_in -less -less_or_equal -greater -greater_or_equal -between -not_between -begins_with -not_begins_with -contains -not_contains -ends_with -not_ends_with -is_empty -is_not_empty -is_null -is_not_null diff --git a/lib/jquery_query_builder/operators/begins_with.rb b/lib/jquery_query_builder/operators/begins_with.rb deleted file mode 100644 index 4dc7b72..0000000 --- a/lib/jquery_query_builder/operators/begins_with.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class BeginsWith - def evaluate(left, right) - left.start_with?(right) - end - end - end -end diff --git a/lib/jquery_query_builder/operators/between.rb b/lib/jquery_query_builder/operators/between.rb deleted file mode 100644 index 8e83645..0000000 --- a/lib/jquery_query_builder/operators/between.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class Between - def evaluate(input, bounds) - input > bounds[0] && input < bounds[1] - end - end - end -end diff --git a/lib/jquery_query_builder/operators/contains.rb b/lib/jquery_query_builder/operators/contains.rb deleted file mode 100644 index da079d5..0000000 --- a/lib/jquery_query_builder/operators/contains.rb +++ /dev/null @@ -1,10 +0,0 @@ -module JqueryQueryBuilder - module Operators - class Contains - def evaluate(left, right) - return false if left.nil? - left.include?(right) - end - end - end -end diff --git a/lib/jquery_query_builder/operators/ends_with.rb b/lib/jquery_query_builder/operators/ends_with.rb deleted file mode 100644 index b990ac8..0000000 --- a/lib/jquery_query_builder/operators/ends_with.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class EndsWith - def evaluate(left, right) - left.end_with?(right) - end - end - end -end diff --git a/lib/jquery_query_builder/operators/equal.rb b/lib/jquery_query_builder/operators/equal.rb deleted file mode 100644 index 294a5e6..0000000 --- a/lib/jquery_query_builder/operators/equal.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class Equal - def evaluate(left, right) - left == right - end - end - end -end diff --git a/lib/jquery_query_builder/operators/greater.rb b/lib/jquery_query_builder/operators/greater.rb deleted file mode 100644 index d5134c7..0000000 --- a/lib/jquery_query_builder/operators/greater.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class Greater - def evaluate(left, right) - left > right - end - end - end -end diff --git a/lib/jquery_query_builder/operators/greater_or_equal.rb b/lib/jquery_query_builder/operators/greater_or_equal.rb deleted file mode 100644 index 1c7133b..0000000 --- a/lib/jquery_query_builder/operators/greater_or_equal.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class GreaterOrEqual - def evaluate(left, right) - left >= right - end - end - end -end diff --git a/lib/jquery_query_builder/operators/in.rb b/lib/jquery_query_builder/operators/in.rb deleted file mode 100644 index b971316..0000000 --- a/lib/jquery_query_builder/operators/in.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class In - def evaluate(left, right) - right.include?(left) - end - end - end -end diff --git a/lib/jquery_query_builder/operators/is_empty.rb b/lib/jquery_query_builder/operators/is_empty.rb deleted file mode 100644 index 7d1b955..0000000 --- a/lib/jquery_query_builder/operators/is_empty.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class IsEmpty - def evaluate(input, value) - input.blank? - end - end - end -end diff --git a/lib/jquery_query_builder/operators/is_not_empty.rb b/lib/jquery_query_builder/operators/is_not_empty.rb deleted file mode 100644 index ae6d37d..0000000 --- a/lib/jquery_query_builder/operators/is_not_empty.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class IsNotEmpty - def evaluate(input, value) - input.present? - end - end - end -end diff --git a/lib/jquery_query_builder/operators/is_not_null.rb b/lib/jquery_query_builder/operators/is_not_null.rb deleted file mode 100644 index fa55d71..0000000 --- a/lib/jquery_query_builder/operators/is_not_null.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class IsNotNull - def evaluate(input, value) - !input.nil? - end - end - end -end diff --git a/lib/jquery_query_builder/operators/is_null.rb b/lib/jquery_query_builder/operators/is_null.rb deleted file mode 100644 index 9835438..0000000 --- a/lib/jquery_query_builder/operators/is_null.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class IsNull - def evaluate(input, value) - input.nil? - end - end - end -end diff --git a/lib/jquery_query_builder/operators/less.rb b/lib/jquery_query_builder/operators/less.rb deleted file mode 100644 index 5a0811c..0000000 --- a/lib/jquery_query_builder/operators/less.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class Less - def evaluate(left, right) - left < right - end - end - end -end diff --git a/lib/jquery_query_builder/operators/less_or_equal.rb b/lib/jquery_query_builder/operators/less_or_equal.rb deleted file mode 100644 index e6eafff..0000000 --- a/lib/jquery_query_builder/operators/less_or_equal.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class LessOrEqual - def evaluate(left, right) - left <= right - end - end - end -end diff --git a/lib/jquery_query_builder/operators/not_begins_with.rb b/lib/jquery_query_builder/operators/not_begins_with.rb deleted file mode 100644 index e1d22a4..0000000 --- a/lib/jquery_query_builder/operators/not_begins_with.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class NotBeginsWith - def evaluate(left, right) - !left.start_with?(right) - end - end - end -end diff --git a/lib/jquery_query_builder/operators/not_between.rb b/lib/jquery_query_builder/operators/not_between.rb deleted file mode 100644 index 76f4dfa..0000000 --- a/lib/jquery_query_builder/operators/not_between.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class NotBetween - def evaluate(input, bounds) - input <= bounds[0] || input >= bounds[1] - end - end - end -end diff --git a/lib/jquery_query_builder/operators/not_contains.rb b/lib/jquery_query_builder/operators/not_contains.rb deleted file mode 100644 index 778d8cf..0000000 --- a/lib/jquery_query_builder/operators/not_contains.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class NotContains - def evaluate(left, right) - !left.include?(right) - end - end - end -end diff --git a/lib/jquery_query_builder/operators/not_ends_with.rb b/lib/jquery_query_builder/operators/not_ends_with.rb deleted file mode 100644 index 8c9b6ad..0000000 --- a/lib/jquery_query_builder/operators/not_ends_with.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class NotEndsWith - def evaluate(left, right) - !left.end_with?(right) - end - end - end -end diff --git a/lib/jquery_query_builder/operators/not_equal.rb b/lib/jquery_query_builder/operators/not_equal.rb deleted file mode 100644 index bb3a325..0000000 --- a/lib/jquery_query_builder/operators/not_equal.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class NotEqual - def evaluate(left, right) - left != right - end - end - end -end diff --git a/lib/jquery_query_builder/operators/not_in.rb b/lib/jquery_query_builder/operators/not_in.rb deleted file mode 100644 index 28c8d40..0000000 --- a/lib/jquery_query_builder/operators/not_in.rb +++ /dev/null @@ -1,9 +0,0 @@ -module JqueryQueryBuilder - module Operators - class NotIn - def evaluate(left, right) - !right.include?(left) - end - end - end -end diff --git a/lib/jquery_query_builder/rule.rb b/lib/jquery_query_builder/rule.rb deleted file mode 100644 index 93f3eca..0000000 --- a/lib/jquery_query_builder/rule.rb +++ /dev/null @@ -1,69 +0,0 @@ -module JqueryQueryBuilder - class Rule - attr_accessor :id, :field, :type, :input, :operator, :value - def initialize(rule_hash) - self.id = rule_hash['id'] - self.field = rule_hash['field'] - self.type = rule_hash['type'] - self.input = rule_hash['input'] - self.operator = rule_hash['operator'] - self.value = rule_hash['value'] - end - - def evaluate(object) - get_operator.evaluate(get_input(object), get_value) - end - - def get_operator - JqueryQueryBuilder::Operator.get_operator_class(operator).new - end - - def get_input(object) - fields = field.split('.') - result = object - steps = fields.length - fields.each_with_index do |field, i| - last_step = i == steps - 1 - result = result[field] - result = result.first if(result.is_a?(Array) && !last_step) - break if result.nil? - end - if result.is_a? Array - result.map{|v| typecast_value(v)} - else - typecast_value(result) - end - end - - def get_value - if value.is_a? Array - value.map{|v| typecast_value(v)} - else - typecast_value(value) - end - end - - def typecast_value(value_to_cast) - return nil if value_to_cast.nil? - - case type - when 'string' - value_to_cast.to_s - when 'integer' - value_to_cast.to_i - when 'double' - value_to_cast.to_f - when 'date' - value_to_cast.is_a?(String) ? Date.parse(value_to_cast) : value_to_cast - when 'time' - value_to_cast.is_a?(String) ? Time.parse(value_to_cast) : value_to_cast - when 'datetime' - value_to_cast.is_a?(String) ? DateTime.parse(value_to_cast) : value_to_cast - when 'boolean' - value_to_cast == 'Yes' || value_to_cast == 'yes' || value_to_cast == 'True' || value_to_cast == 'true' || value_to_cast == true - else - value_to_cast - end - end - end -end diff --git a/lib/jquery_query_builder/rule_group.rb b/lib/jquery_query_builder/rule_group.rb deleted file mode 100644 index b98ae87..0000000 --- a/lib/jquery_query_builder/rule_group.rb +++ /dev/null @@ -1,26 +0,0 @@ -module JqueryQueryBuilder - class RuleGroup - attr_accessor :condition, :rules - def initialize(rule_group_hash) - self.condition = rule_group_hash['condition'] - self.rules = rule_group_hash['rules'] - end - - def evaluate(object) - case condition - when "AND" - rules.all?{|rule| get_rule_object(rule).evaluate(object) } - when "OR" - rules.any?{|rule| get_rule_object(rule).evaluate(object) } - end - end - - def get_rule_object(rule) - if rule['rules'].present? - RuleGroup.new(rule) - else - Rule.new(rule) - end - end - end -end From c8b1d331276c0c68cba69a09f2fbfaa46ee31a18 Mon Sep 17 00:00:00 2001 From: Matthew Hirst Date: Sat, 11 Sep 2021 16:33:54 +0200 Subject: [PATCH 2/5] Correctly use evaluator class like a factory. --- lib/jquery_query_builder/evaluator.rb | 5 ++++- lib/jquery_query_builder/evaluators/boolean.rb | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/lib/jquery_query_builder/evaluator.rb b/lib/jquery_query_builder/evaluator.rb index bb55115..47d5dfa 100644 --- a/lib/jquery_query_builder/evaluator.rb +++ b/lib/jquery_query_builder/evaluator.rb @@ -1,7 +1,10 @@ require 'jquery_query_builder/evaluators/boolean' module JqueryQueryBuilder - class Evaluator < Evaluators::Boolean + class Evaluator + def initialize(rule_set, evaluator_class: Evaluators::Boolean) + evaluator_class.new(rule_set) + end end end diff --git a/lib/jquery_query_builder/evaluators/boolean.rb b/lib/jquery_query_builder/evaluators/boolean.rb index 89dea94..35382ef 100644 --- a/lib/jquery_query_builder/evaluators/boolean.rb +++ b/lib/jquery_query_builder/evaluators/boolean.rb @@ -7,7 +7,7 @@ module JqueryQueryBuilder module Evaluators - class Boolean < JqueryQueryBuilder::Evaluator + class Boolean attr_accessor :parsed_rule_set def initialize(rule_set) if rule_set.is_a? String From c14134604575806407b9e30f5125b98238177769 Mon Sep 17 00:00:00 2001 From: Matthew Hirst Date: Sun, 12 Sep 2021 02:08:41 +0200 Subject: [PATCH 3/5] Move all existing evaluator logic into a boolean evaluator module. Have evaluator default to using the boolean evaluator. Make Rule and RuleGroup isolated objects outside the evaluator. Add RuleEvaluator and RuleGroup evaluator classes to handle evaluation. Mix test around to fit new layout. --- lib/jquery_query_builder/evaluator.rb | 22 +++++- .../evaluators/boolean.rb | 30 -------- .../evaluators/boolean/evaluator.rb | 26 +++++++ .../evaluators/boolean/operator.rb | 2 +- .../evaluators/boolean/rule.rb | 73 ------------------ .../evaluators/boolean/rule_evaluator.rb | 23 ++++++ .../evaluators/boolean/rule_group.rb | 30 -------- .../boolean/rule_group_evaluator.rb | 34 ++++++++ lib/jquery_query_builder/evaluators/sql.rb | 7 -- lib/jquery_query_builder/rule.rb | 61 +++++++++++++++ lib/jquery_query_builder/rule_group.rb | 19 +++++ spec/jquery_query_builder/evaluator_spec.rb | 64 +++++++-------- .../{ => evaluators/boolean}/operator_spec.rb | 6 +- .../boolean}/operators/begins_with_spec.rb | 2 +- .../boolean}/operators/between_spec.rb | 2 +- .../boolean}/operators/contains_spec.rb | 2 +- .../boolean}/operators/ends_with_spec.rb | 2 +- .../boolean}/operators/equal_spec.rb | 2 +- .../operators/greater_or_equal_spec.rb | 2 +- .../boolean}/operators/greater_spec.rb | 2 +- .../boolean}/operators/in_spec.rb | 2 +- .../boolean}/operators/is_empty_spec.rb | 2 +- .../boolean}/operators/is_not_empty_spec.rb | 2 +- .../boolean}/operators/is_not_null_spec.rb | 2 +- .../boolean}/operators/is_null_spec.rb | 2 +- .../boolean}/operators/less_or_equal_spec.rb | 2 +- .../boolean}/operators/less_spec.rb | 2 +- .../operators/not_begins_with_spec.rb | 2 +- .../boolean}/operators/not_between_spec.rb | 2 +- .../boolean}/operators/not_contains_spec.rb | 2 +- .../boolean}/operators/not_ends_with_spec.rb | 2 +- .../boolean}/operators/not_equal_spec.rb | 2 +- .../boolean}/operators/not_in_spec.rb | 2 +- .../evaluators/boolean/rule_evaluator_spec.rb | 32 ++++++++ .../boolean/rule_group_evaluator_spec.rb | 77 +++++++++++++++++++ spec/jquery_query_builder/rule_group_spec.rb | 38 +-------- spec/jquery_query_builder/rule_spec.rb | 25 ------ 37 files changed, 352 insertions(+), 257 deletions(-) delete mode 100644 lib/jquery_query_builder/evaluators/boolean.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/evaluator.rb delete mode 100644 lib/jquery_query_builder/evaluators/boolean/rule.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/rule_evaluator.rb delete mode 100644 lib/jquery_query_builder/evaluators/boolean/rule_group.rb create mode 100644 lib/jquery_query_builder/evaluators/boolean/rule_group_evaluator.rb delete mode 100644 lib/jquery_query_builder/evaluators/sql.rb create mode 100644 lib/jquery_query_builder/rule.rb create mode 100644 lib/jquery_query_builder/rule_group.rb rename spec/jquery_query_builder/{ => evaluators/boolean}/operator_spec.rb (59%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/begins_with_spec.rb (83%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/between_spec.rb (83%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/contains_spec.rb (84%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/ends_with_spec.rb (83%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/equal_spec.rb (83%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/greater_or_equal_spec.rb (86%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/greater_spec.rb (83%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/in_spec.rb (84%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/is_empty_spec.rb (82%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/is_not_empty_spec.rb (81%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/is_not_null_spec.rb (82%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/is_null_spec.rb (82%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/less_or_equal_spec.rb (86%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/less_spec.rb (83%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/not_begins_with_spec.rb (82%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/not_between_spec.rb (82%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/not_contains_spec.rb (83%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/not_ends_with_spec.rb (83%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/not_equal_spec.rb (82%) rename spec/jquery_query_builder/{ => evaluators/boolean}/operators/not_in_spec.rb (83%) create mode 100644 spec/jquery_query_builder/evaluators/boolean/rule_evaluator_spec.rb create mode 100644 spec/jquery_query_builder/evaluators/boolean/rule_group_evaluator_spec.rb diff --git a/lib/jquery_query_builder/evaluator.rb b/lib/jquery_query_builder/evaluator.rb index 47d5dfa..eea27d7 100644 --- a/lib/jquery_query_builder/evaluator.rb +++ b/lib/jquery_query_builder/evaluator.rb @@ -1,10 +1,26 @@ -require 'jquery_query_builder/evaluators/boolean' +require 'json' +require 'jquery_query_builder/rule' +require 'jquery_query_builder/rule_group' +require 'jquery_query_builder/evaluators/boolean/evaluator' +require 'active_support/core_ext/module/delegation' module JqueryQueryBuilder class Evaluator - def initialize(rule_set, evaluator_class: Evaluators::Boolean) - evaluator_class.new(rule_set) + attr_accessor :parsed_rule_set, :evaluator + def initialize(raw_rule_set, evaluator_class: Evaluators::Boolean::Evaluator) + if raw_rule_set.is_a? String + #assuming the json was passed in + self.parsed_rule_set = JSON.parse(raw_rule_set) + else + self.parsed_rule_set = raw_rule_set + end + + rule_set = RuleGroup.new(parsed_rule_set) + self.evaluator = evaluator_class.new(rule_set) end + + # All evaluators must implement + delegate :get_matching_objects, :object_matches_rules?, to: :evaluator end end diff --git a/lib/jquery_query_builder/evaluators/boolean.rb b/lib/jquery_query_builder/evaluators/boolean.rb deleted file mode 100644 index 35382ef..0000000 --- a/lib/jquery_query_builder/evaluators/boolean.rb +++ /dev/null @@ -1,30 +0,0 @@ -require 'active_support/core_ext/hash/indifferent_access' -require 'active_support/core_ext/object/blank' -require 'active_support/core_ext/string/inflections' -require 'jquery_query_builder/evaluators/boolean/operator' -require 'jquery_query_builder/evaluators/boolean/rule_group' -require 'jquery_query_builder/evaluators/boolean/rule' - -module JqueryQueryBuilder - module Evaluators - class Boolean - attr_accessor :parsed_rule_set - def initialize(rule_set) - if rule_set.is_a? String - #assuming the json was passed in - self.parsed_rule_set = JSON.parse(rule_set) - else - self.parsed_rule_set = rule_set - end - end - - def get_matching_objects(objects) - objects.select{|o| object_matches_rules?(o)} - end - - def object_matches_rules?(object) - RuleGroup.new(parsed_rule_set).evaluate(object) - end - end - end -end \ No newline at end of file diff --git a/lib/jquery_query_builder/evaluators/boolean/evaluator.rb b/lib/jquery_query_builder/evaluators/boolean/evaluator.rb new file mode 100644 index 0000000..caacedb --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/evaluator.rb @@ -0,0 +1,26 @@ +require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/string/inflections' +require 'jquery_query_builder/evaluators/boolean/operator' +require 'jquery_query_builder/evaluators/boolean/rule_group_evaluator' + +module JqueryQueryBuilder + module Evaluators + module Boolean + class Evaluator + attr_accessor :rule_group + def initialize(rule_group) + self.rule_group = rule_group + end + + def get_matching_objects(objects) + objects.select{|o| object_matches_rules?(o)} + end + + def object_matches_rules?(object) + RuleGroupEvaluator.new(rule_group).evaluate(object) + end + end + end + end +end \ No newline at end of file diff --git a/lib/jquery_query_builder/evaluators/boolean/operator.rb b/lib/jquery_query_builder/evaluators/boolean/operator.rb index 7b5e945..24a5f9d 100644 --- a/lib/jquery_query_builder/evaluators/boolean/operator.rb +++ b/lib/jquery_query_builder/evaluators/boolean/operator.rb @@ -21,7 +21,7 @@ def self.get_operator_class(operator) end def self.operator_module - "JqueryQueryBuilder::Operators" + "JqueryQueryBuilder::Evaluators::Boolean::Operators" end end end diff --git a/lib/jquery_query_builder/evaluators/boolean/rule.rb b/lib/jquery_query_builder/evaluators/boolean/rule.rb deleted file mode 100644 index ddf3477..0000000 --- a/lib/jquery_query_builder/evaluators/boolean/rule.rb +++ /dev/null @@ -1,73 +0,0 @@ -module JqueryQueryBuilder - module Evaluators - module Boolean - class Rule - attr_accessor :id, :field, :type, :input, :operator, :value - def initialize(rule_hash) - self.id = rule_hash['id'] - self.field = rule_hash['field'] - self.type = rule_hash['type'] - self.input = rule_hash['input'] - self.operator = rule_hash['operator'] - self.value = rule_hash['value'] - end - - def evaluate(object) - get_operator.evaluate(get_input(object), get_value) - end - - def get_operator - JqueryQueryBuilder::Operator.get_operator_class(operator).new - end - - def get_input(object) - fields = field.split('.') - result = object - steps = fields.length - fields.each_with_index do |field, i| - last_step = i == steps - 1 - result = result[field] - result = result.first if(result.is_a?(Array) && !last_step) - break if result.nil? - end - if result.is_a? Array - result.map{|v| typecast_value(v)} - else - typecast_value(result) - end - end - - def get_value - if value.is_a? Array - value.map{|v| typecast_value(v)} - else - typecast_value(value) - end - end - - def typecast_value(value_to_cast) - return nil if value_to_cast.nil? - - case type - when 'string' - value_to_cast.to_s - when 'integer' - value_to_cast.to_i - when 'double' - value_to_cast.to_f - when 'date' - value_to_cast.is_a?(String) ? Date.parse(value_to_cast) : value_to_cast - when 'time' - value_to_cast.is_a?(String) ? Time.parse(value_to_cast) : value_to_cast - when 'datetime' - value_to_cast.is_a?(String) ? DateTime.parse(value_to_cast) : value_to_cast - when 'boolean' - value_to_cast == 'Yes' || value_to_cast == 'yes' || value_to_cast == 'True' || value_to_cast == 'true' || value_to_cast == true - else - value_to_cast - end - end - end - end - end -end diff --git a/lib/jquery_query_builder/evaluators/boolean/rule_evaluator.rb b/lib/jquery_query_builder/evaluators/boolean/rule_evaluator.rb new file mode 100644 index 0000000..3ff4295 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/rule_evaluator.rb @@ -0,0 +1,23 @@ +module JqueryQueryBuilder + module Evaluators + module Boolean + class RuleEvaluator + attr_accessor :rule + def initialize(rule) + self.rule = rule + end + + def evaluate(object) + input = rule.get_input(object) + value = rule.get_value + get_operator.evaluate(input, value) + end + + def get_operator + rule_operator = rule.operator + JqueryQueryBuilder::Evaluators::Boolean::Operator.get_operator_class(rule_operator).new + end + end + end + end +end \ No newline at end of file diff --git a/lib/jquery_query_builder/evaluators/boolean/rule_group.rb b/lib/jquery_query_builder/evaluators/boolean/rule_group.rb deleted file mode 100644 index 87045e4..0000000 --- a/lib/jquery_query_builder/evaluators/boolean/rule_group.rb +++ /dev/null @@ -1,30 +0,0 @@ -module JqueryQueryBuilder - module Evaluators - module Boolean - class RuleGroup - attr_accessor :condition, :rules - def initialize(rule_group_hash) - self.condition = rule_group_hash['condition'] - self.rules = rule_group_hash['rules'] - end - - def evaluate(object) - case condition - when "AND" - rules.all?{|rule| get_rule_object(rule).evaluate(object) } - when "OR" - rules.any?{|rule| get_rule_object(rule).evaluate(object) } - end - end - - def get_rule_object(rule) - if rule['rules'].present? - RuleGroup.new(rule) - else - Rule.new(rule) - end - end - end - end - end -end diff --git a/lib/jquery_query_builder/evaluators/boolean/rule_group_evaluator.rb b/lib/jquery_query_builder/evaluators/boolean/rule_group_evaluator.rb new file mode 100644 index 0000000..f23ef58 --- /dev/null +++ b/lib/jquery_query_builder/evaluators/boolean/rule_group_evaluator.rb @@ -0,0 +1,34 @@ +require 'jquery_query_builder/evaluators/boolean/rule_evaluator' + +module JqueryQueryBuilder + module Evaluators + module Boolean + class RuleGroupEvaluator + attr_accessor :rule_group + def initialize(rule_group) + self.rule_group = rule_group + end + + def evaluate(object) + rules = rule_group.rules + + case rule_group.condition + when "AND" + rules.all?{|rule| get_rule_evaluator(rule).evaluate(object) } + when "OR" + rules.any?{|rule| get_rule_evaluator(rule).evaluate(object) } + end + end + + def get_rule_evaluator(rule) + if rule.is_a?(RuleGroup) + RuleGroupEvaluator.new(rule) + else + RuleEvaluator.new(rule) + end + end + + end + end + end +end \ No newline at end of file diff --git a/lib/jquery_query_builder/evaluators/sql.rb b/lib/jquery_query_builder/evaluators/sql.rb deleted file mode 100644 index 1d3e407..0000000 --- a/lib/jquery_query_builder/evaluators/sql.rb +++ /dev/null @@ -1,7 +0,0 @@ -module JqueryQueryBuilder - module Evaluators - class Sql < JqueryQueryBuilder::Evaluator - - end - end -end \ No newline at end of file diff --git a/lib/jquery_query_builder/rule.rb b/lib/jquery_query_builder/rule.rb new file mode 100644 index 0000000..08d44f4 --- /dev/null +++ b/lib/jquery_query_builder/rule.rb @@ -0,0 +1,61 @@ +module JqueryQueryBuilder + class Rule + attr_accessor :id, :field, :type, :input, :operator, :value + def initialize(rule_hash) + self.id = rule_hash['id'] + self.field = rule_hash['field'] + self.type = rule_hash['type'] + self.input = rule_hash['input'] + self.operator = rule_hash['operator'] + self.value = rule_hash['value'] + end + + def get_input(object) + fields = field.split('.') + result = object + steps = fields.length + fields.each_with_index do |field, i| + last_step = i == steps - 1 + result = result[field] + result = result.first if(result.is_a?(Array) && !last_step) + break if result.nil? + end + if result.is_a? Array + result.map{|v| typecast_value(v)} + else + typecast_value(result) + end + end + + def get_value + if value.is_a? Array + value.map{|v| typecast_value(v)} + else + typecast_value(value) + end + end + + def typecast_value(value_to_cast) + return nil if value_to_cast.nil? + + case type + when 'string' + value_to_cast.to_s + when 'integer' + value_to_cast.to_i + when 'double' + value_to_cast.to_f + when 'date' + value_to_cast.is_a?(String) ? Date.parse(value_to_cast) : value_to_cast + when 'time' + value_to_cast.is_a?(String) ? Time.parse(value_to_cast) : value_to_cast + when 'datetime' + value_to_cast.is_a?(String) ? DateTime.parse(value_to_cast) : value_to_cast + when 'boolean' + value_to_cast == 'Yes' || value_to_cast == 'yes' || value_to_cast == 'True' || value_to_cast == 'true' || value_to_cast == true + else + value_to_cast + end + end + end +end diff --git a/lib/jquery_query_builder/rule_group.rb b/lib/jquery_query_builder/rule_group.rb new file mode 100644 index 0000000..5ed039b --- /dev/null +++ b/lib/jquery_query_builder/rule_group.rb @@ -0,0 +1,19 @@ +module JqueryQueryBuilder + class RuleGroup + attr_accessor :condition, :rules + def initialize(rule_group_hash) + self.condition = rule_group_hash['condition'] + self.rules = (rule_group_hash['rules'] || []).map do |rule| + get_rule_object(rule) + end + end + + def get_rule_object(rule) + if rule['rules'].present? + RuleGroup.new(rule) + else + Rule.new(rule) + end + end + end +end diff --git a/spec/jquery_query_builder/evaluator_spec.rb b/spec/jquery_query_builder/evaluator_spec.rb index 5f78f29..5d6c6d5 100644 --- a/spec/jquery_query_builder/evaluator_spec.rb +++ b/spec/jquery_query_builder/evaluator_spec.rb @@ -1,45 +1,49 @@ require 'spec_helper' describe JqueryQueryBuilder::Evaluator do - describe '#new' do - context 'with an object' do - it 'should initialize a new evaluator' do - evaluator = JqueryQueryBuilder::Evaluator.new({}) + context 'Boolean (default)' do + describe '#new' do + context 'with an object' do + it 'should initialize a new evaluator' do + evaluator = JqueryQueryBuilder::Evaluator.new({}) + end end - end - context 'with json' do - it 'should initialize a new evaluator' do - evaluator = JqueryQueryBuilder::Evaluator.new("{}") + context 'with json' do + it 'should initialize a new evaluator' do + evaluator = JqueryQueryBuilder::Evaluator.new("{}") + end end end - end - describe '#get_matching_objects' do - it 'should try match on each object' do - evaluator = JqueryQueryBuilder::Evaluator.new({}) - a = {one: 1} - b = {two: 2} - c = {three: 3} - expect(evaluator).to receive(:object_matches_rules?).with(a) - expect(evaluator).to receive(:object_matches_rules?).with(b) - expect(evaluator).to receive(:object_matches_rules?).with(c) - evaluator.get_matching_objects([a,b,c]) + describe '#get_matching_objects' do + it 'should try match on each object' do + evaluator = JqueryQueryBuilder::Evaluator.new({}) + a = {one: 1} + b = {two: 2} + c = {three: 3} + expect(evaluator.evaluator).to receive(:object_matches_rules?).with(a).and_call_original + expect(evaluator.evaluator).to receive(:object_matches_rules?).with(b).and_call_original + expect(evaluator.evaluator).to receive(:object_matches_rules?).with(c).and_call_original + result = evaluator.get_matching_objects([a,b,c]) + expect(result).to eq([]) + end end - end - describe '#object_matches_rules' do - it 'should create a new rule group and valuate it' do - rule_set = {} - object_to_match = {} + describe '#object_matches_rules' do + it 'should create a new rule group and valuate it' do + rule_set = {} + object_to_match = {} - evaluator = JqueryQueryBuilder::Evaluator.new(rule_set) - my_rule_group = JqueryQueryBuilder::RuleGroup.new(rule_set) - expect(JqueryQueryBuilder::RuleGroup).to receive(:new).with(rule_set).and_return(my_rule_group) + my_rule_group = JqueryQueryBuilder::RuleGroup.new(rule_set) + my_rule_group_evaluator = JqueryQueryBuilder::Evaluators::Boolean::RuleGroupEvaluator.new(my_rule_group) + expect(JqueryQueryBuilder::RuleGroup).to receive(:new).with(rule_set).and_return(my_rule_group) + expect(JqueryQueryBuilder::Evaluators::Boolean::RuleGroupEvaluator).to receive(:new).with(my_rule_group).and_return(my_rule_group_evaluator) - expect(my_rule_group).to receive(:evaluate).with(object_to_match) - - evaluator.object_matches_rules?(object_to_match) + evaluator = JqueryQueryBuilder::Evaluator.new(rule_set) + expect(my_rule_group_evaluator).to receive(:evaluate).with(object_to_match) + evaluator.object_matches_rules?(object_to_match) + end end end end diff --git a/spec/jquery_query_builder/operator_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operator_spec.rb similarity index 59% rename from spec/jquery_query_builder/operator_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operator_spec.rb index a6d9897..4e6e05d 100644 --- a/spec/jquery_query_builder/operator_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operator_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operator do +describe JqueryQueryBuilder::Evaluators::Boolean::Operator do let(:decimal_rule){ { 'id' => "Decimal_Question", @@ -24,8 +24,8 @@ describe '.get_operator_class' do it 'should return an operator class on the operator' do - expect(JqueryQueryBuilder::Operator.get_operator_class('equal').to_s).to eq('JqueryQueryBuilder::Operators::Equal') - expect(JqueryQueryBuilder::Operator.get_operator_class('not_equal').to_s).to eq('JqueryQueryBuilder::Operators::NotEqual') + expect(JqueryQueryBuilder::Evaluators::Boolean::Operator.get_operator_class('equal').to_s).to eq('JqueryQueryBuilder::Evaluators::Boolean::Operators::Equal') + expect(JqueryQueryBuilder::Evaluators::Boolean::Operator.get_operator_class('not_equal').to_s).to eq('JqueryQueryBuilder::Evaluators::Boolean::Operators::NotEqual') end end end diff --git a/spec/jquery_query_builder/operators/begins_with_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/begins_with_spec.rb similarity index 83% rename from spec/jquery_query_builder/operators/begins_with_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/begins_with_spec.rb index b0f037f..8237dab 100644 --- a/spec/jquery_query_builder/operators/begins_with_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/begins_with_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::BeginsWith do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::BeginsWith do describe '#evaluate' do context 'left begins with right' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/between_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/between_spec.rb similarity index 83% rename from spec/jquery_query_builder/operators/between_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/between_spec.rb index ca67be5..62f4f54 100644 --- a/spec/jquery_query_builder/operators/between_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/between_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::Between do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::Between do describe '#evaluate' do context 'input is between bounds' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/contains_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/contains_spec.rb similarity index 84% rename from spec/jquery_query_builder/operators/contains_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/contains_spec.rb index fe7e9ca..8adc22a 100644 --- a/spec/jquery_query_builder/operators/contains_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/contains_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::Contains do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::Contains do describe '#evaluate' do context 'left contains right' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/ends_with_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/ends_with_spec.rb similarity index 83% rename from spec/jquery_query_builder/operators/ends_with_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/ends_with_spec.rb index 8bd1229..729410b 100644 --- a/spec/jquery_query_builder/operators/ends_with_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/ends_with_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::EndsWith do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::EndsWith do describe '#evaluate' do context 'left ends with right' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/equal_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/equal_spec.rb similarity index 83% rename from spec/jquery_query_builder/operators/equal_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/equal_spec.rb index bbbe127..c089bb4 100644 --- a/spec/jquery_query_builder/operators/equal_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/equal_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::Equal do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::Equal do describe '#evaluate' do context 'left equals right' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/greater_or_equal_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/greater_or_equal_spec.rb similarity index 86% rename from spec/jquery_query_builder/operators/greater_or_equal_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/greater_or_equal_spec.rb index 2df4b70..0b0e627 100644 --- a/spec/jquery_query_builder/operators/greater_or_equal_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/greater_or_equal_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::GreaterOrEqual do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::GreaterOrEqual do describe '#evaluate' do context 'left equals right' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/greater_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/greater_spec.rb similarity index 83% rename from spec/jquery_query_builder/operators/greater_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/greater_spec.rb index 7dd02e3..f82a8e1 100644 --- a/spec/jquery_query_builder/operators/greater_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/greater_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::Greater do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::Greater do describe '#evaluate' do context 'left greater than right' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/in_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/in_spec.rb similarity index 84% rename from spec/jquery_query_builder/operators/in_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/in_spec.rb index 32af1ec..4f38ffa 100644 --- a/spec/jquery_query_builder/operators/in_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/in_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::In do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::In do describe '#evaluate' do context 'left is in right' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/is_empty_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/is_empty_spec.rb similarity index 82% rename from spec/jquery_query_builder/operators/is_empty_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/is_empty_spec.rb index 4b5b0ac..0f429d5 100644 --- a/spec/jquery_query_builder/operators/is_empty_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/is_empty_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::IsEmpty do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::IsEmpty do describe '#evaluate' do context 'input is empty' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/is_not_empty_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/is_not_empty_spec.rb similarity index 81% rename from spec/jquery_query_builder/operators/is_not_empty_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/is_not_empty_spec.rb index f6a2eda..ea173bf 100644 --- a/spec/jquery_query_builder/operators/is_not_empty_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/is_not_empty_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::IsNotEmpty do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::IsNotEmpty do describe '#evaluate' do context 'input is empty' do it 'should return false' do diff --git a/spec/jquery_query_builder/operators/is_not_null_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/is_not_null_spec.rb similarity index 82% rename from spec/jquery_query_builder/operators/is_not_null_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/is_not_null_spec.rb index abf6400..75b3424 100644 --- a/spec/jquery_query_builder/operators/is_not_null_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/is_not_null_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::IsNotNull do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::IsNotNull do describe '#evaluate' do context 'input is null' do it 'should return false' do diff --git a/spec/jquery_query_builder/operators/is_null_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/is_null_spec.rb similarity index 82% rename from spec/jquery_query_builder/operators/is_null_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/is_null_spec.rb index b8cf278..1b7ac14 100644 --- a/spec/jquery_query_builder/operators/is_null_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/is_null_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::IsNull do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::IsNull do describe '#evaluate' do context 'input is null' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/less_or_equal_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/less_or_equal_spec.rb similarity index 86% rename from spec/jquery_query_builder/operators/less_or_equal_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/less_or_equal_spec.rb index fb66e2d..c36e5dc 100644 --- a/spec/jquery_query_builder/operators/less_or_equal_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/less_or_equal_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::LessOrEqual do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::LessOrEqual do describe '#evaluate' do context 'left equals right' do it 'should return true' do diff --git a/spec/jquery_query_builder/operators/less_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/less_spec.rb similarity index 83% rename from spec/jquery_query_builder/operators/less_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/less_spec.rb index 77d0aee..678b3f6 100644 --- a/spec/jquery_query_builder/operators/less_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/less_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::Less do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::Less do describe '#evaluate' do context 'left greater than right' do it 'should return false' do diff --git a/spec/jquery_query_builder/operators/not_begins_with_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/not_begins_with_spec.rb similarity index 82% rename from spec/jquery_query_builder/operators/not_begins_with_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/not_begins_with_spec.rb index 3d982a3..e0d9b58 100644 --- a/spec/jquery_query_builder/operators/not_begins_with_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/not_begins_with_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::NotBeginsWith do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::NotBeginsWith do describe '#evaluate' do context 'left begins with right' do it 'should return false' do diff --git a/spec/jquery_query_builder/operators/not_between_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/not_between_spec.rb similarity index 82% rename from spec/jquery_query_builder/operators/not_between_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/not_between_spec.rb index 2215542..ffb8c68 100644 --- a/spec/jquery_query_builder/operators/not_between_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/not_between_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::NotBetween do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::NotBetween do describe '#evaluate' do context 'input is between bounds' do it 'should return false' do diff --git a/spec/jquery_query_builder/operators/not_contains_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/not_contains_spec.rb similarity index 83% rename from spec/jquery_query_builder/operators/not_contains_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/not_contains_spec.rb index 3b69f64..832ae6e 100644 --- a/spec/jquery_query_builder/operators/not_contains_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/not_contains_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::NotContains do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::NotContains do describe '#evaluate' do context 'left contains right' do it 'should return false' do diff --git a/spec/jquery_query_builder/operators/not_ends_with_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/not_ends_with_spec.rb similarity index 83% rename from spec/jquery_query_builder/operators/not_ends_with_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/not_ends_with_spec.rb index 32062ff..9c3e1c6 100644 --- a/spec/jquery_query_builder/operators/not_ends_with_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/not_ends_with_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::NotEndsWith do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::NotEndsWith do describe '#evaluate' do context 'left ends with right' do it 'should return false' do diff --git a/spec/jquery_query_builder/operators/not_equal_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/not_equal_spec.rb similarity index 82% rename from spec/jquery_query_builder/operators/not_equal_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/not_equal_spec.rb index 5468b4c..657ec0f 100644 --- a/spec/jquery_query_builder/operators/not_equal_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/not_equal_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::NotEqual do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::NotEqual do describe '#evaluate' do context 'left equals right' do it 'should return false' do diff --git a/spec/jquery_query_builder/operators/not_in_spec.rb b/spec/jquery_query_builder/evaluators/boolean/operators/not_in_spec.rb similarity index 83% rename from spec/jquery_query_builder/operators/not_in_spec.rb rename to spec/jquery_query_builder/evaluators/boolean/operators/not_in_spec.rb index b8daac5..464b9b9 100644 --- a/spec/jquery_query_builder/operators/not_in_spec.rb +++ b/spec/jquery_query_builder/evaluators/boolean/operators/not_in_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe JqueryQueryBuilder::Operators::NotIn do +describe JqueryQueryBuilder::Evaluators::Boolean::Operators::NotIn do describe '#evaluate' do context 'left is in right' do it 'should return false' do diff --git a/spec/jquery_query_builder/evaluators/boolean/rule_evaluator_spec.rb b/spec/jquery_query_builder/evaluators/boolean/rule_evaluator_spec.rb new file mode 100644 index 0000000..23c46dd --- /dev/null +++ b/spec/jquery_query_builder/evaluators/boolean/rule_evaluator_spec.rb @@ -0,0 +1,32 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Evaluators::Boolean::RuleEvaluator do + let(:decimal_rule){ + JqueryQueryBuilder::Rule.new({ + 'id' => "Decimal_Question", + 'field' => "Decimal_Question", + 'type' => "double", + 'input' => "text", + 'operator' => "equal", + 'value' => "1.2" + }) + } + + describe '#evaluate' do + it 'should evaluate using the operator with the input+value' do + rule_evaluator = described_class.new(decimal_rule) + + operator = JqueryQueryBuilder::Evaluators::Boolean::Operators::Equal.new + input = 1.2 + value = 1.2 + + object = {'Decimal_Question' => input} + + expect(rule_evaluator).to receive(:get_operator).and_return(operator) + expect(decimal_rule).to receive(:get_input).with(object).and_return(input) + expect(decimal_rule).to receive(:get_value).and_return(value) + + expect(rule_evaluator.evaluate(object)).to eq(true) + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/evaluators/boolean/rule_group_evaluator_spec.rb b/spec/jquery_query_builder/evaluators/boolean/rule_group_evaluator_spec.rb new file mode 100644 index 0000000..4fa7b12 --- /dev/null +++ b/spec/jquery_query_builder/evaluators/boolean/rule_group_evaluator_spec.rb @@ -0,0 +1,77 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Evaluators::Boolean::RuleGroupEvaluator do + let(:decimal_rule){ + { + 'id' => "Decimal_Question", + 'field' => "Decimal_Question", + 'type' => "double", + 'input' => "text", + 'operator' => "equal", + 'value' => "1.2" + } + } + let(:boolean_rule){ + { + "id" => "Yes_No_Question", + "field" => "Yes_No_Question", + "type" => "boolean", + "input" => "select", + "operator" => "equal", + "value" => "true" + } + } + + describe '#evaluate' do + context 'AND' do + let(:rules){[decimal_rule, boolean_rule]} + let(:evaluator){ + described_class.new( + JqueryQueryBuilder::RuleGroup.new({ + 'condition' => 'AND', + 'rules' => rules + }) + ) + } + it 'should returns true if all are true' do + expect(evaluator.evaluate({"Decimal_Question" => 1.2, "Yes_No_Question" => true})).to eq true + end + it 'should return false if any are false' do + expect(evaluator.evaluate({"Decimal_Question" => 1.2, "Yes_No_Question" => false})).to eq false + end + end + + context 'OR' do + let(:rules){[decimal_rule, boolean_rule]} + let(:evaluator){ + described_class.new( + JqueryQueryBuilder::RuleGroup.new({ + 'condition' => 'OR', + 'rules' => rules + }) + ) + } + it 'should returns true if any are true' do + expect(evaluator.evaluate({"Decimal_Question" => 1.5, "Yes_No_Question" => true})).to eq true + end + it 'should return false if all are false' do + expect(evaluator.evaluate({"Decimal_Question" => 1.0, "Yes_No_Question" => false})).to eq false + end + end + end + + describe '#get_rule_evaluator' do + context 'passed a rule' do + it 'should return a rule object' do + result = described_class.new(JqueryQueryBuilder::RuleGroup.new({})).get_rule_evaluator(decimal_rule) + expect(result.is_a?(JqueryQueryBuilder::Evaluators::Boolean::RuleEvaluator)).to eq(true) + end + end + context 'passed a rule group' do + it 'should return a rule group' do + result = described_class.new(JqueryQueryBuilder::RuleGroup.new({})).get_rule_evaluator(JqueryQueryBuilder::RuleGroup.new({'condition' => 'AND', 'rules' => [{}]})) + expect(result.is_a?(JqueryQueryBuilder::Evaluators::Boolean::RuleGroupEvaluator)).to eq(true) + end + end + end +end diff --git a/spec/jquery_query_builder/rule_group_spec.rb b/spec/jquery_query_builder/rule_group_spec.rb index 1bbdc49..89c5084 100644 --- a/spec/jquery_query_builder/rule_group_spec.rb +++ b/spec/jquery_query_builder/rule_group_spec.rb @@ -24,46 +24,14 @@ describe '#new' do it 'should initialize a new rule group and get the conditions and rules' do + decimal_rule_object = JqueryQueryBuilder::Rule.new(decimal_rule) + expect(JqueryQueryBuilder::Rule).to receive(:new).with(decimal_rule).and_return(decimal_rule_object) evaluator = JqueryQueryBuilder::RuleGroup.new({ 'condition' => 'AND', 'rules' => [decimal_rule] }) expect(evaluator.condition).to eq('AND') - expect(evaluator.rules).to eq([decimal_rule]) - end - end - - describe '#evaluate' do - context 'AND' do - let(:rules){[decimal_rule, boolean_rule]} - let(:evaluator){ - JqueryQueryBuilder::RuleGroup.new({ - 'condition' => 'AND', - 'rules' => rules - }) - } - it 'should returns true if all are true' do - expect(evaluator.evaluate({"Decimal_Question" => 1.2, "Yes_No_Question" => true})).to eq true - end - it 'should return false if any are false' do - expect(evaluator.evaluate({"Decimal_Question" => 1.2, "Yes_No_Question" => false})).to eq false - end - end - - context 'OR' do - let(:rules){[decimal_rule, boolean_rule]} - let(:evaluator){ - JqueryQueryBuilder::RuleGroup.new({ - 'condition' => 'OR', - 'rules' => rules - }) - } - it 'should returns true if any are true' do - expect(evaluator.evaluate({"Decimal_Question" => 1.5, "Yes_No_Question" => true})).to eq true - end - it 'should return false if all are false' do - expect(evaluator.evaluate({"Decimal_Question" => 1.0, "Yes_No_Question" => false})).to eq false - end + expect(evaluator.rules).to eq([decimal_rule_object]) end end diff --git a/spec/jquery_query_builder/rule_spec.rb b/spec/jquery_query_builder/rule_spec.rb index 7d86860..86153f1 100644 --- a/spec/jquery_query_builder/rule_spec.rb +++ b/spec/jquery_query_builder/rule_spec.rb @@ -24,13 +24,6 @@ end end - describe '#get_operator' do - it 'should get an operator based on type' do - rule = JqueryQueryBuilder::Rule.new(decimal_rule) - expect(rule.get_operator.class.to_s).to eq(JqueryQueryBuilder::Operators::Equal.to_s) - end - end - describe '#get_input' do context 'input exists' do context 'base value' do @@ -99,23 +92,5 @@ rule.get_value end end - - describe '#evaluate' do - it 'should evaluate using the operator with the input+value' do - rule = JqueryQueryBuilder::Rule.new(decimal_rule) - - operator = JqueryQueryBuilder::Operators::Equal.new - input = 1.2 - value = 1.2 - - object = {'Decimal_Question' => input} - - expect(rule).to receive(:get_operator).and_return(operator) - expect(rule).to receive(:get_input).with(object).and_return(input) - expect(rule).to receive(:get_value).and_return(value) - - expect(rule.evaluate(object)).to eq(true) - end - end end From 805d6ccffdd0fadc3dd297bf651d9edf0cbe5ac4 Mon Sep 17 00:00:00 2001 From: Matthew Hirst Date: Mon, 13 Sep 2021 22:39:30 +0200 Subject: [PATCH 4/5] WIP: SQL generator. --- lib/jquery_query_builder-rails.rb | 1 + lib/jquery_query_builder/generator.rb | 25 ++++++++ .../generators/sql/generator.rb | 26 +++++++++ .../generators/sql/operator.rb | 52 +++++++++++++++++ .../generators/sql/operators/begins_with.rb | 14 +++++ .../generators/sql/operators/between.rb | 14 +++++ .../generators/sql/operators/contains.rb | 14 +++++ .../generators/sql/operators/ends_with.rb | 14 +++++ .../generators/sql/operators/equal.rb | 14 +++++ .../generators/sql/operators/greater.rb | 14 +++++ .../sql/operators/greater_or_equal.rb | 14 +++++ .../generators/sql/operators/in.rb | 14 +++++ .../generators/sql/operators/is_empty.rb | 14 +++++ .../generators/sql/operators/is_not_empty.rb | 14 +++++ .../generators/sql/operators/is_not_null.rb | 14 +++++ .../generators/sql/operators/is_null.rb | 14 +++++ .../generators/sql/operators/less.rb | 14 +++++ .../generators/sql/operators/less_or_equal.rb | 14 +++++ .../sql/operators/not_begins_with.rb | 14 +++++ .../generators/sql/operators/not_between.rb | 14 +++++ .../generators/sql/operators/not_contains.rb | 14 +++++ .../generators/sql/operators/not_ends_with.rb | 14 +++++ .../generators/sql/operators/not_equal.rb | 14 +++++ .../generators/sql/operators/not_in.rb | 14 +++++ .../generators/sql/rule_generator.rb | 29 ++++++++++ .../generators/sql/rule_group_generator.rb | 57 +++++++++++++++++++ .../generators/sql/sanitizor.rb | 15 +++++ .../problems/problems_spec.rb | 3 + 28 files changed, 488 insertions(+) create mode 100644 lib/jquery_query_builder/generator.rb create mode 100644 lib/jquery_query_builder/generators/sql/generator.rb create mode 100644 lib/jquery_query_builder/generators/sql/operator.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/begins_with.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/between.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/contains.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/ends_with.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/equal.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/greater.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/greater_or_equal.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/in.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/is_empty.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/is_not_empty.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/is_not_null.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/is_null.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/less.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/less_or_equal.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/not_begins_with.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/not_between.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/not_contains.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/not_ends_with.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/not_equal.rb create mode 100644 lib/jquery_query_builder/generators/sql/operators/not_in.rb create mode 100644 lib/jquery_query_builder/generators/sql/rule_generator.rb create mode 100644 lib/jquery_query_builder/generators/sql/rule_group_generator.rb create mode 100644 lib/jquery_query_builder/generators/sql/sanitizor.rb diff --git a/lib/jquery_query_builder-rails.rb b/lib/jquery_query_builder-rails.rb index aacbd2d..16d0fc4 100644 --- a/lib/jquery_query_builder-rails.rb +++ b/lib/jquery_query_builder-rails.rb @@ -1,5 +1,6 @@ require "jquery_query_builder/rails/version" require "jquery_query_builder/evaluator" +require "jquery_query_builder/generator" module JqueryQueryBuilder module Rails diff --git a/lib/jquery_query_builder/generator.rb b/lib/jquery_query_builder/generator.rb new file mode 100644 index 0000000..04dd3e6 --- /dev/null +++ b/lib/jquery_query_builder/generator.rb @@ -0,0 +1,25 @@ +require 'json' +require 'jquery_query_builder/rule' +require 'jquery_query_builder/rule_group' +require 'jquery_query_builder/generators/sql/generator' +require 'active_support/core_ext/module/delegation' + +module JqueryQueryBuilder + class Generator + attr_accessor :parsed_rule_set, :generator + def initialize(raw_rule_set, generator_class: Generators::SQL::Generator) + if raw_rule_set.is_a? String + #assuming the json was passed in + self.parsed_rule_set = JSON.parse(raw_rule_set) + else + self.parsed_rule_set = raw_rule_set + end + + rule_set = RuleGroup.new(parsed_rule_set) + self.generator = generator_class.new(rule_set) + end + + # All evaluators must implement + delegate :generate, to: :generator + end +end \ No newline at end of file diff --git a/lib/jquery_query_builder/generators/sql/generator.rb b/lib/jquery_query_builder/generators/sql/generator.rb new file mode 100644 index 0000000..8e6d813 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/generator.rb @@ -0,0 +1,26 @@ +require 'active_support/core_ext/hash/indifferent_access' +require 'active_support/core_ext/object/blank' +require 'active_support/core_ext/string/inflections' + +require 'jquery_query_builder/generators/sql/operator' +require 'jquery_query_builder/generators/sql/sanitizor' +require 'jquery_query_builder/generators/sql/rule_group_generator' + +module JqueryQueryBuilder + module Generators + module SQL + class Generator + attr_accessor :rule_group, :field_whitelist + + def initialize(rule_group, field_whitelist: nil) + self.rule_group = rule_group + self.field_whitelist = field_whitelist + end + + def generate + RuleGroupGenerator.new(rule_group, field_whitelist: field_whitelist).generate + end + end + end + end +end \ No newline at end of file diff --git a/lib/jquery_query_builder/generators/sql/operator.rb b/lib/jquery_query_builder/generators/sql/operator.rb new file mode 100644 index 0000000..39632db --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operator.rb @@ -0,0 +1,52 @@ +#require all the operators +Dir[File.join(File.dirname(__FILE__) + '/operators', "**/*.rb")].each do |f| + require f +end + +module JqueryQueryBuilder + module Generators + module SQL + class Operator + SPECIAL_CASE_MAP = { + } + + def self.get_operator_class(operator) + operator_class = SPECIAL_CASE_MAP[operator] || operator.camelize + + begin + operator_class = "#{operator_module}::#{operator_class}".constantize + rescue NameError + raise "Unknown operator #{operator} used." + end + end + + def self.operator_module + "JqueryQueryBuilder::Generators::SQL::Operators" + end + end + end + end +end + +__END__ + +equal +not_equal +in +not_in +less +less_or_equal +greater +greater_or_equal +between +not_between +begins_with +not_begins_with +contains +not_contains +ends_with +not_ends_with +is_empty +is_not_empty +is_null +is_not_null diff --git a/lib/jquery_query_builder/generators/sql/operators/begins_with.rb b/lib/jquery_query_builder/generators/sql/operators/begins_with.rb new file mode 100644 index 0000000..a81354c --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/begins_with.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class BeginsWith + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(LOWER(#{field}) LIKE LOWER(?))", "#{value}%"] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/between.rb b/lib/jquery_query_builder/generators/sql/operators/between.rb new file mode 100644 index 0000000..92b89b0 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/between.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class Between + def generate(field, bounds) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} BETWEEN ? AND ?)", bounds[0], bounds[1]] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/contains.rb b/lib/jquery_query_builder/generators/sql/operators/contains.rb new file mode 100644 index 0000000..8b32c27 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/contains.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class Contains + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(LOWER(#{field}) LIKE LOWER(?))", "%#{value}%"] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/ends_with.rb b/lib/jquery_query_builder/generators/sql/operators/ends_with.rb new file mode 100644 index 0000000..6bde207 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/ends_with.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class EndsWith + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(LOWER(#{field}) LIKE LOWER(?))", "%#{value}"] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/equal.rb b/lib/jquery_query_builder/generators/sql/operators/equal.rb new file mode 100644 index 0000000..5fce47e --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/equal.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class Equal + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} = ?)", value] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/greater.rb b/lib/jquery_query_builder/generators/sql/operators/greater.rb new file mode 100644 index 0000000..ebfec7b --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/greater.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class Greater + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} > ?)", value] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/greater_or_equal.rb b/lib/jquery_query_builder/generators/sql/operators/greater_or_equal.rb new file mode 100644 index 0000000..ae12f1d --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/greater_or_equal.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class GreaterOrEqual + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} >= ?)", value] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/in.rb b/lib/jquery_query_builder/generators/sql/operators/in.rb new file mode 100644 index 0000000..0a9f4e3 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/in.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class In + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} IN(?))", value] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/is_empty.rb b/lib/jquery_query_builder/generators/sql/operators/is_empty.rb new file mode 100644 index 0000000..650c5be --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/is_empty.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class IsEmpty + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} = ?)", ''] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/is_not_empty.rb b/lib/jquery_query_builder/generators/sql/operators/is_not_empty.rb new file mode 100644 index 0000000..12bcac7 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/is_not_empty.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class IsNotEmpty + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} != ?)", ''] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/is_not_null.rb b/lib/jquery_query_builder/generators/sql/operators/is_not_null.rb new file mode 100644 index 0000000..793dfbc --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/is_not_null.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class IsNotNull + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} IS NOT NULL)"] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/is_null.rb b/lib/jquery_query_builder/generators/sql/operators/is_null.rb new file mode 100644 index 0000000..5aa176f --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/is_null.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class IsNull + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} IS NULL)"] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/less.rb b/lib/jquery_query_builder/generators/sql/operators/less.rb new file mode 100644 index 0000000..2359f33 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/less.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class Less + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} < ?)", value] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/less_or_equal.rb b/lib/jquery_query_builder/generators/sql/operators/less_or_equal.rb new file mode 100644 index 0000000..f59ad8e --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/less_or_equal.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class LessOrEqual + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} <= ?)", value] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/not_begins_with.rb b/lib/jquery_query_builder/generators/sql/operators/not_begins_with.rb new file mode 100644 index 0000000..d48ab1f --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/not_begins_with.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class NotBeginsWith + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} NOT LIKE ?)", "%#{value}%"] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/not_between.rb b/lib/jquery_query_builder/generators/sql/operators/not_between.rb new file mode 100644 index 0000000..f06c047 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/not_between.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class NotBetween + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} NOT BETWEEN ? AND ?)", bounds[0], bounds[1]] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/not_contains.rb b/lib/jquery_query_builder/generators/sql/operators/not_contains.rb new file mode 100644 index 0000000..059dbd1 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/not_contains.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class NotContains + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(LOWER(#{field}) NOT LIKE LOWER(?))", "%#{value}%"] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/not_ends_with.rb b/lib/jquery_query_builder/generators/sql/operators/not_ends_with.rb new file mode 100644 index 0000000..93b5027 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/not_ends_with.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class NotEndsWith + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(LOWER(#{field}) NOT LIKE LOWER(?))", "%#{value}"] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/not_equal.rb b/lib/jquery_query_builder/generators/sql/operators/not_equal.rb new file mode 100644 index 0000000..35195b6 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/not_equal.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class NotEqual + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} != ?)", value] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/operators/not_in.rb b/lib/jquery_query_builder/generators/sql/operators/not_in.rb new file mode 100644 index 0000000..ab4bc6c --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/operators/not_in.rb @@ -0,0 +1,14 @@ +module JqueryQueryBuilder + module Generators + module SQL + module Operators + class NotIn + def generate(field, value) + # sanitize_sql_for_conditions is made public in Rails 5.2 + Sanitizor.sanitize(["(#{field} NOT IN(?))", value] ) + end + end + end + end + end +end diff --git a/lib/jquery_query_builder/generators/sql/rule_generator.rb b/lib/jquery_query_builder/generators/sql/rule_generator.rb new file mode 100644 index 0000000..da723b2 --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/rule_generator.rb @@ -0,0 +1,29 @@ +module JqueryQueryBuilder + module Generators + module SQL + class RuleGenerator + attr_accessor :rule, :field_whitelist + def initialize(rule, field_whitelist: nil) + self.rule = rule + self.field_whitelist = field_whitelist + end + + def generate + field = rule.id + value = rule.get_value + get_operator.generate(field, value) + end + + def whitelisted? + return true if field_whitelist.blank? + field_whitelist.include?(rule.id) + end + + def get_operator + rule_operator = rule.operator + JqueryQueryBuilder::Generators::SQL::Operator.get_operator_class(rule_operator).new + end + end + end + end +end \ No newline at end of file diff --git a/lib/jquery_query_builder/generators/sql/rule_group_generator.rb b/lib/jquery_query_builder/generators/sql/rule_group_generator.rb new file mode 100644 index 0000000..8828dfd --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/rule_group_generator.rb @@ -0,0 +1,57 @@ +require 'jquery_query_builder/generators/sql/rule_generator' + +module JqueryQueryBuilder + module Generators + module SQL + class RuleGroupGenerator + attr_accessor :rule_group, :field_whitelist + def initialize(rule_group, field_whitelist: nil) + self.rule_group = rule_group + self.field_whitelist = field_whitelist + end + + def generate + rules = rule_group.rules + + queries = [] + rules.each do |rule| + rule_generator = get_rule_generator(rule) + # skip the conditional if the rule is not whitelisted + sub_query = rule_generator.generate if rule_generator.whitelisted? + queries << sub_query if sub_query # query can be nil if all rules are rejected + end + + query_string = nil + + if queries.length == 1 + query_string = queries[0] + elsif queries.length > 1 + case rule_group.condition + when "AND" + query_string = queries.join(' AND ') + when "OR" + query_string = queries.join(' OR ') + end + query_string = "(#{query_string})" # add parens for groups + end + + query_string + end + + def whitelisted? + # rule groups are always whitelisted, only rules can fail + true + end + + def get_rule_generator(rule) + if rule.is_a?(RuleGroup) + RuleGroupGenerator.new(rule, field_whitelist: field_whitelist) + else + RuleGenerator.new(rule, field_whitelist: field_whitelist) + end + end + + end + end + end +end \ No newline at end of file diff --git a/lib/jquery_query_builder/generators/sql/sanitizor.rb b/lib/jquery_query_builder/generators/sql/sanitizor.rb new file mode 100644 index 0000000..bab25af --- /dev/null +++ b/lib/jquery_query_builder/generators/sql/sanitizor.rb @@ -0,0 +1,15 @@ +require 'active_record' + +module JqueryQueryBuilder + module Generators + module SQL + class Sanitizor + def self.sanitize(query) + # TODO - Need to make it so we can pass in the model + # to get the connection from to do the sanitization. + ActiveRecord::Base.send(:sanitize_sql_for_conditions, query) + end + end + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/problems/problems_spec.rb b/spec/jquery_query_builder/problems/problems_spec.rb index 8e08f63..e4879ec 100644 --- a/spec/jquery_query_builder/problems/problems_spec.rb +++ b/spec/jquery_query_builder/problems/problems_spec.rb @@ -28,6 +28,9 @@ object = {"fields" => {"Customer"=>"BOB EVANS FARMS LLC", "Site_Name"=>"BOB EVANS", "STON"=>"300", "Work_Order_Number"=>"600168", "Purpose"=>"IMAC", "Industry"=>"HSR", "Street_Address"=>"1301 GOVERNORS PL", "City"=>"BEAR", "State"=>"Delaware", "Zip_Code"=>"19701-3051", "SD"=>"2016-09-11", "Scope_Of_Work"=>"Complete Site Install Night 2. Fill out and Fax Checklist and SQS to 800.854.9041. Email pictures to InstallationServices.HSR@ncr.com. Contact Britt Brittain at 205-492-0843 with any questions or concerns. Please close out your work order by sending the work order number and site times to WI230016@ncr.com. Submit expenses as NON billable. NCR Bob Evans Install checklist NIGHT 2. Justin Berryman is the lead tech and will be responsible for all paperwork and pictures. Additional Notes: (Radiant Dispatch Center only) None", "CIN"=>[{"TCIV"=>"2016-09-11T19:30:28-0400", "Site_Abort_or_Cancel_"=>"false", "TCIVD"=>"2016-09-11T19:30:28-0400", "Check_In_Location_Verified"=>"lat=39.63346855, long=-75.66046963, alt=-16.0, accuracy=19.0"}], "Bob_Evan_s"=>[{"Number_of_POS"=>"6", "Number_of_Receipt_Printers"=>"7", "Number_of_Kitchen_Monitors"=>"7", "Number_of_Remote_Printers"=>"1", "Number_of_Cash_Drawers"=>"4", "Fileserver_Serial_Number"=>"03307000302125", "Security_Key_Number"=>"272533", "Install_Night"=>"2", "Bob_Evan_s_Night_2"=>[{"Lexmark_MAC_Address"=>"0021b71903b4", "Repurposed_Kitchen_Printer_for_Carryout_Location_and_Type"=>"markiv expo to carry out "}], "Night_1_Pictures"=>"", "Night_2_Pictures"=>[{"POS_1"=>"IMAGE", "POS_1_under"=>"IMAGE", "POS_2"=>"IMAGE", "POS_2_under"=>"IMAGE", "POS_3"=>"IMAGE", "POS_3_under"=>"IMAGE", "POS_5"=>"IMAGE", "POS_5_under"=>"IMAGE", "POS_6"=>"IMAGE", "POS_6_Under"=>"IMAGE", "POS_7"=>"IMAGE", "POS_7_under"=>"IMAGE", "Carryout"=>"IMAGE", "FC_Customer"=>"IMAGE", "FC_Employee"=>"IMAGE", "Prep_counter"=>"IMAGE", "Grill_Left"=>"IMAGE", "Grill_Right"=>"IMAGE", "Meat_1"=>"IMAGE", "Egg_1"=>"IMAGE", "Meat_2"=>"IMAGE", "Egg_2"=>"IMAGE", "Salad"=>"IMAGE", "Expo_1"=>"IMAGE", "Expo_2"=>"IMAGE", "Network_Closet"=>"IMAGE", "Patch_panel"=>"IMAGE", "POE"=>"IMAGE", "D_Mark"=>"IMAGE", "MWS"=>"IMAGE", "CyberPower"=>"IMAGE", "Office_Network_Jacks"=>"IMAGE", "Server"=>"IMAGE", "BOH_Overall"=>"IMAGE", "Caller_ID"=>"IMAGE", "SEKO_Boxes"=>"IMAGE", "CORP_Boxes"=>"IMAGE"}]}], "SO"=>[{"NOI"=>"2", "LT"=>"Justin Berryman ", "HT1"=>[{"HT1"=>"levie", "LT"=>"Justin Berryman ", "SD"=>"2016-09-11", "TTR"=>"2016-09-12T03:38:20-0400", "MOD"=>"Tammy", "NOI"=>"2", "STON"=>"300", "TCIV"=>"2016-09-11T19:30:28-0400", "TTOS"=>"8.13", "City"=>"BEAR", "LTWON"=>"600168", "State"=>"Delaware", "LTSTS"=>"2016-09-12T03:38:14-0400", "MODSTS"=>"2016-09-12T04:21:11-0400", "Status"=>"Complete- With Outstanding Issues", "Purpose"=>"IMAC", "Industry"=>"HSR", "Zip_Code"=>"19701-3051", "Customer"=>"BOB EVANS FARMS LLC", "Site_Name"=>"BOB EVANS", "Lead_Tech"=>"Justin Berryman ", "Closed_Issues"=>"none", "Street_Address"=>"1301 GOVERNORS PL", "Outstanding_Issues"=>"none", "Site_Abort_or_Cancel_"=>"false"}], "Status"=>"Complete- With Outstanding Issues", "Outstanding_Issues"=>"edc's not working currently escalated and will be fixed promptly", "Closed_Issues"=>"none", "MOD"=>"Tammy", "MODS"=>"IMAGE", "LTS"=>"IMAGE", "TTR"=>"2016-09-12T03:38:20-0400", "TTOS"=>"8.13", "Your_Email_Address"=>"justinberryman1@gmail.com", "TTRD"=>"2016-09-12T03:38:20-0400", "LTSTS"=>"2016-09-12T03:38:14-0400", "MODSTS"=>"2016-09-12T04:21:11-0400", "Check_Out_Location"=>"lat=39.63341509, long=-75.66064347, alt=-18.0, accuracy=214.0"}], "Pics"=>[{"PIC1"=>"IMAGE", "PIC2"=>"IMAGE", "PIC3"=>"IMAGE", "PIC4"=>"IMAGE", "PIC5"=>"IMAGE", "PIC6"=>"IMAGE", "PIC7"=>"IMAGE", "PIC8"=>"IMAGE", "PIC9"=>"IMAGE", "PIC10"=>"IMAGE", "PIC11"=>"IMAGE", "PIC12"=>"IMAGE"}]}} expect(rule.object_matches_rules?(object)).to eq(true) + + generator = JqueryQueryBuilder::Generator.new(rule_json) + # TODO - check generator generates properly end end end From e961197abac9414ab1a1e91b22675107d2e792e3 Mon Sep 17 00:00:00 2001 From: Matthew Hirst Date: Thu, 23 Sep 2021 23:41:11 +0200 Subject: [PATCH 5/5] Test sql generator. --- jquery_query_build_rails_test | 0 jquery_query_builder-rails.gemspec | 1 + .../generators/sql/operators/in.rb | 2 +- .../sql/operators/not_begins_with.rb | 2 +- .../generators/sql/operators/not_between.rb | 2 +- .../generators/sql/operators/not_in.rb | 2 +- spec/jquery_query_builder/generator_spec.rb | 29 ++++++++ .../generators/sql/operator_spec.rb | 31 ++++++++ .../sql/operators/begins_with_spec.rb | 9 +++ .../generators/sql/operators/between_spec.rb | 9 +++ .../generators/sql/operators/contains_spec.rb | 9 +++ .../sql/operators/ends_with_spec.rb | 9 +++ .../generators/sql/operators/equal_spec.rb | 9 +++ .../sql/operators/greater_or_equal_spec.rb | 9 +++ .../generators/sql/operators/greater_spec.rb | 9 +++ .../generators/sql/operators/in_spec.rb | 9 +++ .../generators/sql/operators/is_empty_spec.rb | 9 +++ .../sql/operators/is_not_empty_spec.rb | 9 +++ .../sql/operators/is_not_null_spec.rb | 9 +++ .../generators/sql/operators/is_null_spec.rb | 9 +++ .../sql/operators/less_or_equal_spec.rb | 9 +++ .../generators/sql/operators/less_spec.rb | 9 +++ .../sql/operators/not_begins_with_spec.rb | 9 +++ .../sql/operators/not_between_spec.rb | 9 +++ .../sql/operators/not_contains_spec.rb | 9 +++ .../sql/operators/not_ends_with_spec.rb | 9 +++ .../sql/operators/not_equal_spec.rb | 9 +++ .../generators/sql/operators/not_in_spec.rb | 9 +++ .../generators/sql/rule_generator_spec.rb | 28 ++++++++ .../sql/rule_group_generator_spec.rb | 71 +++++++++++++++++++ .../generators/sql/sanitizor_spec.rb | 10 +++ spec/spec_helper.rb | 6 ++ 32 files changed, 360 insertions(+), 4 deletions(-) create mode 100644 jquery_query_build_rails_test create mode 100644 spec/jquery_query_builder/generator_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operator_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/begins_with_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/between_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/contains_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/ends_with_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/equal_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/greater_or_equal_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/greater_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/in_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/is_empty_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/is_not_empty_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/is_not_null_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/is_null_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/less_or_equal_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/less_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/not_begins_with_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/not_between_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/not_contains_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/not_ends_with_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/not_equal_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/operators/not_in_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/rule_generator_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/rule_group_generator_spec.rb create mode 100644 spec/jquery_query_builder/generators/sql/sanitizor_spec.rb diff --git a/jquery_query_build_rails_test b/jquery_query_build_rails_test new file mode 100644 index 0000000..e69de29 diff --git a/jquery_query_builder-rails.gemspec b/jquery_query_builder-rails.gemspec index ed4bc10..130d8e4 100644 --- a/jquery_query_builder-rails.gemspec +++ b/jquery_query_builder-rails.gemspec @@ -18,6 +18,7 @@ Gem::Specification.new do |spec| spec.add_dependency "railties", ">= 3.1" spec.add_dependency "json", ">= 1.8.3" spec.add_dependency "activesupport" + spec.add_development_dependency "sqlite3" spec.add_development_dependency "bundler" spec.add_development_dependency "rake" spec.add_development_dependency "rspec" diff --git a/lib/jquery_query_builder/generators/sql/operators/in.rb b/lib/jquery_query_builder/generators/sql/operators/in.rb index 0a9f4e3..88df1e8 100644 --- a/lib/jquery_query_builder/generators/sql/operators/in.rb +++ b/lib/jquery_query_builder/generators/sql/operators/in.rb @@ -5,7 +5,7 @@ module Operators class In def generate(field, value) # sanitize_sql_for_conditions is made public in Rails 5.2 - Sanitizor.sanitize(["(#{field} IN(?))", value] ) + Sanitizor.sanitize(["(#{field} IN (?))", value] ) end end end diff --git a/lib/jquery_query_builder/generators/sql/operators/not_begins_with.rb b/lib/jquery_query_builder/generators/sql/operators/not_begins_with.rb index d48ab1f..6cc157d 100644 --- a/lib/jquery_query_builder/generators/sql/operators/not_begins_with.rb +++ b/lib/jquery_query_builder/generators/sql/operators/not_begins_with.rb @@ -5,7 +5,7 @@ module Operators class NotBeginsWith def generate(field, value) # sanitize_sql_for_conditions is made public in Rails 5.2 - Sanitizor.sanitize(["(#{field} NOT LIKE ?)", "%#{value}%"] ) + Sanitizor.sanitize(["(LOWER(#{field}) NOT LIKE LOWER(?))", "#{value}%"] ) end end end diff --git a/lib/jquery_query_builder/generators/sql/operators/not_between.rb b/lib/jquery_query_builder/generators/sql/operators/not_between.rb index f06c047..ece5de4 100644 --- a/lib/jquery_query_builder/generators/sql/operators/not_between.rb +++ b/lib/jquery_query_builder/generators/sql/operators/not_between.rb @@ -3,7 +3,7 @@ module Generators module SQL module Operators class NotBetween - def generate(field, value) + def generate(field, bounds) # sanitize_sql_for_conditions is made public in Rails 5.2 Sanitizor.sanitize(["(#{field} NOT BETWEEN ? AND ?)", bounds[0], bounds[1]] ) end diff --git a/lib/jquery_query_builder/generators/sql/operators/not_in.rb b/lib/jquery_query_builder/generators/sql/operators/not_in.rb index ab4bc6c..1df79fd 100644 --- a/lib/jquery_query_builder/generators/sql/operators/not_in.rb +++ b/lib/jquery_query_builder/generators/sql/operators/not_in.rb @@ -5,7 +5,7 @@ module Operators class NotIn def generate(field, value) # sanitize_sql_for_conditions is made public in Rails 5.2 - Sanitizor.sanitize(["(#{field} NOT IN(?))", value] ) + Sanitizor.sanitize(["(#{field} NOT IN (?))", value] ) end end end diff --git a/spec/jquery_query_builder/generator_spec.rb b/spec/jquery_query_builder/generator_spec.rb new file mode 100644 index 0000000..fe0b646 --- /dev/null +++ b/spec/jquery_query_builder/generator_spec.rb @@ -0,0 +1,29 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generator do + context 'SQL (default)' do + describe '#new' do + context 'with an object' do + it 'should initialize a new evaluator' do + generator = JqueryQueryBuilder::Generator.new({}) + end + end + + context 'with json' do + it 'should initialize a new evaluator' do + generator = JqueryQueryBuilder::Generator.new("{}") + end + end + end + + describe '#generate' do + it 'should try generate using the generator class' do + generator = JqueryQueryBuilder::Generator.new({}) + expect(generator.generator).to receive(:generate).and_call_original + result = generator.generate + expect(result).to eq(nil) + end + end + + end +end diff --git a/spec/jquery_query_builder/generators/sql/operator_spec.rb b/spec/jquery_query_builder/generators/sql/operator_spec.rb new file mode 100644 index 0000000..12dd526 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operator_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operator do + let(:decimal_rule){ + { + 'id' => "Decimal_Question", + 'field' => "Decimal_Question", + 'type' => "double", + 'input' => "text", + 'operator' => "equal", + 'value' => "1.2" + } + } + let(:boolean_rule){ + { + "id" => "Yes_No_Question", + "field" => "Yes_No_Question", + "type" => "boolean", + "input" => "select", + "operator" => "equal", + "value" => "true" + } + } + + describe '.get_operator_class' do + it 'should return an operator class on the operator' do + expect(JqueryQueryBuilder::Generators::SQL::Operator.get_operator_class('equal').to_s).to eq('JqueryQueryBuilder::Generators::SQL::Operators::Equal') + expect(JqueryQueryBuilder::Generators::SQL::Operator.get_operator_class('not_equal').to_s).to eq('JqueryQueryBuilder::Generators::SQL::Operators::NotEqual') + end + end +end diff --git a/spec/jquery_query_builder/generators/sql/operators/begins_with_spec.rb b/spec/jquery_query_builder/generators/sql/operators/begins_with_spec.rb new file mode 100644 index 0000000..33236c5 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/begins_with_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::BeginsWith do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", "ab")).to eq("(LOWER(abcde) LIKE LOWER('ab%'))") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/between_spec.rb b/spec/jquery_query_builder/generators/sql/operators/between_spec.rb new file mode 100644 index 0000000..15edd59 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/between_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::Between do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", [1,2])).to eq("(abcde BETWEEN 1 AND 2)") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/contains_spec.rb b/spec/jquery_query_builder/generators/sql/operators/contains_spec.rb new file mode 100644 index 0000000..aae90d1 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/contains_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::Contains do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", "lol")).to eq("(LOWER(abcde) LIKE LOWER('%lol%'))") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/ends_with_spec.rb b/spec/jquery_query_builder/generators/sql/operators/ends_with_spec.rb new file mode 100644 index 0000000..4383f12 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/ends_with_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::EndsWith do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", "ab")).to eq("(LOWER(abcde) LIKE LOWER('%ab'))") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/equal_spec.rb b/spec/jquery_query_builder/generators/sql/operators/equal_spec.rb new file mode 100644 index 0000000..6497a15a9 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/equal_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::Equal do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", "ab")).to eq("(abcde = 'ab')") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/greater_or_equal_spec.rb b/spec/jquery_query_builder/generators/sql/operators/greater_or_equal_spec.rb new file mode 100644 index 0000000..0d5214c --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/greater_or_equal_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::GreaterOrEqual do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", 1)).to eq("(abcde >= 1)") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/greater_spec.rb b/spec/jquery_query_builder/generators/sql/operators/greater_spec.rb new file mode 100644 index 0000000..be21ce9 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/greater_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::Greater do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", 1)).to eq("(abcde > 1)") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/in_spec.rb b/spec/jquery_query_builder/generators/sql/operators/in_spec.rb new file mode 100644 index 0000000..6adafac --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/in_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::In do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", [1])).to eq("(abcde IN (1))") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/is_empty_spec.rb b/spec/jquery_query_builder/generators/sql/operators/is_empty_spec.rb new file mode 100644 index 0000000..079b277 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/is_empty_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::IsEmpty do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", nil)).to eq("(abcde = '')") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/is_not_empty_spec.rb b/spec/jquery_query_builder/generators/sql/operators/is_not_empty_spec.rb new file mode 100644 index 0000000..7f85e91 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/is_not_empty_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::IsNotEmpty do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", nil)).to eq("(abcde != '')") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/is_not_null_spec.rb b/spec/jquery_query_builder/generators/sql/operators/is_not_null_spec.rb new file mode 100644 index 0000000..769f0bc --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/is_not_null_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::IsNotNull do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", nil)).to eq("(abcde IS NOT NULL)") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/is_null_spec.rb b/spec/jquery_query_builder/generators/sql/operators/is_null_spec.rb new file mode 100644 index 0000000..ae6433d --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/is_null_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::IsNull do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", nil)).to eq("(abcde IS NULL)") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/less_or_equal_spec.rb b/spec/jquery_query_builder/generators/sql/operators/less_or_equal_spec.rb new file mode 100644 index 0000000..5fa3014 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/less_or_equal_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::LessOrEqual do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", 1)).to eq("(abcde <= 1)") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/less_spec.rb b/spec/jquery_query_builder/generators/sql/operators/less_spec.rb new file mode 100644 index 0000000..aea32e8 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/less_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::Less do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", 1)).to eq("(abcde < 1)") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/not_begins_with_spec.rb b/spec/jquery_query_builder/generators/sql/operators/not_begins_with_spec.rb new file mode 100644 index 0000000..cf3ec3e --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/not_begins_with_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::NotBeginsWith do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", "ab")).to eq("(LOWER(abcde) NOT LIKE LOWER('ab%'))") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/not_between_spec.rb b/spec/jquery_query_builder/generators/sql/operators/not_between_spec.rb new file mode 100644 index 0000000..d3790c2 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/not_between_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::NotBetween do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", [1,2])).to eq("(abcde NOT BETWEEN 1 AND 2)") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/not_contains_spec.rb b/spec/jquery_query_builder/generators/sql/operators/not_contains_spec.rb new file mode 100644 index 0000000..6a90c10 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/not_contains_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::NotContains do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", "lol")).to eq("(LOWER(abcde) NOT LIKE LOWER('%lol%'))") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/not_ends_with_spec.rb b/spec/jquery_query_builder/generators/sql/operators/not_ends_with_spec.rb new file mode 100644 index 0000000..f93b67a --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/not_ends_with_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::NotEndsWith do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", "ab")).to eq("(LOWER(abcde) NOT LIKE LOWER('%ab'))") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/not_equal_spec.rb b/spec/jquery_query_builder/generators/sql/operators/not_equal_spec.rb new file mode 100644 index 0000000..1d81c1c --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/not_equal_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::NotEqual do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", "ab")).to eq("(abcde != 'ab')") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/operators/not_in_spec.rb b/spec/jquery_query_builder/generators/sql/operators/not_in_spec.rb new file mode 100644 index 0000000..71a23f5 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/operators/not_in_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Operators::NotIn do + describe '#generate' do + it 'should generate the sql where clause' do + expect(subject.generate("abcde", [1])).to eq("(abcde NOT IN (1))") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/rule_generator_spec.rb b/spec/jquery_query_builder/generators/sql/rule_generator_spec.rb new file mode 100644 index 0000000..fb53fb9 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/rule_generator_spec.rb @@ -0,0 +1,28 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::RuleGenerator do + let(:decimal_rule){ + JqueryQueryBuilder::Rule.new({ + 'id' => "Decimal_Question", + 'field' => "Decimal_Question", + 'type' => "double", + 'input' => "text", + 'operator' => "equal", + 'value' => "1.2" + }) + } + + describe '#generate' do + it 'should generate using the operator with the value' do + rule_generator = described_class.new(decimal_rule) + + operator = JqueryQueryBuilder::Generators::SQL::Operators::Equal.new + value = 1.2 + + expect(rule_generator).to receive(:get_operator).and_return(operator) + expect(decimal_rule).to receive(:get_value).and_return(value) + + expect(rule_generator.generate).to eq("(Decimal_Question = 1.2)") + end + end +end \ No newline at end of file diff --git a/spec/jquery_query_builder/generators/sql/rule_group_generator_spec.rb b/spec/jquery_query_builder/generators/sql/rule_group_generator_spec.rb new file mode 100644 index 0000000..0d2779c --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/rule_group_generator_spec.rb @@ -0,0 +1,71 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::RuleGroupGenerator do + let(:decimal_rule){ + { + 'id' => "Decimal_Question", + 'field' => "Decimal_Question", + 'type' => "double", + 'input' => "text", + 'operator' => "equal", + 'value' => "1.2" + } + } + let(:boolean_rule){ + { + "id" => "Yes_No_Question", + "field" => "Yes_No_Question", + "type" => "boolean", + "input" => "select", + "operator" => "equal", + "value" => "true" + } + } + + describe '#generate' do + context 'AND' do + let(:rules){[decimal_rule, boolean_rule]} + let(:generator){ + described_class.new( + JqueryQueryBuilder::RuleGroup.new({ + 'condition' => 'AND', + 'rules' => rules + }) + ) + } + it 'should generate an AND sql statement' do + expect(generator.generate).to eq "((Decimal_Question = 1.2) AND (Yes_No_Question = 't'))" + end + end + + context 'OR' do + let(:rules){[decimal_rule, boolean_rule]} + let(:generator){ + described_class.new( + JqueryQueryBuilder::RuleGroup.new({ + 'condition' => 'OR', + 'rules' => rules + }) + ) + } + it 'should generate an OR sql statement' do + expect(generator.generate).to eq "((Decimal_Question = 1.2) OR (Yes_No_Question = 't'))" + end + end + end + + describe '#get_rule_generator' do + context 'passed a rule' do + it 'should return a rule object' do + result = described_class.new(JqueryQueryBuilder::RuleGroup.new({})).get_rule_generator(decimal_rule) + expect(result.is_a?(JqueryQueryBuilder::Generators::SQL::RuleGenerator)).to eq(true) + end + end + context 'passed a rule group' do + it 'should return a rule group' do + result = described_class.new(JqueryQueryBuilder::RuleGroup.new({})).get_rule_generator(JqueryQueryBuilder::RuleGroup.new({'condition' => 'AND', 'rules' => [{}]})) + expect(result.is_a?(JqueryQueryBuilder::Generators::SQL::RuleGroupGenerator)).to eq(true) + end + end + end +end diff --git a/spec/jquery_query_builder/generators/sql/sanitizor_spec.rb b/spec/jquery_query_builder/generators/sql/sanitizor_spec.rb new file mode 100644 index 0000000..728e772 --- /dev/null +++ b/spec/jquery_query_builder/generators/sql/sanitizor_spec.rb @@ -0,0 +1,10 @@ +require 'spec_helper' + +describe JqueryQueryBuilder::Generators::SQL::Sanitizor do + describe '.sanitize' do + it 'should sanitize the sql' do + sanitized_sql = described_class.sanitize(["(lol) = ?", "Robert'); DROP TABLE profiles; --"]) + expect(sanitized_sql).to eq("(lol) = 'Robert''); DROP TABLE profiles; --'") + end + end +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index d7609e3..9805a3e 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,9 @@ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) require 'pry' require 'jquery_query_builder-rails' + +ActiveRecord::Base.establish_connection( + database: 'jquery_query_build_rails_test', + adapter: 'sqlite3', + dbfile: ':memory:' +) \ No newline at end of file