Class: Armada::Relation
- Inherits:
-
Object
show all
- Defined in:
- lib/armada/relation.rb
Constant Summary
collapse
- FIND_OPTIONS_KEYS =
%w(where offset order limit only distinct)
Instance Method Summary
collapse
Constructor Details
#initialize(superclass) ⇒ Relation
Returns a new instance of Relation.
29
30
31
32
|
# File 'lib/armada/relation.rb', line 29
def initialize(superclass)
@superclass = superclass
@join = "and"
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
# File 'lib/armada/relation.rb', line 147
def method_missing(method, *args, &block)
method = method.to_s
if %w(create_index drop_index).include?(method)
singleton_class.send(:define_method, method) do
raise(ArgumentError, "Missing 'order' condition") unless option_defined?(:order)
query(to_query(method, @order)) == 1
end.call
elsif %w(delete count update insert select checked_write multi_read multi_write list_indexes).include?(method)
singleton_class.send(:define_method, method) do |*args, &block|
query(to_query(method, *args, &block))
end.call(*args, &block)
else
super
end
end
|
Instance Method Details
#all ⇒ Object
130
131
132
133
134
|
# File 'lib/armada/relation.rb', line 130
def all
results = self.select
return results if option_defined?(:only) || @superclass.is_a?(String)
results.map { |record| @superclass.send(:instantiate, record) }
end
|
#distinct ⇒ Object
122
123
124
|
# File 'lib/armada/relation.rb', line 122
def distinct
self.dup.tap { |r| r.set_option(:distinct, true) }
end
|
#get_option(option) ⇒ Object
141
142
143
|
# File 'lib/armada/relation.rb', line 141
def get_option(option)
instance_variable_get("@#{option}")
end
|
#limit(value) ⇒ Object
83
84
85
|
# File 'lib/armada/relation.rb', line 83
def limit(value)
self.dup.tap { |r| r.set_option(:limit, value) }
end
|
#offset(value) ⇒ Object
79
80
81
|
# File 'lib/armada/relation.rb', line 79
def offset(value)
self.dup.tap { |r| r.set_option(:offset, value) }
end
|
#only(*attributes) ⇒ Object
111
112
113
114
115
116
117
118
119
120
|
# File 'lib/armada/relation.rb', line 111
def only(*attributes)
attributes.flatten!
only = if option_defined?(:only)
Array.wrap(@only).concat(attributes)
else
attributes.size == 1 ? attributes.first : attributes
end
self.dup.tap { |r| r.set_option(:only, only) }
end
|
#or ⇒ Object
74
75
76
77
|
# File 'lib/armada/relation.rb', line 74
def or
raise(ArgumentError, "Missing 'where' condition") unless option_defined?(:where)
self.dup.tap { |r| r.set_option(:join, "or") }
end
|
#order(*attributes) ⇒ Object
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
|
# File 'lib/armada/relation.rb', line 87
def order(*attributes)
options = attributes.
attributes.flatten!
attributes.map! do |attribute|
attribute.is_a?(Array) ? attribute : [attribute, :asc]
end
order = attributes.concat(options.to_a).tap do |order|
order.flatten! if order.size == 1
end
old_order = @order
new_order = if option_defined?(:order)
old_order = [old_order] unless old_order.first.is_a?(Array)
order.first.is_a?(Array) ? old_order.concat(order) : old_order << order
else
order
end
self.dup.tap { |r| r.set_option(:order, new_order) }
end
|
#set_option(option, value) ⇒ Object
137
138
139
|
# File 'lib/armada/relation.rb', line 137
def set_option(option, value)
instance_variable_set("@#{option}", value)
end
|
#to_query(method = nil, *args, &block) ⇒ Object
126
127
128
|
# File 'lib/armada/relation.rb', line 126
def to_query(method = nil, *args, &block)
method ? send("generate_#{method}_query", *args, &block) : find_options
end
|
#where(conditions) ⇒ Object
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
|
# File 'lib/armada/relation.rb', line 34
def where(conditions)
where = []
conditions.each_pair do |attribute, value|
if value.is_a?(Hash)
value.each_pair do |operator, val|
where << [operator, attribute, build_condition_value(val)]
end
else
where << build_condition(attribute, value)
end
end
where = where.size > 1 ? where.unshift("and") : where.first
join, old_where = [@join, @where]
new_where = if option_defined?(:where)
if join == old_where.first && old_where.first == where.first
old_where.concat(where.from(1))
elsif join == old_where.first && !is_conjunction?(where.first)
old_where << where
elsif join == where.first && is_conjunction?(old_where.first)
old_where.tap { |w| w[-1] = ([join] << w.last).concat(where.from(1)) }
elsif join == where.first && !is_conjunction?(old_where.first)
where.insert(1,old_where)
elsif join == "and" && old_where.first == "or" && !is_conjunction?(where.first) && !is_conjunction?(old_where.last.first)
old_where.tap { |w| w[-1] = [join] << w.last << where }
elsif join == "and" && old_where.first == "or" && !is_conjunction?(where.first) && is_conjunction?(old_where.last.first)
old_where.tap { |w| w[-1] << where }
else
[join] << old_where << where
end
else
where
end
self.dup.tap do |r|
r.set_option(:where, new_where)
r.set_option(:join, "and")
end
end
|