Class: BazaModels::Query
Defined Under Namespace
Modules: Pagination
Classes: Inspector, Not, SqlGenerator
Instance Attribute Summary collapse
Instance Method Summary
collapse
Methods included from Pagination
#current_page, #out_of_bounds?, #page, #paginated?, #per, #total_entries, #total_pages
Constructor Details
#initialize(args) ⇒ Query
Returns a new instance of Query.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
# File 'lib/baza_models/query.rb', line 10
def initialize(args)
@args = args
@model = @args[:model]
@db = @model.db
raise "No database?" unless @db
@selects = args[:selects] || []
@wheres = args[:wheres] || []
@includes = args[:includes] || []
@joins = args[:joins] || []
@groups = args[:groups] || []
@offset = args[:offset]
@orders = args[:orders] || []
@page = args[:page]
@per = args[:per]
@previous_model = args[:previous_model]
@limit = args[:limit]
@joins_tracker = {}
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method_name, *args, &blk) ⇒ Object
480
481
482
483
484
485
486
487
488
|
# File 'lib/baza_models/query.rb', line 480
def method_missing(method_name, *args, &blk)
return super unless @model
scopes = @model.instance_variable_get(:@scopes)
return super if !scopes || !scopes.key?(method_name)
block = scopes.fetch(method_name).fetch(:blk)
instance_exec(*args, &block)
end
|
Instance Attribute Details
#previous_model ⇒ Object
Returns the value of attribute previous_model.
8
9
10
|
# File 'lib/baza_models/query.rb', line 8
def previous_model
@previous_model
end
|
#relation ⇒ Object
Returns the value of attribute relation.
8
9
10
|
# File 'lib/baza_models/query.rb', line 8
def relation
@relation
end
|
Instance Method Details
#<<(model) ⇒ Object
355
356
357
358
359
360
361
362
363
364
365
366
|
# File 'lib/baza_models/query.rb', line 355
def <<(model)
raise "No previous model set" unless @previous_model
raise "No relation" unless @relation
if model.persisted?
model.update_attributes!(@relation.fetch(:foreign_key) => @previous_model.id)
else
autoloaded_cache_or_create << model
end
self
end
|
#<=(_other) ⇒ Object
373
374
375
|
# File 'lib/baza_models/query.rb', line 373
def <=(_other)
false
end
|
#accessible_by(ability, action = :index) ⇒ Object
369
370
371
|
# File 'lib/baza_models/query.rb', line 369
def accessible_by(ability, action = :index)
ability.model_adapter(self, action).database_records
end
|
#all ⇒ Object
32
33
34
|
# File 'lib/baza_models/query.rb', line 32
def all
self
end
|
#any? ⇒ Boolean
36
37
38
39
40
41
42
|
# File 'lib/baza_models/query.rb', line 36
def any?
if @db.query(clone.select(:id).limit(1).to_sql).fetch
true
else
false
end
end
|
#average(column_name) ⇒ Object
44
45
46
47
|
# File 'lib/baza_models/query.rb', line 44
def average(column_name)
query = select("AVG(#{table_sql}.#{column_sql(column_name)}) AS average")
@db.query(query.to_sql).fetch.fetch(:average).to_f
end
|
#count ⇒ Object
71
72
73
74
75
76
77
78
79
80
81
82
|
# File 'lib/baza_models/query.rb', line 71
def count
if @previous_model && @previous_model.new_record?
autoloaded_cache_or_create.length
else
query = clone(selects: [])
.select("COUNT(*) AS count")
.limit(nil)
.offset(nil)
@db.query(query.to_sql).fetch.fetch(:count)
end
end
|
#destroy_all ⇒ Object
343
344
345
|
# File 'lib/baza_models/query.rb', line 343
def destroy_all
each(&:destroy!)
end
|
#each ⇒ Object
303
304
305
306
307
|
# File 'lib/baza_models/query.rb', line 303
def each
to_enum.each do |model|
yield model
end
end
|
#empty? ⇒ Boolean
49
50
51
|
# File 'lib/baza_models/query.rb', line 49
def empty?
!any?
end
|
#find(id) ⇒ Object
128
129
130
131
132
133
134
135
136
137
138
|
# File 'lib/baza_models/query.rb', line 128
def find(id)
model = clone.where(id: id).limit(1).to_enum.first
if model
model.__send__(:fire_callbacks, :after_find)
else
raise BazaModels::Errors::RecordNotFound
end
model
end
|
#find_by(args) ⇒ Object
140
141
142
|
# File 'lib/baza_models/query.rb', line 140
def find_by(args)
clone.where(args).limit(1).to_enum.first
end
|
#find_each ⇒ Object
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
|
# File 'lib/baza_models/query.rb', line 309
def find_each
query = clone
query.instance_variable_set(:@order, [])
query.instance_variable_set(:@limit, nil)
query = query.order(:id)
offset = 0
loop do
query = query.offset(offset, 1000)
offset += 1000
count = 0
query.each do |model|
yield model
count += 1
end
break if count == 0
end
end
|
#find_first(args) ⇒ Object
331
332
333
|
# File 'lib/baza_models/query.rb', line 331
def find_first(args)
clone.where(args).first
end
|
#first ⇒ Object
144
145
146
147
148
149
150
151
152
153
|
# File 'lib/baza_models/query.rb', line 144
def first
return autoloaded_cache.first if should_use_autoload?
query = clone.limit(1)
orders = query.instance_variable_get(:@orders)
query = query.order(:id) if orders.empty?
query.to_enum.first
end
|
#group(name) ⇒ Object
247
248
249
250
251
252
253
254
255
|
# File 'lib/baza_models/query.rb', line 247
def group(name)
if name.is_a?(Symbol)
clone(groups: @groups + ["`#{@model.table_name}`.`#{name}`"])
elsif name.is_a?(String)
clone(groups: @groups + [name])
else
raise "Didn't know how to group by that argument: #{name}"
end
end
|
#ids ⇒ Object
53
54
55
|
# File 'lib/baza_models/query.rb', line 53
def ids
pluck(:id)
end
|
#includes(*names) ⇒ Object
184
185
186
|
# File 'lib/baza_models/query.rb', line 184
def includes(*names)
clone(includes: @includes + names)
end
|
#inspect ⇒ Object
351
352
353
|
# File 'lib/baza_models/query.rb', line 351
def inspect
to_s
end
|
#joins(*arguments) ⇒ Object
235
236
237
238
239
240
241
242
243
244
245
|
# File 'lib/baza_models/query.rb', line 235
def joins(*arguments)
BazaModels::Query::Inspector.new(
query: self,
model: @model,
argument: arguments,
joins: @joins,
joins_tracker: @joins_tracker
).execute
self
end
|
#last ⇒ Object
155
156
157
158
159
160
161
162
163
164
|
# File 'lib/baza_models/query.rb', line 155
def last
return autoloaded_cache.last if should_use_autoload?
query = clone.limit(1)
orders = query.instance_variable_get(:@orders)
query = query.order(:id) if orders.empty?
query.reverse_order.to_enum.first
end
|
#length ⇒ Object
84
85
86
87
88
89
90
|
# File 'lib/baza_models/query.rb', line 84
def length
if @previous_model && !any_wheres_other_than_relation? && @previous_model.autoloads[@relation.fetch(:relation_name)]
@previous_model.autoloads[@relation.fetch(:relation_name)].length
else
count
end
end
|
#limit(limit) ⇒ Object
180
181
182
|
# File 'lib/baza_models/query.rb', line 180
def limit(limit)
clone(limit: limit)
end
|
#map(&blk) ⇒ Object
272
273
274
|
# File 'lib/baza_models/query.rb', line 272
def map(&blk)
to_enum.map(&blk)
end
|
#maximum(column_name) ⇒ Object
57
58
59
60
|
# File 'lib/baza_models/query.rb', line 57
def maximum(column_name)
query = select("MAX(#{table_sql}.#{column_sql(column_name)}) AS maximum")
@db.query(query.to_sql).fetch.fetch(:maximum).to_f
end
|
#minimum(column_name) ⇒ Object
62
63
64
65
|
# File 'lib/baza_models/query.rb', line 62
def minimum(column_name)
query = select("MIN(#{table_sql}.#{column_sql(column_name)}) AS minimum")
@db.query(query.to_sql).fetch.fetch(:minimum).to_f
end
|
#new(attributes) ⇒ Object
117
118
119
120
121
122
123
124
125
126
|
# File 'lib/baza_models/query.rb', line 117
def new(attributes)
raise "No previous model" unless @previous_model
raise "No relation" unless @relation
new_sub_model = @model.new(@relation.fetch(:foreign_key) => @previous_model.id)
new_sub_model.assign_attributes(attributes)
autoloaded_cache_or_create << new_sub_model
new_sub_model
end
|
#none? ⇒ Boolean
67
68
69
|
# File 'lib/baza_models/query.rb', line 67
def none?
!any?
end
|
#offset(offset) ⇒ Object
176
177
178
|
# File 'lib/baza_models/query.rb', line 176
def offset(offset)
clone(offset: offset)
end
|
#order(name) ⇒ Object
257
258
259
260
261
262
263
264
265
|
# File 'lib/baza_models/query.rb', line 257
def order(name)
if name.is_a?(Symbol)
clone(orders: @orders + ["`#{@model.table_name}`.`#{name}`"])
elsif name.is_a?(String)
clone(orders: @orders + [name])
else
raise "Didn't know how to order by that argument: #{name}"
end
end
|
#pluck(*column_names) ⇒ Object
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
# File 'lib/baza_models/query.rb', line 97
def pluck(*column_names)
results = @db.query(select(column_names).to_sql).to_a
results.map do |result|
if column_names.length == 1
result.fetch(column_names.first)
else
new_result = []
column_names.each do |column_name|
new_result << result.fetch(column_name)
end
new_result
end
end
end
|
#ransack(params, args = {}) ⇒ Object
382
383
384
|
# File 'lib/baza_models/query.rb', line 382
def ransack(params, args = {})
BazaModels::Ransacker.new(class: @model, params: params, query: self, args: args)
end
|
#reverse_order ⇒ Object
267
268
269
270
|
# File 'lib/baza_models/query.rb', line 267
def reverse_order
@reverse_order = true
self
end
|
#sanitize_sql(value) ⇒ Object
377
378
379
380
|
# File 'lib/baza_models/query.rb', line 377
def sanitize_sql(value)
return value if value.is_a?(Array) || value.is_a?(Integer) || value.is_a?(Integer)
"'#{@db.esc(value)}'"
end
|
#select(select = nil, &blk) ⇒ Object
166
167
168
169
170
171
172
173
174
|
# File 'lib/baza_models/query.rb', line 166
def select(select = nil, &blk)
if !select && blk
to_enum.select(&blk)
elsif select.is_a?(Symbol)
clone(selects: @selects + ["`#{@model.table_name}`.`#{select}`"])
else
clone(selects: @selects + [select])
end
end
|
#size ⇒ Object
92
93
94
95
|
# File 'lib/baza_models/query.rb', line 92
def size
length
end
|
#sum(column_name) ⇒ Object
112
113
114
115
|
# File 'lib/baza_models/query.rb', line 112
def sum(column_name)
query = select("SUM(#{table_sql}.#{column_sql(column_name)}) AS sum")
@db.query(query.to_sql).fetch.fetch(:sum).to_f
end
|
#to_a ⇒ Object
335
336
337
|
# File 'lib/baza_models/query.rb', line 335
def to_a
to_enum.to_a
end
|
#to_enum ⇒ Object
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
|
# File 'lib/baza_models/query.rb', line 276
def to_enum
return autoloaded_cache if should_use_autoload?
array_enum = ArrayEnumerator.new do |yielder|
@db.query(to_sql).each do |data|
yielder << @model.new(data, init: true)
end
end
if @includes.empty?
return array_enum
else
array = array_enum.to_a
if @includes.any? && array.any?
autoloader = BazaModels::Autoloader.new(
models: array,
autoloads: @includes,
db: @db
)
autoloader.autoload
end
return array
end
end
|
#to_s ⇒ Object
347
348
349
|
# File 'lib/baza_models/query.rb', line 347
def to_s
"#<BazaModels::Query class=#{@model.name} wheres=#{@wheres}>"
end
|
#where(*args) ⇒ Object
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
|
# File 'lib/baza_models/query.rb', line 188
def where(*args)
first_arg = args.first
new_wheres = @wheres.dup
if first_arg.is_a?(String)
new_where = "(#{args.shift})"
args.each do |arg|
new_where.sub!("?", @db.quote_value(arg))
end
new_wheres << new_where
elsif first_arg.is_a?(Array)
str = first_arg.shift
first_arg.each do |arg|
if arg.is_a?(Symbol)
arg = "`#{@model.table_name}`.`#{@db.escape_column(arg)}`"
elsif arg.is_a?(FalseClass)
arg = "0"
elsif arg.is_a?(TrueClass)
arg = "1"
else
arg = @db.quote_value(arg)
end
str.sub!("?", arg)
end
new_wheres << "(#{str})"
elsif first_arg == nil
return Not.new(query: self)
else
first_arg.each do |key, value|
if value.is_a?(Hash)
value.each do |hash_key, hash_value|
new_wheres << "`#{key}`.`#{key_convert(hash_key, hash_value)}` #{value_with_mode(value_convert(hash_value))}"
end
else
new_wheres << "`#{@model.table_name}`.`#{key_convert(key, value)}` #{value_with_mode(value_convert(value))}"
end
end
end
clone(wheres: new_wheres)
end
|