CloudSesame 0.6.8 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (101) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +12 -0
  3. data/.gitignore +1 -1
  4. data/Gemfile.lock +13 -13
  5. data/Guardfile +1 -0
  6. data/cloud_sesame.gemspec +2 -2
  7. data/coverage/.last_run.json +1 -1
  8. data/coverage/.resultset.json +679 -591
  9. data/lib/cloud_sesame/config/credential.rb +6 -6
  10. data/lib/cloud_sesame/context.rb +0 -5
  11. data/lib/cloud_sesame/domain/base.rb +147 -128
  12. data/lib/cloud_sesame/domain/client.rb +25 -25
  13. data/lib/cloud_sesame/domain/client_module/caching/base.rb +19 -23
  14. data/lib/cloud_sesame/domain/client_module/caching/no_cache.rb +11 -11
  15. data/lib/cloud_sesame/domain/client_module/caching/rails_cache.rb +32 -28
  16. data/lib/cloud_sesame/domain/client_module/caching.rb +19 -28
  17. data/lib/cloud_sesame/domain/client_module/retry.rb +6 -6
  18. data/lib/cloud_sesame/domain/config.rb +6 -6
  19. data/lib/cloud_sesame/query/ast/abstract/multi_expression_operator.rb +37 -0
  20. data/lib/cloud_sesame/query/ast/abstract/operator.rb +27 -0
  21. data/lib/cloud_sesame/query/ast/abstract/single_expression_operator.rb +39 -0
  22. data/lib/cloud_sesame/query/ast/abstract/value.rb +88 -0
  23. data/lib/cloud_sesame/query/ast/and.rb +1 -1
  24. data/lib/cloud_sesame/query/ast/date_value.rb +19 -3
  25. data/lib/cloud_sesame/query/ast/literal.rb +13 -28
  26. data/lib/cloud_sesame/query/ast/near.rb +4 -4
  27. data/lib/cloud_sesame/query/ast/not.rb +6 -7
  28. data/lib/cloud_sesame/query/ast/numeric_value.rb +20 -12
  29. data/lib/cloud_sesame/query/ast/or.rb +1 -1
  30. data/lib/cloud_sesame/query/ast/phrase.rb +1 -1
  31. data/lib/cloud_sesame/query/ast/prefix.rb +1 -1
  32. data/lib/cloud_sesame/query/ast/range_value.rb +40 -39
  33. data/lib/cloud_sesame/query/ast/root.rb +2 -6
  34. data/lib/cloud_sesame/query/ast/string_value.rb +26 -0
  35. data/lib/cloud_sesame/query/ast/term.rb +1 -1
  36. data/lib/cloud_sesame/query/ast/value.rb +25 -54
  37. data/lib/cloud_sesame/query/builder.rb +83 -54
  38. data/lib/cloud_sesame/query/domain/block.rb +3 -1
  39. data/lib/cloud_sesame/query/dsl/applied_filter_query.rb +14 -23
  40. data/lib/cloud_sesame/query/dsl/field_accessors.rb +25 -22
  41. data/lib/cloud_sesame/query/dsl/field_array_methods.rb +1 -1
  42. data/lib/cloud_sesame/query/dsl/inspect_method.rb +31 -0
  43. data/lib/cloud_sesame/query/dsl/sort_methods.rb +5 -4
  44. data/lib/cloud_sesame/query/node/abstract.rb +1 -2
  45. data/lib/cloud_sesame/query/node/facet.rb +1 -5
  46. data/lib/cloud_sesame/query/node/filter_query.rb +15 -2
  47. data/lib/cloud_sesame/query/node/fuzziness.rb +4 -3
  48. data/lib/cloud_sesame/query/node/page.rb +2 -2
  49. data/lib/cloud_sesame/query/node/query.rb +4 -17
  50. data/lib/cloud_sesame/query/node/query_options.rb +6 -16
  51. data/lib/cloud_sesame/query/node/query_options_field.rb +3 -1
  52. data/lib/cloud_sesame/query/node/query_parser.rb +8 -10
  53. data/lib/cloud_sesame/query/node/request.rb +57 -31
  54. data/lib/cloud_sesame/query/node/sort.rb +25 -11
  55. data/lib/cloud_sesame.rb +15 -12
  56. data/lib/{abstract_object.rb → services/abstract_object.rb} +0 -0
  57. data/lib/services/class_specific.rb +44 -0
  58. data/lib/services/lazy_object.rb +19 -0
  59. data/spec/cloud_sesame/domain/base_spec.rb +26 -11
  60. data/spec/cloud_sesame/domain/client_module/caching/base_spec.rb +2 -1
  61. data/spec/cloud_sesame/domain/client_module/caching/no_cache_spec.rb +2 -3
  62. data/spec/cloud_sesame/domain/client_module/caching/rails_cache_spec.rb +6 -6
  63. data/spec/cloud_sesame/domain/client_module/caching_spec.rb +33 -32
  64. data/spec/cloud_sesame/query/ast/abstract/multi_expression_operator_spec.rb +67 -0
  65. data/spec/cloud_sesame/query/ast/abstract/operator_spec.rb +29 -0
  66. data/spec/cloud_sesame/query/ast/abstract/single_expression_operator_spec.rb +70 -0
  67. data/spec/cloud_sesame/query/ast/abstract/value_spec.rb +118 -0
  68. data/spec/cloud_sesame/query/ast/and_spec.rb +1 -1
  69. data/spec/cloud_sesame/query/ast/or_spec.rb +1 -1
  70. data/spec/cloud_sesame/query/ast/range_value_spec.rb +5 -11
  71. data/spec/cloud_sesame/query/builder_spec.rb +10 -4
  72. data/spec/cloud_sesame/query/domain/block_spec.rb +15 -8
  73. data/spec/cloud_sesame/query/dsl/{block_methods_spec.rb → block_styled_operators_spec.rb} +0 -0
  74. data/spec/cloud_sesame/query/dsl/field_accessors_spec.rb +88 -50
  75. data/spec/cloud_sesame/query/dsl/field_array_methods_spec.rb +0 -2
  76. data/spec/cloud_sesame/query/node/facet_spec.rb +1 -15
  77. data/spec/cloud_sesame/query/node/filter_query_spec.rb +16 -2
  78. data/spec/cloud_sesame/query/node/page_spec.rb +3 -2
  79. data/spec/cloud_sesame/query/node/query_options_spec.rb +1 -1
  80. data/spec/cloud_sesame/query/node/query_parser_spec.rb +1 -7
  81. data/spec/cloud_sesame/query/node/query_spec.rb +10 -28
  82. data/spec/cloud_sesame/query/node/sort_spec.rb +19 -28
  83. data/spec/cloud_sesame_spec.rb +2 -156
  84. data/spec/helpers/benchmark_helper.rb +12 -0
  85. data/spec/integration/filter_query_spec.rb +0 -0
  86. data/spec/profiling_spec.rb +155 -0
  87. data/spec/{abstract_object_spec.rb → services/abstract_object_spec.rb} +0 -0
  88. data/spec/services/class_specific_spec.rb +135 -0
  89. data/spec/spec_helper.rb +3 -0
  90. metadata +32 -22
  91. data/lib/active_support/core_ext/object/deep_dup.rb +0 -53
  92. data/lib/active_support/core_ext/object/duplicable.rb +0 -98
  93. data/lib/cloud_sesame/query/ast/multi_expression_operator.rb +0 -35
  94. data/lib/cloud_sesame/query/ast/operator.rb +0 -25
  95. data/lib/cloud_sesame/query/ast/single_expression_operator.rb +0 -35
  96. data/lib/cloud_sesame/query/scope.rb +0 -21
  97. data/profiler.rb +0 -91
  98. data/spec/cloud_sesame/query/ast/multi_expression_operator_spec.rb +0 -76
  99. data/spec/cloud_sesame/query/ast/operator_spec.rb +0 -29
  100. data/spec/cloud_sesame/query/ast/single_expression_operator_spec.rb +0 -78
  101. data/spec/context_spec.rb +0 -17
@@ -0,0 +1,39 @@
1
+ module CloudSesame
2
+ module Query
3
+ module AST
4
+ module Abstract
5
+ class SingleExpressionOperator < Operator
6
+
7
+ DETAILED = false
8
+
9
+ attr_accessor :child
10
+
11
+ def <<(object)
12
+ self.child = object
13
+ end
14
+
15
+ def applied(included = true)
16
+ child.applied(included)
17
+ end
18
+
19
+ def compile(_detailed = nil)
20
+ if child && (compiled = child.compile operator_detailed) && !compiled.empty?
21
+ "(#{ symbol }#{ boost } #{ compiled })"
22
+ end
23
+ end
24
+
25
+ def is_for(field, options = {})
26
+ child.is_for field, options if child
27
+ end
28
+
29
+ private
30
+
31
+ def operator_detailed
32
+ self.class::DETAILED
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,88 @@
1
+ module CloudSesame
2
+ module Query
3
+ module AST
4
+ module Abstract
5
+ class Value
6
+
7
+ RANGE_FORMAT = Regexp.new(/\A(\[|{)(.*),(.*)(\}|\])\z/).freeze
8
+ DIGIT_FORMAT = Regexp.new(/\A\d+(.\d+)?\z/).freeze
9
+
10
+ attr_reader :value, :changed, :compiled
11
+
12
+ def self.range?(value)
13
+ value.kind_of?(Range)
14
+ end
15
+
16
+ def self.string_range?(value)
17
+ RANGE_FORMAT =~ strip(value)
18
+ end
19
+
20
+ def self.numeric?(value)
21
+ value.is_a?(Numeric)
22
+ end
23
+
24
+ def self.string_numeric?(value)
25
+ DIGIT_FORMAT =~ value.to_s
26
+ end
27
+
28
+ def self.datetime?(value)
29
+ value.kind_of?(Date) || value.kind_of?(Time)
30
+ end
31
+
32
+ def initialize(value, type = nil)
33
+ self.value = value
34
+ @type = type
35
+ end
36
+
37
+ def value=(value)
38
+ unless @value == value
39
+ @changed = true
40
+ @value = value
41
+ end
42
+ end
43
+
44
+ def compile
45
+ changed ? recompile(value) : @compiled
46
+ end
47
+
48
+ def to_s
49
+ value.to_s
50
+ end
51
+
52
+ def ==(value)
53
+ (value.respond_to?(:compile) && compile == value.compile) ||
54
+ @value == value ||
55
+ compile == value
56
+ end
57
+
58
+ private
59
+
60
+ def recompile(value)
61
+ @changed = false
62
+ @compiled = value
63
+ end
64
+
65
+ # Private Helper Methods
66
+ # ===============================================
67
+
68
+ def self.strip(string)
69
+ string.to_s.tr(' '.freeze, ''.freeze)
70
+ end
71
+
72
+ def self.strip!(string)
73
+ string.to_s.tr!(' '.freeze, ''.freeze)
74
+ end
75
+
76
+ def strip(string)
77
+ string.to_s.tr(' '.freeze, ''.freeze)
78
+ end
79
+
80
+ def strip!(string)
81
+ string.to_s.tr!(' '.freeze, ''.freeze)
82
+ end
83
+
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -1,7 +1,7 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class And < MultiExpressionOperator
4
+ class And < Abstract::MultiExpressionOperator
5
5
  SYMBOL = :and
6
6
  end
7
7
  end
@@ -1,10 +1,26 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class DateValue < Value
4
+ class DateValue < StringValue
5
5
 
6
- def compile
7
- strip escape data.strftime '%FT%TZ'
6
+ FORMAT = '%FT%TZ'.freeze
7
+
8
+ def self.parse(value)
9
+ range?(value) || string_range?(value) ? RangeValue.parse(value, self) : new(value)
10
+ end
11
+
12
+ def to_s
13
+ compile
14
+ end
15
+
16
+ private
17
+
18
+ def recompile(value)
19
+ super strip format value
20
+ end
21
+
22
+ def format(value)
23
+ value.strftime FORMAT
8
24
  end
9
25
 
10
26
  end
@@ -3,22 +3,15 @@ module CloudSesame
3
3
  module AST
4
4
  class Literal
5
5
 
6
- SINGLE_QUATE = /\'/
7
- ESCAPE_QUATE = "\\'"
6
+ SINGLE_QUATE = Regexp.new(/\'/).freeze
7
+ ESCAPE_QUATE = "\\'".freeze
8
8
 
9
- attr_accessor :field
10
- attr_reader :options, :value
9
+ attr_reader :value
11
10
 
12
- def initialize(field, value = nil, options = {})
13
- @field, @options = field, options
14
- self.value = value
15
- end
16
-
17
- def value=(value)
18
- if value
19
- @value = Value.parse value
20
- is_included
21
- end
11
+ def initialize(field, value, options = {})
12
+ @field = field
13
+ @options = options
14
+ @value = LazyObject.new { (options[:type] || Value).parse(value) } if value
22
15
  end
23
16
 
24
17
  def is_for(field, options = {})
@@ -26,34 +19,26 @@ module CloudSesame
26
19
  @options.merge! options
27
20
  end
28
21
 
29
- def is_included
30
- applied[value] = true
31
- end
32
-
33
- def is_excluded
34
- applied[value] = applied[value] == false ? true : false
22
+ def applied(included)
23
+ { field: @field, value: @value, included: included } if @value
35
24
  end
36
25
 
37
26
  def as_field
38
- options[:as] || field
27
+ @options[:as] || @field
39
28
  end
40
29
 
41
30
  def compile(detailed = false)
42
- (detailed ? detailed_format : standard_format) if value
31
+ (detailed ? detailed_format : standard_format) if @value
43
32
  end
44
33
 
45
34
  private
46
35
 
47
- def applied
48
- options[:applied] ||= {}
49
- end
50
-
51
36
  def standard_format
52
- "#{ as_field }:#{ value.compile }"
37
+ "#{ as_field }:#{ @value.compile }"
53
38
  end
54
39
 
55
40
  def detailed_format
56
- "field=#{ escape as_field.to_s } #{ value.compile }"
41
+ "field=#{ escape as_field.to_s } #{ @value.compile }"
57
42
  end
58
43
 
59
44
  def escape(data)
@@ -1,15 +1,15 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class Near < SingleExpressionOperator
4
+ class Near < Abstract::SingleExpressionOperator
5
5
  DETAILED = true
6
- SYMBOL = :near
6
+ SYMBOL = :near
7
7
 
8
- def compile(_detailed = nil)
8
+ def compile(_detailed = nil)
9
9
  if child && (compiled = child.compile operator_detailed) && !compiled.empty?
10
10
  "(#{ symbol }#{ boost }#{ distance } #{ compiled })"
11
11
  end
12
- end
12
+ end
13
13
 
14
14
  def distance
15
15
  " distance=#{ options[:distance] }" if options[:distance]
@@ -1,13 +1,8 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class Not < SingleExpressionOperator
5
- SYMBOL = :not
6
-
7
- def <<(object)
8
- object.is_excluded
9
- self.child = object
10
- end
4
+ class Not < Abstract::SingleExpressionOperator
5
+ SYMBOL = :not
11
6
 
12
7
  def compile
13
8
  if child && (compiled = child.compile) && !compiled.empty?
@@ -15,6 +10,10 @@ module CloudSesame
15
10
  end
16
11
  end
17
12
 
13
+ def applied(included = true)
14
+ child.applied(!included)
15
+ end
16
+
18
17
  end
19
18
  end
20
19
  end
@@ -1,19 +1,27 @@
1
1
  module CloudSesame
2
- module Query
3
- module AST
4
- class NumericValue < Value
2
+ module Query
3
+ module AST
4
+ class NumericValue < Abstract::Value
5
5
 
6
- def compile
7
- data.to_s
8
- end
6
+ def self.parse(value)
7
+ range?(value) || string_range?(value) ? RangeValue.parse(value, self) : new(value)
8
+ end
9
+
10
+ def to_s
11
+ compile
12
+ end
9
13
 
10
14
  def ==(value)
11
- value == data.to_f ||
12
- value == data ||
13
- value == compile
15
+ value == @value.to_f || value == @value || value == compile
16
+ end
17
+
18
+ private
19
+
20
+ def recompile(value)
21
+ super value.to_s
14
22
  end
15
23
 
16
- end
17
- end
18
- end
24
+ end
25
+ end
26
+ end
19
27
  end
@@ -1,7 +1,7 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class Or < MultiExpressionOperator
4
+ class Or < Abstract::MultiExpressionOperator
5
5
  SYMBOL = :or
6
6
  end
7
7
  end
@@ -1,7 +1,7 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class Phrase < SingleExpressionOperator
4
+ class Phrase < Abstract::SingleExpressionOperator
5
5
  DETAILED = true
6
6
  SYMBOL = :phrase
7
7
  end
@@ -1,7 +1,7 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class Prefix < SingleExpressionOperator
4
+ class Prefix < Abstract::SingleExpressionOperator
5
5
  DETAILED = true
6
6
  SYMBOL = :prefix
7
7
  end
@@ -1,78 +1,79 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class RangeValue < Value
5
-
6
- RANGE_FORMAT = /\A(\[|{)(.*),(.*)(\}|\])\z/
7
-
8
- def initialize(value = nil)
9
- @data = (
10
- if value.kind_of?(Range)
11
- range_to_array(value)
12
- elsif value.is_a?(String) && (match = string_format?(value))
13
- data = match.captures
14
- data[1, 2] = data[1, 2].map { |i| Value.parse(i) unless i.nil? || i.empty? }
15
- data
16
- else
17
- default_range
18
- end
19
- )
4
+ class RangeValue < Abstract::Value
5
+
6
+ def initialize(value = nil, type = nil)
7
+
8
+ self.value = RangeValue.range?(value) ? range_handler(value) :
9
+ RangeValue.string_range?(value) ? string_handler(value) :
10
+ empty_value
11
+
12
+ self.type = type if type
20
13
  end
21
14
 
22
- def gt(value = nil)
15
+ def type=(type)
16
+ value_type_handler(type) if (@type = type)
17
+ type
18
+ end
19
+
20
+ def gt(value)
23
21
  update_lower_value(value) if value
24
22
  return self
25
23
  end
26
24
 
27
- def gte(value = nil)
28
- update_lower_value(value, true) if value
25
+ def gte(value)
26
+ update_lower_value(value, '[') if value
29
27
  return self
30
28
  end
31
29
 
32
- def lt(value = nil)
30
+ def lt(value)
33
31
  update_uppoer_value(value) if value
34
32
  return self
35
33
  end
36
34
 
37
- def lte(value = nil)
38
- update_uppoer_value(value, true) if value
35
+ def lte(value)
36
+ update_uppoer_value(value, ']') if value
39
37
  return self
40
38
  end
41
39
 
42
- def compile
43
- "#{ data[0] }#{ data[1] },#{ data[2] }#{ data[3] }"
40
+ def to_s
41
+ compile
44
42
  end
45
43
 
46
44
  def ==(object)
47
- data == Value.parse(object).data
45
+ value == RangeValue.new(object, Value).value
48
46
  end
49
47
 
50
48
  private
51
49
 
52
- def update_lower_value(value, included = false)
53
- data[0], data[1] = (included ? '[' : '{'), Value.parse(value)
50
+ def recompile(value)
51
+ super "#{ value[0] }#{ value[1] },#{ value[2] }#{ value[3] }"
52
+ end
53
+
54
+ def update_lower_value(value, included = '{')
55
+ self.value[0] = included
56
+ self.value[1] = value
54
57
  end
55
58
 
56
- def update_uppoer_value(value, included = false)
57
- data[2], data[3] = Value.parse(value), (included ? ']' : '}')
59
+ def update_uppoer_value(value, included = '}')
60
+ self.value[2] = value
61
+ self.value[3] = included
58
62
  end
59
63
 
60
- def string_format?(string)
61
- RANGE_FORMAT.match string.tr(' ', '')
64
+ def range_handler(value)
65
+ ['[', value.begin, value.end, value.exclude_end? ? '}' : ']']
62
66
  end
63
67
 
64
- def range_to_array(range)
65
- ['[',
66
- Value.parse(range.begin),
67
- Value.parse(range.end),
68
- end_symbol(range)]
68
+ def string_handler(value)
69
+ RANGE_FORMAT.match(strip(value)).captures
69
70
  end
70
71
 
71
- def end_symbol(value)
72
- value.exclude_end? ? '}' : ']'
72
+ def value_type_handler(type)
73
+ self.value[1, 2] = value[1, 2].map { |v| type.parse(v) unless v.to_s.empty? }
73
74
  end
74
75
 
75
- def default_range
76
+ def empty_value
76
77
  ['{', nil, nil, '}']
77
78
  end
78
79
 
@@ -1,15 +1,11 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class Root < MultiExpressionOperator
4
+ class Root < Abstract::MultiExpressionOperator
5
5
  SYMBOL = :and # default operator for root
6
6
 
7
7
  def compile
8
- more_than_one_child? ? super : children.compile
9
- end
10
-
11
- def more_than_one_child?
12
- children.size > 1
8
+ children.size > 1 ? super : children.compile
13
9
  end
14
10
 
15
11
  private
@@ -0,0 +1,26 @@
1
+ module CloudSesame
2
+ module Query
3
+ module AST
4
+ class StringValue < Abstract::Value
5
+
6
+ SINGLE_QUATE = Regexp.new(/\'/).freeze
7
+ ESCAPE_QUATE = "\\'".freeze
8
+
9
+ def self.parse(value)
10
+ new value.to_s if value
11
+ end
12
+
13
+ private
14
+
15
+ def recompile(value)
16
+ super escape value.to_s
17
+ end
18
+
19
+ def escape(value)
20
+ "'#{ value.gsub(SINGLE_QUATE) { ESCAPE_QUATE } }'"
21
+ end
22
+
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,7 +1,7 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class Term < SingleExpressionOperator
4
+ class Term < Abstract::SingleExpressionOperator
5
5
  DETAILED = true
6
6
  SYMBOL = :term
7
7
  end
@@ -1,70 +1,41 @@
1
1
  module CloudSesame
2
2
  module Query
3
3
  module AST
4
- class Value
4
+ class Value < Abstract::Value
5
5
 
6
- RANGE_FORMAT = /\A(\[|{)(.*),(.*)(\}|\])\z/
7
- DIGIT_FORMAT = /\A\d+(.\d+)?\z/
8
- SINGLE_QUATE = /\'/
9
- ESCAPE_QUATE = "\\'"
6
+ TYPES = {
7
+ string: StringValue,
8
+ numeric: NumericValue,
9
+ date: DateValue
10
+ }
10
11
 
11
- attr_reader :data
12
-
13
- def self.parse(value)
14
- return value if value.kind_of? AST::Value
15
- (
16
- is_a_numeric?(value) ? AST::NumericValue :
17
- is_a_datetime?(value) ? AST::DateValue :
18
- is_a_range?(value) ? AST::RangeValue :
19
- AST::Value
20
- ).new(value)
21
- end
22
-
23
- def self.is_a_numeric?(value)
24
- value.is_a?(Numeric) || (value.is_a?(String) && DIGIT_FORMAT =~ value)
25
- end
26
-
27
- def self.is_a_datetime?(value)
28
- value.kind_of?(Date) || value.kind_of?(Time)
29
- end
30
-
31
- def self.is_a_range?(value)
32
- value.kind_of?(Range) || (value.is_a?(String) && RANGE_FORMAT =~ value)
33
- end
34
-
35
- def initialize(data)
36
- @data = data
37
- end
38
-
39
- def compile
40
- updated? ? recompile : @compiled
41
- end
42
-
43
- def to_s
44
- compile
12
+ def self.map_type(symbol)
13
+ (klass =TYPES[symbol]) ? klass : self
45
14
  end
46
15
 
47
- def ==(value)
48
- value == data || value == compile
49
- end
50
-
51
- private
16
+ # if the value is already a range value object
17
+ # set the type to Value and return the value
18
+ # else determine the type of value and create it
19
+ def self.parse(value)
20
+ if value.kind_of?(RangeValue)
21
+ value.type = self
22
+ return value
23
+ end
52
24
 
53
- def updated?
54
- @compiled_data != @data
55
- end
25
+ (
26
+ range_value?(value) ? RangeValue :
27
+ numeric_value?(value) ? NumericValue :
28
+ datetime?(value) ? DateValue : StringValue
29
+ ).new(value, self)
56
30
 
57
- def recompile
58
- @compiled_data = @data
59
- @compiled = escape @compiled_data
60
31
  end
61
32
 
62
- def escape(data)
63
- "'#{ data.gsub(SINGLE_QUATE) { ESCAPE_QUATE } }'"
33
+ def self.range_value?(value)
34
+ range?(value) || string_range?(value)
64
35
  end
65
36
 
66
- def strip(string)
67
- string.tr(" ", "")
37
+ def self.numeric_value?(value)
38
+ numeric?(value) || string_numeric?(value)
68
39
  end
69
40
 
70
41
  end