Class: Lotus::Model::Adapters::Memory::Query
- Inherits:
-
Object
- Object
- Lotus::Model::Adapters::Memory::Query
- Extended by:
- Forwardable
- Includes:
- Enumerable
- Defined in:
- lib/lotus/model/adapters/memory/query.rb
Overview
Query the in-memory database with a powerful API.
All the methods are chainable, it allows advanced composition of conditions.
This works as a lazy filtering mechanism: the records are fetched from the database only when needed.
It implements Ruby’s Enumerable and borrows some methods from Array. Expect a query to act like them.
Instance Attribute Summary collapse
- #conditions ⇒ Object readonly private
- #modifiers ⇒ Object readonly private
Instance Method Summary collapse
-
#all ⇒ Array
Resolves the query by fetching records from the database and translating them into entities.
-
#average(column) ⇒ Numeric
(also: #avg)
Returns the average of the values for the given column.
-
#count ⇒ Fixnum
Returns a count of the records for the current conditions.
-
#desc(*columns) ⇒ Object
Specify the descending order of the records, sorted by the given columns.
-
#exclude(condition) ⇒ Object
(also: #not)
Logical negation of a #where condition.
-
#exist? ⇒ TrueClass, FalseClass
Checks if at least one record exists for the current conditions.
-
#initialize(dataset, collection, &blk) ⇒ Query
constructor
private
Initialize a query.
-
#interval(column) ⇒ Numeric
Returns the difference between the MAX and MIN for the given column.
-
#limit(number) ⇒ Object
Limit the number of records to return.
-
#max(column) ⇒ Object
Returns the maximum value for the given column.
-
#min(column) ⇒ Object
Returns the minimum value for the given column.
-
#negate! ⇒ Object
This method is defined in order to make the interface of
Memory::Queryidentical toSql::Query, but this feature is NOT implemented. -
#offset(number) ⇒ Object
Simulate an
OFFSETclause, without the need of specify a limit. -
#or(condition = nil, &blk) ⇒ Object
Adds a condition that behaves like SQL
OR. -
#order(*columns) ⇒ Object
(also: #asc)
Specify the ascending order of the records, sorted by the given columns.
-
#range(column) ⇒ Range
Returns a range of values between the MAX and the MIN for the given column.
-
#select(*columns) ⇒ Object
Select only the specified columns.
-
#sum(column) ⇒ Numeric
Returns the sum of the values for the given column.
-
#where(condition) ⇒ Object
(also: #and)
Adds a condition that behaves like SQL
WHERE.
Constructor Details
#initialize(dataset, collection, &blk) ⇒ Query
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Initialize a query
55 56 57 58 59 60 61 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 55 def initialize(dataset, collection, &blk) @dataset = dataset @collection = collection @conditions = [] @modifiers = [] instance_eval(&blk) if block_given? end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args, &blk) ⇒ Object (protected)
444 445 446 447 448 449 450 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 444 def method_missing(m, *args, &blk) if @context.respond_to?(m) apply @context.public_send(m, *args, &blk) else super end end |
Instance Attribute Details
#conditions ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
38 39 40 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 38 def conditions @conditions end |
#modifiers ⇒ Object (readonly)
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
44 45 46 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 44 def modifiers @modifiers end |
Instance Method Details
#all ⇒ Array
Resolves the query by fetching records from the database and translating them into entities.
69 70 71 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 69 def all @collection.deserialize(run) end |
#average(column) ⇒ Numeric Also known as: avg
Returns the average of the values for the given column.
328 329 330 331 332 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 328 def average(column) if s = sum(column) s / _all_with_present_column(column).count.to_f end end |
#count ⇒ Fixnum
Returns a count of the records for the current conditions.
426 427 428 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 426 def count run.count end |
#desc(*columns) ⇒ Object
Specify the descending order of the records, sorted by the given columns.
252 253 254 255 256 257 258 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 252 def desc(*columns) Lotus::Utils::Kernel.Array(columns).each do |column| modifiers.push(Proc.new{ sort_by!{|r| r.fetch(column)}.reverse! }) end self end |
#exclude(condition) ⇒ Object Also known as: not
Logical negation of a #where condition.
It accepts a Hash with only one pair. The key must be the name of the column expressed as a Symbol. The value is the one used by the internal filtering logic.
168 169 170 171 172 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 168 def exclude(condition) column, value = (condition) conditions.push([:where, Proc.new{ reject {|r| r.fetch(column) == value} }]) self end |
#exist? ⇒ TrueClass, FalseClass
Checks if at least one record exists for the current conditions.
413 414 415 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 413 def exist? !count.zero? end |
#interval(column) ⇒ Numeric
Returns the difference between the MAX and MIN for the given column.
380 381 382 383 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 380 def interval(column) max(column) - min(column) rescue NoMethodError end |
#limit(number) ⇒ Object
Limit the number of records to return.
271 272 273 274 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 271 def limit(number) modifiers.push(Proc.new{ replace(flatten.first(number)) }) self end |
#max(column) ⇒ Object
Returns the maximum value for the given column.
347 348 349 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 347 def max(column) _all_with_present_column(column).max end |
#min(column) ⇒ Object
Returns the minimum value for the given column.
362 363 364 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 362 def min(column) _all_with_present_column(column).min end |
#negate! ⇒ Object
This method is defined in order to make the interface of Memory::Query identical to Sql::Query, but this feature is NOT implemented
439 440 441 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 439 def negate! raise NotImplementedError end |
#offset(number) ⇒ Object
Simulate an OFFSET clause, without the need of specify a limit.
287 288 289 290 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 287 def offset(number) modifiers.unshift(Proc.new{ replace(flatten.drop(number)) }) self end |
#or(condition = nil, &blk) ⇒ Object
Adds a condition that behaves like SQL OR.
It accepts a Hash with only one pair. The key must be the name of the column expressed as a Symbol. The value is the one used by the SQL query
This condition will be ignored if not used with WHERE.
134 135 136 137 138 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 134 def or(condition=nil, &blk) column, value = (condition) conditions.push([:or, Proc.new{ find_all{|r| r.fetch(column) == value} }]) self end |
#order(*columns) ⇒ Object Also known as: asc
Specify the ascending order of the records, sorted by the given columns.
220 221 222 223 224 225 226 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 220 def order(*columns) Lotus::Utils::Kernel.Array(columns).each do |column| modifiers.push(Proc.new{ sort_by!{|r| r.fetch(column)} }) end self end |
#range(column) ⇒ Range
Returns a range of values between the MAX and the MIN for the given column.
400 401 402 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 400 def range(column) min(column)..max(column) end |
#select(*columns) ⇒ Object
Select only the specified columns.
By default a query selects all the mapped columns.
193 194 195 196 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 193 def select(*columns) columns = Lotus::Utils::Kernel.Array(columns) modifiers.push(Proc.new{ flatten!; each {|r| r.delete_if {|k,_| !columns.include?(k)} } }) end |
#sum(column) ⇒ Numeric
Returns the sum of the values for the given column.
303 304 305 306 307 308 309 310 311 312 313 314 315 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 303 def sum(column) result = all if result.any? result.inject(0.0) do |acc, record| if value = record.public_send(column) acc += value end acc end end end |
#where(condition) ⇒ Object Also known as: and
Adds a condition that behaves like SQL WHERE.
It accepts a Hash with only one pair. The key must be the name of the column expressed as a Symbol. The value is the one used by the internal filtering logic.
101 102 103 104 105 |
# File 'lib/lotus/model/adapters/memory/query.rb', line 101 def where(condition) column, value = (condition) conditions.push([:where, Proc.new{ find_all{|r| r.fetch(column) == value} }]) self end |