Class: Lotus::Model::Adapters::Sql::Query
- Inherits:
-
Object
- Object
- Lotus::Model::Adapters::Sql::Query
- Extended by:
- Forwardable
- Includes:
- Enumerable
- Defined in:
- lib/lotus/model/adapters/sql/query.rb
Overview
Query the database with a powerful API.
All the methods are chainable, it allows advanced composition of SQL 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.
Constant Summary collapse
- OPERATORS_MAPPING =
This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.
Define negations for operators.
{ where: :exclude, exclude: :where }.freeze
Instance Attribute Summary collapse
- #conditions ⇒ 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.
-
#exclude(condition = nil, &blk) ⇒ Object
(also: #not)
Logical negation of a WHERE condition.
-
#exist? ⇒ TrueClass, FalseClass
Checks if at least one record exists for the current conditions.
-
#group(*columns) ⇒ Object
Group by the specified columns.
-
#initialize(collection, context = nil, &blk) ⇒ Lotus::Model::Adapters::Sql::Query
constructor
Initialize a query.
-
#interval(column) ⇒ Numeric
Returns the difference between the MAX and MIN for the given column.
-
#join(collection, options = {}) ⇒ Object
(also: #inner_join)
Specify an ‘INNER JOIN` clause.
-
#left_join(collection, options = {}) ⇒ Object
(also: #left_outer_join)
Specify a ‘LEFT JOIN` clause.
-
#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
Negates the current where/exclude conditions with the logical opposite operator.
-
#offset(number) ⇒ Object
Specify an ‘OFFSET` clause.
-
#or(condition = nil, &blk) ⇒ Object
Adds a SQL ‘OR` condition.
-
#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.
-
#reverse_order(*columns) ⇒ Object
(also: #desc)
Specify the descending order of the records, sorted by the given columns.
-
#scoped ⇒ Lotus::Model::Adapters::Sql::Collection
(also: #run)
Apply all the conditions and returns a filtered collection.
-
#select(*columns) ⇒ Object
Select only the specified columns.
-
#sum(column) ⇒ Numeric
Returns the sum of the values for the given column.
-
#where(condition = nil, &blk) ⇒ Object
(also: #and)
Adds a SQL ‘WHERE` condition.
Constructor Details
#initialize(collection, context = nil, &blk) ⇒ Lotus::Model::Adapters::Sql::Query
Initialize a query
61 62 63 64 65 66 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 61 def initialize(collection, context = nil, &blk) @collection, @context = collection, context @conditions = [] 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)
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.
Handles missing methods for query combinations
670 671 672 673 674 675 676 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 670 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.
50 51 52 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 50 def conditions @conditions end |
Instance Method Details
#all ⇒ Array
Resolves the query by fetching records from the database and translating them into entities.
hitting the database for fetching records
77 78 79 80 81 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 77 def all run.to_a rescue Sequel::DatabaseError => e raise Lotus::Model::InvalidQueryError.new(e.) end |
#average(column) ⇒ Numeric Also known as: avg
Returns the average of the values for the given column.
458 459 460 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 458 def average(column) run.avg(column) end |
#count ⇒ Fixnum
Returns a count of the records for the current conditions.
573 574 575 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 573 def count run.count end |
#exclude(condition = nil, &blk) ⇒ 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 SQL query
216 217 218 219 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 216 def exclude(condition = nil, &blk) _push_to_conditions(:exclude, condition || blk) self end |
#exist? ⇒ TrueClass, FalseClass
Checks if at least one record exists for the current conditions.
560 561 562 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 560 def exist? !count.zero? end |
#group(*columns) ⇒ Object
Group by the specified columns.
423 424 425 426 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 423 def group(*columns) conditions.push([:group, *columns]) self end |
#interval(column) ⇒ Numeric
Returns the difference between the MAX and MIN for the given column.
526 527 528 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 526 def interval(column) run.interval(column) end |
#join(collection, options = {}) ⇒ Object Also known as: inner_join
Specify an ‘INNER JOIN` clause.
635 636 637 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 635 def join(collection, = {}) _join(collection, .merge(join: :inner)) end |
#left_join(collection, options = {}) ⇒ Object Also known as: left_outer_join
Specify a ‘LEFT JOIN` clause.
657 658 659 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 657 def left_join(collection, = {}) _join(collection, .merge(join: :left)) end |
#limit(number) ⇒ Object
Limit the number of records to return.
This operation is performed at the database level with ‘LIMIT`.
264 265 266 267 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 264 def limit(number) conditions.push([:limit, number]) self end |
#max(column) ⇒ Object
Returns the maximum value for the given column.
483 484 485 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 483 def max(column) run.max(column) end |
#min(column) ⇒ Object
Returns the minimum value for the given column.
506 507 508 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 506 def min(column) run.min(column) end |
#negate! ⇒ Object
Negates the current where/exclude conditions with the logical opposite operator.
All the other conditions will be ignored.
593 594 595 596 597 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 593 def negate! conditions.map! do |(operator, condition)| [OPERATORS_MAPPING.fetch(operator) { operator }, condition] end end |
#offset(number) ⇒ Object
Specify an ‘OFFSET` clause.
Due to SQL syntax restriction, offset MUST be used with ‘#limit`.
286 287 288 289 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 286 def offset(number) conditions.push([:offset, number]) self end |
#or(condition = nil, &blk) ⇒ Object
Adds a SQL ‘OR` 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 SQL query
This condition will be ignored if not used with WHERE.
169 170 171 172 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 169 def or(condition = nil, &blk) _push_to_conditions(:or, condition || blk) self end |
#order(*columns) ⇒ Object Also known as: asc
Specify the ascending order of the records, sorted by the given columns.
319 320 321 322 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 319 def order(*columns) conditions.push([_order_operator, *columns]) self end |
#range(column) ⇒ Range
Returns a range of values between the MAX and the MIN for the given column.
547 548 549 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 547 def range(column) run.range(column) end |
#reverse_order(*columns) ⇒ Object Also known as: desc
Specify the descending order of the records, sorted by the given columns.
377 378 379 380 381 382 383 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 377 def reverse_order(*columns) Array(columns).each do |column| conditions.push([_order_operator, Sequel.desc(column)]) end self end |
#scoped ⇒ Lotus::Model::Adapters::Sql::Collection Also known as: run
Apply all the conditions and returns a filtered collection.
This operation is idempotent, and the returned result didn’t fetched the records yet.
607 608 609 610 611 612 613 614 615 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 607 def scoped scope = @collection conditions.each do |(method,*args)| scope = scope.public_send(method, *args) end scope end |
#select(*columns) ⇒ Object
Select only the specified columns.
By default a query selects all the columns of a table (‘SELECT *`).
244 245 246 247 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 244 def select(*columns) conditions.push([:select, *columns]) self end |
#sum(column) ⇒ Numeric
Returns the sum of the values for the given column.
441 442 443 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 441 def sum(column) run.sum(column) end |
#where(condition = nil, &blk) ⇒ Object Also known as: and
Adds a SQL ‘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 SQL query
125 126 127 128 |
# File 'lib/lotus/model/adapters/sql/query.rb', line 125 def where(condition = nil, &blk) _push_to_conditions(:where, condition || blk) self end |