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.
- data/Rakefile +3 -0
- data/lib/origin.rb +3 -4
- data/lib/origin/extensions.rb +25 -0
- data/lib/origin/extensions/array.rb +153 -0
- data/lib/origin/extensions/big_decimal.rb +33 -0
- data/lib/origin/extensions/boolean.rb +30 -0
- data/lib/origin/extensions/date.rb +59 -0
- data/lib/origin/extensions/date_time.rb +44 -0
- data/lib/origin/extensions/hash.rb +180 -0
- data/lib/origin/extensions/nil_class.rb +82 -0
- data/lib/origin/extensions/numeric.rb +86 -0
- data/lib/origin/extensions/object.rb +182 -0
- data/lib/origin/extensions/range.rb +66 -0
- data/lib/origin/extensions/regexp.rb +41 -0
- data/lib/origin/extensions/set.rb +28 -0
- data/lib/origin/extensions/string.rb +100 -0
- data/lib/origin/extensions/symbol.rb +74 -0
- data/lib/origin/extensions/time.rb +44 -0
- data/lib/origin/extensions/time_with_zone.rb +50 -0
- data/lib/origin/forwardable.rb +57 -0
- data/lib/origin/key.rb +74 -0
- data/lib/origin/macroable.rb +23 -0
- data/lib/origin/mergeable.rb +226 -0
- data/lib/origin/optional.rb +314 -29
- data/lib/origin/options.rb +64 -1
- data/lib/origin/queryable.rb +55 -12
- data/lib/origin/selectable.rb +613 -0
- data/lib/origin/selector.rb +140 -1
- data/lib/origin/smash.rb +85 -0
- data/lib/origin/version.rb +1 -1
- metadata +94 -62
- data/lib/origin/ext.rb +0 -5
- data/lib/origin/ext/array.rb +0 -21
- data/lib/origin/ext/hash.rb +0 -38
- data/lib/origin/ext/nil.rb +0 -9
- data/lib/origin/ext/object.rb +0 -25
- data/lib/origin/optional/batch_size.rb +0 -11
- data/lib/origin/optional/hint.rb +0 -15
- data/lib/origin/optional/limit.rb +0 -11
- data/lib/origin/optional/max_scan.rb +0 -11
- data/lib/origin/optional/no_timeout.rb +0 -11
- data/lib/origin/optional/only.rb +0 -15
- data/lib/origin/optional/read.rb +0 -11
- data/lib/origin/optional/return_key.rb +0 -11
- data/lib/origin/optional/show_disk_loc.rb +0 -11
- data/lib/origin/optional/skip.rb +0 -11
- data/lib/origin/optional/slice.rb +0 -17
- data/lib/origin/optional/snapshot.rb +0 -13
- data/lib/origin/optional/transformer.rb +0 -11
- data/lib/origin/optional/without.rb +0 -15
- data/lib/origin/selection.rb +0 -59
- data/lib/origin/selection/all.rb +0 -18
- data/lib/origin/selection/and.rb +0 -11
- data/lib/origin/selection/between.rb +0 -16
- data/lib/origin/selection/elem_match.rb +0 -18
- data/lib/origin/selection/exists.rb +0 -18
- data/lib/origin/selection/gt.rb +0 -18
- data/lib/origin/selection/gte.rb +0 -18
- data/lib/origin/selection/in.rb +0 -18
- data/lib/origin/selection/key.rb +0 -20
- data/lib/origin/selection/lt.rb +0 -18
- data/lib/origin/selection/lte.rb +0 -18
- data/lib/origin/selection/max_distance.rb +0 -11
- data/lib/origin/selection/mod.rb +0 -18
- data/lib/origin/selection/ne.rb +0 -18
- data/lib/origin/selection/near.rb +0 -18
- data/lib/origin/selection/near_sphere.rb +0 -18
- data/lib/origin/selection/nin.rb +0 -18
- data/lib/origin/selection/nor.rb +0 -11
- data/lib/origin/selection/or.rb +0 -11
- data/lib/origin/selection/size.rb +0 -18
- data/lib/origin/selection/strategies.rb +0 -40
- data/lib/origin/selection/strategies/add.rb +0 -18
- data/lib/origin/selection/strategies/expanded.rb +0 -15
- data/lib/origin/selection/strategies/intersect.rb +0 -22
- data/lib/origin/selection/strategies/multi.rb +0 -21
- data/lib/origin/selection/strategies/override.rb +0 -19
- data/lib/origin/selection/strategies/union.rb +0 -22
- data/lib/origin/selection/type.rb +0 -18
- data/lib/origin/selection/where.rb +0 -29
- data/lib/origin/selection/within_box.rb +0 -18
- data/lib/origin/selection/within_circle.rb +0 -18
- 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
|
data/lib/origin/key.rb
ADDED
@@ -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
|