origin 0.0.0.alpha → 1.0.0.alpha

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 (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