CloudSesame 0.6.8 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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