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
data/Rakefile CHANGED
@@ -1,3 +1,6 @@
1
+ require "bundler"
2
+ Bundler.setup
3
+
1
4
  require "rake"
2
5
  require "rspec"
3
6
  require "rspec/core/rake_task"
@@ -1,5 +1,4 @@
1
1
  # encoding: utf-8
2
- module Origin
3
- autoload :Queryable, "origin/queryable"
4
- autoload :Version, "origin/version"
5
- end
2
+ require "origin/forwardable"
3
+ require "origin/queryable"
4
+ require "origin/version"
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ unless defined?(Boolean)
3
+ class Boolean; end
4
+ end
5
+
6
+ if defined?(ActiveSupport)
7
+ require "origin/extensions/time_with_zone"
8
+ end
9
+
10
+ require "time"
11
+ require "origin/extensions/object"
12
+ require "origin/extensions/array"
13
+ require "origin/extensions/big_decimal"
14
+ require "origin/extensions/boolean"
15
+ require "origin/extensions/date"
16
+ require "origin/extensions/date_time"
17
+ require "origin/extensions/hash"
18
+ require "origin/extensions/nil_class"
19
+ require "origin/extensions/numeric"
20
+ require "origin/extensions/range"
21
+ require "origin/extensions/regexp"
22
+ require "origin/extensions/set"
23
+ require "origin/extensions/string"
24
+ require "origin/extensions/symbol"
25
+ require "origin/extensions/time"
@@ -0,0 +1,153 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+ module Extensions
4
+
5
+ # The array module adds custom behaviour for Origin onto the Array class.
6
+ module Array
7
+
8
+ # Combine the two objects using the add strategy.
9
+ #
10
+ # @example Add the object to the array.
11
+ # [ 1, 2, 3 ].__add__(4)
12
+ #
13
+ # @param [ Object ] object The object to add.
14
+ #
15
+ # @return [ Object ] The result of the add.
16
+ #
17
+ # @since 1.0.0
18
+ def __add__(object)
19
+ object.__add_from_array__(self)
20
+ end
21
+
22
+ # Return the object as an array.
23
+ #
24
+ # @example Get the array.
25
+ # [ 1, 2 ].__array__
26
+ #
27
+ # @return [ Array ] self
28
+ #
29
+ # @since 1.0.0
30
+ def __array__; self; end
31
+
32
+ # Makes a deep copy of the array, deep copying every element inside the
33
+ # array.
34
+ #
35
+ # @example Get a deep copy of the array.
36
+ # [ 1, 2, 3 ].__deep_copy__
37
+ #
38
+ # @return [ Array ] The deep copy of the array.
39
+ #
40
+ # @since 1.0.0
41
+ def __deep_copy__
42
+ map { |value| value.__deep_copy__ }
43
+ end
44
+
45
+ # Evolve the array into an array of mongo friendly dates. (Times at
46
+ # midnight).
47
+ #
48
+ # @example Evolve the array to dates.
49
+ # [ Date.new(2010, 1, 1) ].__evolve_date__
50
+ #
51
+ # @return [ Array<Time> ] The array as times at midnight UTC.
52
+ #
53
+ # @since 1.0.0
54
+ def __evolve_date__
55
+ map { |value| value.__evolve_date__ }
56
+ end
57
+
58
+ # Evolve the array to an array of times.
59
+ #
60
+ # @example Evolve the array to times.
61
+ # [ 1231231231 ].__evolve_time__
62
+ #
63
+ # @return [ Array<Time> ] The array as times.
64
+ #
65
+ # @since 1.0.0
66
+ def __evolve_time__
67
+ map { |value| value.__evolve_time__ }
68
+ end
69
+
70
+ # Combine the two objects using an intersection strategy.
71
+ #
72
+ # @example Interset with the object.
73
+ # [ 1, 2 ].__intersect__(3)
74
+ #
75
+ # @param [ Object ] object The object to intersect with.
76
+ #
77
+ # @return [ Object ] The result of the intersection.
78
+ #
79
+ # @since 1.0.0
80
+ def __intersect__(object)
81
+ object.__intersect_from_array__(self)
82
+ end
83
+
84
+ # Gets the array as options in the proper format to pass as MongoDB sort
85
+ # criteria.
86
+ #
87
+ # @example Get the array as sorting options.
88
+ # [ :field, 1 ].__sort_option__
89
+ #
90
+ # @return [ Hash ] The array as sort criterion.
91
+ #
92
+ # @since 1.0.0
93
+ def __sort_option__
94
+ multi.inject({}) do |options, criteria|
95
+ options.merge!(criteria.__sort_pair__)
96
+ options
97
+ end
98
+ end
99
+
100
+ # Get the array as a sort pair.
101
+ #
102
+ # @example Get the array as field/direction pair.
103
+ # [ field, 1 ].__sort_pair__
104
+ #
105
+ # @return [ Hash ] The field/direction pair.
106
+ #
107
+ # @since 1.0.0
108
+ def __sort_pair__
109
+ { first => last.to_direction }
110
+ end
111
+
112
+ private
113
+
114
+ # Converts the array to a multi-dimensional array.
115
+ #
116
+ # @api private
117
+ #
118
+ # @example Convert to multi-dimensional.
119
+ # [ 1, 2, 3 ].multi
120
+ #
121
+ # @return [ Array ] The multi-dimensional array.
122
+ #
123
+ # @since 1.0.0
124
+ def multi
125
+ first.is_a?(::Symbol) || first.is_a?(::String) ? [ self ] : self
126
+ end
127
+
128
+ module ClassMethods
129
+
130
+ # Evolve the object when the serializer is defined as an array.
131
+ #
132
+ # @example Evolve the object.
133
+ # Array.evolve(1)
134
+ #
135
+ # @param [ Object ] The object to evolve.
136
+ #
137
+ # @return [ Object ] The evolved object.
138
+ #
139
+ # @since 1.0.0
140
+ def evolve(object)
141
+ if object.is_a?(::Array)
142
+ object.map!{ |obj| obj.class.evolve(obj) }
143
+ else
144
+ object
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
150
+ end
151
+
152
+ ::Array.__send__(:include, Origin::Extensions::Array)
153
+ ::Array.__send__(:extend, Origin::Extensions::Array::ClassMethods)
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+ require "bigdecimal"
3
+
4
+ module Origin
5
+ module Extensions
6
+
7
+ # The big decimal module adds custom behaviour for Origin onto the
8
+ # BigDecimal class.
9
+ module BigDecimal
10
+ module ClassMethods
11
+
12
+ # Evolves the big decimal into a MongoDB friendly value - in this case
13
+ # a string.
14
+ #
15
+ # @example Evolve the big decimal
16
+ # BigDecimal.evolve(decimal)
17
+ #
18
+ # @param [ BigDecimal ] object The object to convert.
19
+ #
20
+ # @return [ String ] The big decimal as a string.
21
+ #
22
+ # @since 1.0.0
23
+ def evolve(object)
24
+ __evolve__(object) do |obj|
25
+ obj ? obj.to_s : obj
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ ::BigDecimal.__send__(:extend, Origin::Extensions::BigDecimal::ClassMethods)
@@ -0,0 +1,30 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+ module Extensions
4
+
5
+ # This module contains extensions for boolean selection.
6
+ module Boolean
7
+ module ClassMethods
8
+
9
+ # Evolve the value into a boolean value stored in MongoDB. Will return
10
+ # true for any of these values: true, t, yes, y, 1, 1.0.
11
+ #
12
+ # @example Evolve the value to a boolean.
13
+ # Boolean.evolve(true)
14
+ #
15
+ # @param [ Object ] The object to evolve.
16
+ #
17
+ # @return [ true, false ] The boolean value.
18
+ #
19
+ # @since 1.0.0
20
+ def evolve(object)
21
+ __evolve__(object) do |obj|
22
+ obj.to_s =~ (/(true|t|yes|y|1|1.0)$/i) ? true : false
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ ::Boolean.__send__(:extend, Origin::Extensions::Boolean::ClassMethods)
@@ -0,0 +1,59 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+ module Extensions
4
+
5
+ # This module contains additional date behaviour.
6
+ module Date
7
+
8
+ # Evolve the date into a mongo friendly time, UTC midnight.
9
+ #
10
+ # @example Evolve the date.
11
+ # date.__evolve_date__
12
+ #
13
+ # @return [ Time ] The date as a UTC time at midnight.
14
+ #
15
+ # @since 1.0.0
16
+ def __evolve_date__
17
+ ::Time.utc(year, month, day, 0, 0, 0, 0)
18
+ end
19
+
20
+ # Evolve the date into a time, which is always in the local timezone.
21
+ #
22
+ # @example Evolve the date.
23
+ # date.__evolve_time__
24
+ #
25
+ # @return [ Time ] The date as a local time.
26
+ #
27
+ # @since 1.0.0
28
+ def __evolve_time__
29
+ ::Time.local(year, month, day)
30
+ end
31
+
32
+ module ClassMethods
33
+
34
+ # Evolve the object to an date.
35
+ #
36
+ # @example Evolve dates.
37
+ # Date.evolve(Date.new(1990, 1, 1))
38
+ #
39
+ # @example Evolve string dates.
40
+ # Date.evolve("1990-1-1")
41
+ #
42
+ # @example Evolve date ranges.
43
+ # Date.evolve(Date.new(1990, 1, 1)..Date.new(1990, 1, 4))
44
+ #
45
+ # @param [ Object ] object The object to evolve.
46
+ #
47
+ # @return [ Time ] The evolved date.
48
+ #
49
+ # @since 1.0.0
50
+ def evolve(object)
51
+ object.__evolve_date__
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ ::Date.__send__(:include, Origin::Extensions::Date)
59
+ ::Date.__send__(:extend, Origin::Extensions::Date::ClassMethods)
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+ module Extensions
4
+
5
+ # This module contains additional datetime behaviour.
6
+ module DateTime
7
+
8
+ # Evolve the date time into a mongo friendly UTC time.
9
+ #
10
+ # @example Evolve the date time.
11
+ # date_time.__evolve_time__
12
+ #
13
+ # @return [ Time ] The converted time in UTC.
14
+ #
15
+ # @since 1.0.0
16
+ def __evolve_time__
17
+ ::Time.local(year, month, day, hour, min, sec).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
+ ::DateTime.__send__(:include, Origin::Extensions::DateTime)
44
+ ::DateTime.__send__(:extend, Origin::Extensions::DateTime::ClassMethods)
@@ -0,0 +1,180 @@
1
+ # encoding: utf-8
2
+ module Origin
3
+ module Extensions
4
+
5
+ # This module contains additional hash behaviour.
6
+ module Hash
7
+
8
+ # Add an object to a hash using the merge strategies.
9
+ #
10
+ # @example Add an object to a hash.
11
+ # { field: value }.__add__({ field: other_value })
12
+ #
13
+ # @param [ Hash ] object The other hash to add.
14
+ #
15
+ # @return [ Hash ] The hash with object added.
16
+ #
17
+ # @since 1.0.0
18
+ def __add__(object)
19
+ apply_strategy(:__add__, object)
20
+ end
21
+
22
+ # Merge this hash into the provided array.
23
+ #
24
+ # @example Merge the hash into the array.
25
+ # { field: value }.__add_from_array__([ 1, 2 ])
26
+ #
27
+ # @param [ Array ] value The array to add to.
28
+ #
29
+ # @return [ Hash ] The merged hash.
30
+ #
31
+ # @since 1.0.0
32
+ def __add_from_array__(array)
33
+ { keys.first => array.__add__(values.first) }
34
+ end
35
+
36
+ # Add an object to a hash using the merge strategies.
37
+ #
38
+ # @example Add an object to a hash.
39
+ # { field: value }.__intersect__({ field: other_value })
40
+ #
41
+ # @param [ Hash ] object The other hash to intersect.
42
+ #
43
+ # @return [ Hash ] The hash with object intersected.
44
+ #
45
+ # @since 1.0.0
46
+ def __intersect__(object)
47
+ apply_strategy(:__intersect__, object)
48
+ end
49
+
50
+ # Merge this hash into the provided array.
51
+ #
52
+ # @example Merge the hash into the array.
53
+ # { field: value }.__intersect_from_array__([ 1, 2 ])
54
+ #
55
+ # @param [ Array ] value The array to intersect to.
56
+ #
57
+ # @return [ Hash ] The merged hash.
58
+ #
59
+ # @since 1.0.0
60
+ def __intersect_from_array__(array)
61
+ { keys.first => array.__intersect__(values.first) }
62
+ end
63
+
64
+ # Merge this hash into the provided object.
65
+ #
66
+ # @example Merge the hash into the object.
67
+ # { field: value }.__intersect_from_object__([ 1, 2 ])
68
+ #
69
+ # @param [ Object ] value The object to intersect to.
70
+ #
71
+ # @return [ Hash ] The merged hash.
72
+ #
73
+ # @since 1.0.0
74
+ def __intersect_from_object__(object)
75
+ { keys.first => object.__intersect__(values.first) }
76
+ end
77
+
78
+ # Add an object to a hash using the merge strategies.
79
+ #
80
+ # @example Add an object to a hash.
81
+ # { field: value }.__union__({ field: other_value })
82
+ #
83
+ # @param [ Hash ] object The other hash to union.
84
+ #
85
+ # @return [ Hash ] The hash with object unioned.
86
+ #
87
+ # @since 1.0.0
88
+ def __union__(object)
89
+ apply_strategy(:__union__, object)
90
+ end
91
+
92
+ # Merge this hash into the provided object.
93
+ #
94
+ # @example Merge the hash into the object.
95
+ # { field: value }.__union_from_object__([ 1, 2 ])
96
+ #
97
+ # @param [ Object ] value The object to union to.
98
+ #
99
+ # @return [ Hash ] The merged hash.
100
+ #
101
+ # @since 1.0.0
102
+ def __union_from_object__(object)
103
+ { keys.first => object.__union__(values.first) }
104
+ end
105
+
106
+ # Make a deep copy of this hash.
107
+ #
108
+ # @example Make a deep copy of the hash.
109
+ # { field: value }.__deep_copy__
110
+ #
111
+ # @return [ Hash ] The copied hash.
112
+ #
113
+ # @since 1.0.0
114
+ def __deep_copy__
115
+ {}.tap do |copy|
116
+ each_pair do |key, value|
117
+ copy.store(key, value.__deep_copy__)
118
+ end
119
+ end
120
+ end
121
+
122
+ # Get the hash as a sort option.
123
+ #
124
+ # @example Get the hash as a sort option.
125
+ # { field: 1 }.__sort_option__
126
+ #
127
+ # @return [ Hash ] The hash as sort option.
128
+ #
129
+ # @since 1.0.0
130
+ def __sort_option__
131
+ tap do |hash|
132
+ hash.each_pair do |key, value|
133
+ hash.store(key, value.to_direction)
134
+ end
135
+ end
136
+ end
137
+
138
+ # Update all the values in the hash with the provided block.
139
+ #
140
+ # @example Update the values in place.
141
+ # { field: "1" }.update_values(&:to_i)
142
+ #
143
+ # @param [ Proc ] block The block to execute on each value.
144
+ #
145
+ # @return [ Hash ] the hash.
146
+ #
147
+ # @since 1.0.0
148
+ def update_values(&block)
149
+ each_pair do |key, value|
150
+ store(key, block[value])
151
+ end
152
+ end
153
+
154
+ private
155
+
156
+ # Apply the provided strategy for the hash with the given object.
157
+ #
158
+ # @api private
159
+ #
160
+ # @example Apply the strategy.
161
+ # { field: value }.apply_strategy(:__add__, 1)
162
+ #
163
+ # @param [ Symbol ] strategy The strategy to apply.
164
+ # @param [ Object ] object The object to merge.
165
+ #
166
+ # @return [ Hash ] The merged hash.
167
+ #
168
+ # @since 1.0.0
169
+ def apply_strategy(strategy, object)
170
+ tap do |hash|
171
+ object.each_pair do |key, value|
172
+ hash.store(key, hash[key].send(strategy, value))
173
+ end
174
+ end
175
+ end
176
+ end
177
+ end
178
+ end
179
+
180
+ ::Hash.__send__(:include, Origin::Extensions::Hash)