origin 0.0.0.alpha → 1.0.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. data/Rakefile +3 -0
  2. data/lib/origin.rb +3 -4
  3. data/lib/origin/extensions.rb +25 -0
  4. data/lib/origin/extensions/array.rb +153 -0
  5. data/lib/origin/extensions/big_decimal.rb +33 -0
  6. data/lib/origin/extensions/boolean.rb +30 -0
  7. data/lib/origin/extensions/date.rb +59 -0
  8. data/lib/origin/extensions/date_time.rb +44 -0
  9. data/lib/origin/extensions/hash.rb +180 -0
  10. data/lib/origin/extensions/nil_class.rb +82 -0
  11. data/lib/origin/extensions/numeric.rb +86 -0
  12. data/lib/origin/extensions/object.rb +182 -0
  13. data/lib/origin/extensions/range.rb +66 -0
  14. data/lib/origin/extensions/regexp.rb +41 -0
  15. data/lib/origin/extensions/set.rb +28 -0
  16. data/lib/origin/extensions/string.rb +100 -0
  17. data/lib/origin/extensions/symbol.rb +74 -0
  18. data/lib/origin/extensions/time.rb +44 -0
  19. data/lib/origin/extensions/time_with_zone.rb +50 -0
  20. data/lib/origin/forwardable.rb +57 -0
  21. data/lib/origin/key.rb +74 -0
  22. data/lib/origin/macroable.rb +23 -0
  23. data/lib/origin/mergeable.rb +226 -0
  24. data/lib/origin/optional.rb +314 -29
  25. data/lib/origin/options.rb +64 -1
  26. data/lib/origin/queryable.rb +55 -12
  27. data/lib/origin/selectable.rb +613 -0
  28. data/lib/origin/selector.rb +140 -1
  29. data/lib/origin/smash.rb +85 -0
  30. data/lib/origin/version.rb +1 -1
  31. metadata +94 -62
  32. data/lib/origin/ext.rb +0 -5
  33. data/lib/origin/ext/array.rb +0 -21
  34. data/lib/origin/ext/hash.rb +0 -38
  35. data/lib/origin/ext/nil.rb +0 -9
  36. data/lib/origin/ext/object.rb +0 -25
  37. data/lib/origin/optional/batch_size.rb +0 -11
  38. data/lib/origin/optional/hint.rb +0 -15
  39. data/lib/origin/optional/limit.rb +0 -11
  40. data/lib/origin/optional/max_scan.rb +0 -11
  41. data/lib/origin/optional/no_timeout.rb +0 -11
  42. data/lib/origin/optional/only.rb +0 -15
  43. data/lib/origin/optional/read.rb +0 -11
  44. data/lib/origin/optional/return_key.rb +0 -11
  45. data/lib/origin/optional/show_disk_loc.rb +0 -11
  46. data/lib/origin/optional/skip.rb +0 -11
  47. data/lib/origin/optional/slice.rb +0 -17
  48. data/lib/origin/optional/snapshot.rb +0 -13
  49. data/lib/origin/optional/transformer.rb +0 -11
  50. data/lib/origin/optional/without.rb +0 -15
  51. data/lib/origin/selection.rb +0 -59
  52. data/lib/origin/selection/all.rb +0 -18
  53. data/lib/origin/selection/and.rb +0 -11
  54. data/lib/origin/selection/between.rb +0 -16
  55. data/lib/origin/selection/elem_match.rb +0 -18
  56. data/lib/origin/selection/exists.rb +0 -18
  57. data/lib/origin/selection/gt.rb +0 -18
  58. data/lib/origin/selection/gte.rb +0 -18
  59. data/lib/origin/selection/in.rb +0 -18
  60. data/lib/origin/selection/key.rb +0 -20
  61. data/lib/origin/selection/lt.rb +0 -18
  62. data/lib/origin/selection/lte.rb +0 -18
  63. data/lib/origin/selection/max_distance.rb +0 -11
  64. data/lib/origin/selection/mod.rb +0 -18
  65. data/lib/origin/selection/ne.rb +0 -18
  66. data/lib/origin/selection/near.rb +0 -18
  67. data/lib/origin/selection/near_sphere.rb +0 -18
  68. data/lib/origin/selection/nin.rb +0 -18
  69. data/lib/origin/selection/nor.rb +0 -11
  70. data/lib/origin/selection/or.rb +0 -11
  71. data/lib/origin/selection/size.rb +0 -18
  72. data/lib/origin/selection/strategies.rb +0 -40
  73. data/lib/origin/selection/strategies/add.rb +0 -18
  74. data/lib/origin/selection/strategies/expanded.rb +0 -15
  75. data/lib/origin/selection/strategies/intersect.rb +0 -22
  76. data/lib/origin/selection/strategies/multi.rb +0 -21
  77. data/lib/origin/selection/strategies/override.rb +0 -19
  78. data/lib/origin/selection/strategies/union.rb +0 -22
  79. data/lib/origin/selection/type.rb +0 -18
  80. data/lib/origin/selection/where.rb +0 -29
  81. data/lib/origin/selection/within_box.rb +0 -18
  82. data/lib/origin/selection/within_circle.rb +0 -18
  83. data/lib/origin/selection/within_spherical_circle.rb +0 -18
@@ -0,0 +1,28 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+ module Extensions
4
+
5
+ # This module contains additional object behaviour.
6
+ module Set
7
+ module ClassMethods
8
+
9
+ # Evolve the set, casting all its elements.
10
+ #
11
+ # @example Evolve the set.
12
+ # Set.evolve(set)
13
+ #
14
+ # @param [ Set, Object ] object The object to evolve.
15
+ #
16
+ # @return [ Array ] The evolved set.
17
+ #
18
+ # @since 1.0.0
19
+ def evolve(object)
20
+ return object if !object || !object.respond_to?(:map)
21
+ object.map{ |obj| obj.class.evolve(obj) }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ ::Set.__send__(:extend, Origin::Extensions::Set::ClassMethods)
@@ -0,0 +1,100 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+ module Extensions
4
+
5
+ # This module contains additional object behaviour.
6
+ module String
7
+
8
+ # Evolve the string into a mongodb friendly date.
9
+ #
10
+ # @example Evolve the string.
11
+ # "2012-1-1".__evolve_date__
12
+ #
13
+ # @return [ Time ] The time at UTC midnight.
14
+ #
15
+ # @since 1.0.0
16
+ def __evolve_date__
17
+ time = ::Time.parse(self)
18
+ ::Time.utc(time.year, time.month, time.day, 0, 0, 0, 0)
19
+ end
20
+
21
+ # Evolve the string into a mongodb friendly time.
22
+ #
23
+ # @example Evolve the string.
24
+ # "2012-1-1".__evolve_time__
25
+ #
26
+ # @return [ Time ] The string as a time.
27
+ #
28
+ # @since 1.0.0
29
+ def __evolve_time__
30
+ ::Time.parse(self).utc
31
+ end
32
+
33
+ # Get the string as a sort option.
34
+ #
35
+ # @example Get the string as a sort option.
36
+ # "field ASC".__sort_option__
37
+ #
38
+ # @return [ Hash ] The string as a sort option hash.
39
+ #
40
+ # @since 1.0.0
41
+ def __sort_option__
42
+ split(/,/).inject({}) do |hash, spec|
43
+ hash.tap do |_hash|
44
+ field, direction = spec.strip.split(/\s/)
45
+ _hash[field.to_sym] = direction.to_direction
46
+ end
47
+ end
48
+ end
49
+
50
+ # Get the string as a specification.
51
+ #
52
+ # @example Get the string as a criteria.
53
+ # "field".specify(value)
54
+ #
55
+ # @param [ Object ] value The value of the criteria.
56
+ #
57
+ # @return [ Hash ] The selection.
58
+ #
59
+ # @since 1.0.0
60
+ def specify(value)
61
+ { self => value }
62
+ end
63
+
64
+ # Get the string as a sort direction.
65
+ #
66
+ # @example Get the string as a sort direction.
67
+ # "1".to_direction
68
+ #
69
+ # @return [ Integer ] The direction.
70
+ #
71
+ # @since 1.0.0
72
+ def to_direction
73
+ self =~ /desc/i ? -1 : 1
74
+ end
75
+
76
+ module ClassMethods
77
+
78
+ # Evolves the string into a MongoDB friendly value - in this case
79
+ # a string.
80
+ #
81
+ # @example Evolve the string
82
+ # String.evolve(1)
83
+ #
84
+ # @param [ Object ] object The object to convert.
85
+ #
86
+ # @return [ String ] The value as a string.
87
+ #
88
+ # @since 1.0.0
89
+ def evolve(object)
90
+ __evolve__(object) do |obj|
91
+ obj.regexp? ? obj : obj.to_s
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+
99
+ ::String.__send__(:include, Origin::Extensions::String)
100
+ ::String.__send__(:extend, Origin::Extensions::String::ClassMethods)
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+ module Extensions
4
+
5
+ # This module contains additional symbol behaviour.
6
+ module Symbol
7
+
8
+ # Get the symbol as a specification.
9
+ #
10
+ # @example Get the symbol as a criteria.
11
+ # :field.specify(value)
12
+ #
13
+ # @param [ Object ] value The value of the criteria.
14
+ #
15
+ # @return [ Hash ] The selection.
16
+ #
17
+ # @since 1.0.0
18
+ def specify(value)
19
+ { self => value }
20
+ end
21
+
22
+ # Get the symbol as a sort direction.
23
+ #
24
+ # @example Get the symbol as a sort direction.
25
+ # "1".to_direction
26
+ #
27
+ # @return [ Integer ] The direction.
28
+ #
29
+ # @since 1.0.0
30
+ def to_direction
31
+ to_s.to_direction
32
+ end
33
+
34
+ module ClassMethods
35
+
36
+ # Adds a method on symbol as a convenience for the MongoDB operator.
37
+ #
38
+ # @example Add the $in method.
39
+ # Symbol.add_key(:in, "$in")
40
+ #
41
+ # @param [ Symbol ] name The name of the method.
42
+ # @param [ Symbol ] strategy The name of the merge strategy.
43
+ # @param [ String ] operator The MongoDB operator.
44
+ # @param [ String ] additional The additional MongoDB operator.
45
+ #
46
+ # @since 1.0.0
47
+ def add_key(name, strategy, operator, additional = nil, &block)
48
+ define_method(name) do
49
+ method = "__#{strategy}__".to_sym
50
+ Key.new(self, method, operator, additional, &block)
51
+ end
52
+ end
53
+
54
+ # Evolves the symbol into a MongoDB friendly value - in this case
55
+ # a symbol.
56
+ #
57
+ # @example Evolve the symbol
58
+ # Symbol.evolve("test")
59
+ #
60
+ # @param [ Object ] object The object to convert.
61
+ #
62
+ # @return [ Symbol ] The value as a symbol.
63
+ #
64
+ # @since 1.0.0
65
+ def evolve(object)
66
+ __evolve__(object) { |obj| obj.to_sym }
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ ::Symbol.__send__(:include, Origin::Extensions::Symbol)
74
+ ::Symbol.__send__(:extend, Origin::Extensions::Symbol::ClassMethods)
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+ module Extensions
4
+
5
+ # This module contains additional time behaviour.
6
+ module Time
7
+
8
+ # Evolve the time into a utc time.
9
+ #
10
+ # @example Evolve the time.
11
+ # time.__evolve_time__
12
+ #
13
+ # @return [ Time ] The time in UTC.
14
+ #
15
+ # @since 1.0.0
16
+ def __evolve_time__
17
+ utc
18
+ end
19
+
20
+ module ClassMethods
21
+
22
+ # Evolve the object to an date.
23
+ #
24
+ # @example Evolve dates.
25
+ #
26
+ # @example Evolve string dates.
27
+ #
28
+ # @example Evolve date ranges.
29
+ #
30
+ # @param [ Object ] object The object to evolve.
31
+ #
32
+ # @return [ Time ] The evolved date time.
33
+ #
34
+ # @since 1.0.0
35
+ def evolve(object)
36
+ object.__evolve_time__
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ ::Time.__send__(:include, Origin::Extensions::Time)
44
+ ::Time.__send__(:extend, Origin::Extensions::Time::ClassMethods)
@@ -0,0 +1,50 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+ module Extensions
4
+
5
+ # This module contains additional time with zone behaviour.
6
+ module TimeWithZone
7
+
8
+ # Evolve the time into a utc time.
9
+ #
10
+ # @example Evolve the time.
11
+ # time.__evolve_time__
12
+ #
13
+ # @return [ Time ] The time in UTC.
14
+ #
15
+ # @since 1.0.0
16
+ def __evolve_time__
17
+ utc
18
+ end
19
+
20
+ module ClassMethods
21
+
22
+ # Evolve the object to an date.
23
+ #
24
+ # @example Evolve dates.
25
+ #
26
+ # @example Evolve string dates.
27
+ #
28
+ # @example Evolve date ranges.
29
+ #
30
+ # @param [ Object ] object The object to evolve.
31
+ #
32
+ # @return [ Time ] The evolved date time.
33
+ #
34
+ # @since 1.0.0
35
+ def evolve(object)
36
+ object.__evolve_time__
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ ::ActiveSupport::TimeWithZone.__send__(
44
+ :include,
45
+ Origin::Extensions::TimeWithZone
46
+ )
47
+ ::ActiveSupport::TimeWithZone.__send__(
48
+ :extend,
49
+ Origin::Extensions::TimeWithZone::ClassMethods
50
+ )
@@ -0,0 +1,57 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+
4
+ # Allows for easy delegation of origin queryable instance methods to a
5
+ # specific method.
6
+ module Forwardable
7
+
8
+ # Tells origin with method on the class to delegate to when calling an
9
+ # original selectable or optional method on the class.
10
+ #
11
+ # @example Tell origin where to select from.
12
+ # class Band
13
+ # extend Origin::Forwardable
14
+ # select_with :criteria
15
+ #
16
+ # def self.criteria
17
+ # Query.new
18
+ # end
19
+ # end
20
+ #
21
+ # @param [ Symbol ] receiver The name of the receiver method.
22
+ #
23
+ # @return [ Array<Symbol> ] The names of the forwarded methods.
24
+ #
25
+ # @since 1.0.0
26
+ def select_with(receiver)
27
+ (Selectable.forwardables + Optional.forwardables).each do |name|
28
+ __forward__(name, receiver)
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ # Forwards the method name to the provided receiver method.
35
+ #
36
+ # @api private
37
+ #
38
+ # @example Define the forwarding.
39
+ # Model.__forward__(:exists, :criteria)
40
+ #
41
+ # @param [ Symbol ] name The name of the method.
42
+ # @param [ Symbol ] receiver The name of the receiver method.
43
+ #
44
+ # @since 1.0.0
45
+ def __forward__(name, receiver)
46
+ if self.class == Module
47
+ module_eval <<-SEL
48
+ delegate :#{name}, to: :#{receiver}
49
+ SEL
50
+ else
51
+ (class << self; self; end).class_eval <<-SEL
52
+ delegate :#{name}, to: :#{receiver}
53
+ SEL
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,74 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+
4
+ # The key is a representation of a field in a queryable, that can be
5
+ # expanded to special MongoDB selectors.
6
+ class Key
7
+
8
+ # @attribute [r] name The name of the field.
9
+ # @attribute [r] block The optional block to transform values.
10
+ # @attribute [r] operator The MongoDB query operator.
11
+ # @attribute [r] expanded The MongoDB expanded query operator.
12
+ # @attribute [r] strategy The name of the merge strategy.
13
+ attr_reader :block, :name, :operator, :expanded, :strategy
14
+
15
+ # Does the key equal another object?
16
+ #
17
+ # @example Is the key equal to another?
18
+ # key == other
19
+ #
20
+ # @param [ Object ] other The object to compare to.
21
+ #
22
+ # @return [ true, false ] If the objects are equal.
23
+ #
24
+ # @since 1.0.0
25
+ def ==(other)
26
+ return false unless other.is_a?(Key)
27
+ name == other.name && operator == other.operator && expanded == other.expanded
28
+ end
29
+
30
+ # Instantiate the new key.
31
+ #
32
+ # @example Instantiate the key.
33
+ # Key.new("age", "$gt")
34
+ #
35
+ # @param [ String, Symbol ] name The field name.
36
+ # @param [ Symbol ] strategy The name of the merge strategy.
37
+ # @param [ String ] operator The Mongo operator.
38
+ # @param [ String ] expanded The Mongo expanded operator.
39
+ #
40
+ # @since 1.0.0
41
+ def initialize(name, strategy, operator, expanded = nil, &block)
42
+ @name, @strategy, @operator, @expanded, @block =
43
+ name, strategy, operator, expanded, block
44
+ end
45
+
46
+ # Gets the raw selector that would be passed to Mongo from this key.
47
+ #
48
+ # @example Specify the raw selector.
49
+ # key.specify(50)
50
+ #
51
+ # @param [ Object ] object The value to be included.
52
+ #
53
+ # @return [ Hash ] The raw MongoDB selector.
54
+ #
55
+ # @since 1.0.0
56
+ def specify(object)
57
+ value = block ? block[object] : object
58
+ { name.to_s => { operator => expanded ? { expanded => value } : value }}
59
+ end
60
+
61
+ # Get the key as raw Mongo sorting options.
62
+ #
63
+ # @example Get the key as a sort.
64
+ # key.__sort_option__
65
+ #
66
+ # @return [ Hash ] The field/direction pair.
67
+ #
68
+ # @since 1.0.0
69
+ def __sort_option__
70
+ { name => operator }
71
+ end
72
+ alias :__sort_pair__ :__sort_option__
73
+ end
74
+ end
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+
4
+ # Adds macro behaviour for adding symbol methods.
5
+ module Macroable
6
+
7
+ # Adds a method on Symbol for convenience in where queries for the
8
+ # provided operators.
9
+ #
10
+ # @example Add a symbol key.
11
+ # key :all, "$all
12
+ #
13
+ # @param [ Symbol ] name The name of the method.
14
+ # @param [ Symbol ] strategy The merge strategy.
15
+ # @param [ String ] operator The MongoDB operator.
16
+ # @param [ String ] additional The additional MongoDB operator.
17
+ #
18
+ # @since 1.0.0
19
+ def key(name, strategy, operator, additional = nil, &block)
20
+ ::Symbol.add_key(name, strategy, operator, additional, &block)
21
+ end
22
+ end
23
+ end