Class: Flounder::Query::Base
- Inherits:
-
Object
- Object
- Flounder::Query::Base
- Includes:
- Helpers::Entity
- Defined in:
- lib/flounder/query/base.rb
Instance Attribute Summary collapse
-
#bind_values ⇒ Object
readonly
Bound values in this query.
-
#domain ⇒ Object
readonly
Domain that this query was issued from.
-
#engine ⇒ Object
readonly
Database engine that links Arel to Postgres.
-
#entity ⇒ Object
readonly
Entity this query operates on.
-
#manager ⇒ Object
readonly
Arel *Manager that accumulates this query.
Instance Method Summary collapse
-
#column_name_to_entity(name) ⇒ Object
Implement this if your column names in the query allow inferring the entity and the column name.
-
#initialize(domain, manager_klass, entity) ⇒ Base
constructor
A new instance of Base.
-
#kick(connection = nil) ⇒ Object
Returns all rows of the query result as an array.
-
#measure ⇒ Object
Measures the block given to it and logs time spent in the block to the domain.
-
#parse_conditions(*conditions, &apply) ⇒ Object
Parses a conditions array like it is found with #where and #having and calls the block for each condition bit.
-
#to_sql ⇒ Object
Kickers.
-
#where(*conditions) ⇒ Object
Restricts the result returned to only those records that match the conditions.
- #with(name, query) ⇒ Object
Methods included from Helpers::Entity
#convert_to_entity, #entity_like?
Constructor Details
#initialize(domain, manager_klass, entity) ⇒ Base
Returns a new instance of Base.
10 11 12 13 14 15 16 17 |
# File 'lib/flounder/query/base.rb', line 10 def initialize domain, manager_klass, entity @domain = domain @engine = Flounder::Engine.new(domain.connection_pool) @manager = manager_klass.new(engine) @entity = entity @bind_values = [] end |
Instance Attribute Details
#bind_values ⇒ Object (readonly)
Bound values in this query.
24 25 26 |
# File 'lib/flounder/query/base.rb', line 24 def bind_values @bind_values end |
#domain ⇒ Object (readonly)
Domain that this query was issued from.
20 21 22 |
# File 'lib/flounder/query/base.rb', line 20 def domain @domain end |
#engine ⇒ Object (readonly)
Database engine that links Arel to Postgres.
22 23 24 |
# File 'lib/flounder/query/base.rb', line 22 def engine @engine end |
#entity ⇒ Object (readonly)
Entity this query operates on.
28 29 30 |
# File 'lib/flounder/query/base.rb', line 28 def entity @entity end |
#manager ⇒ Object (readonly)
Arel *Manager that accumulates this query.
26 27 28 |
# File 'lib/flounder/query/base.rb', line 26 def manager @manager end |
Instance Method Details
#column_name_to_entity(name) ⇒ Object
Implement this if your column names in the query allow inferring the entity and the column name. Return them as a tuple <entity, name>.
81 82 |
# File 'lib/flounder/query/base.rb', line 81 def column_name_to_entity name end |
#kick(connection = nil) ⇒ Object
Returns all rows of the query result as an array. Individual rows are mapped to objects using the row mapper.
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/flounder/query/base.rb', line 59 def kick connection=nil all = nil connection ||= engine measure do result = connection.exec(self.to_sql, bind_values) descriptor = ::Flounder::Result::Descriptor.new( connection, entity, result, &method(:column_name_to_entity)) all = Array.new(result.ntuples, nil) result.ntuples.times do |row_idx| all[row_idx] = descriptor.row(row_idx) end end all end |
#measure ⇒ Object
Measures the block given to it and logs time spent in the block to the domain.
87 88 89 90 91 92 |
# File 'lib/flounder/query/base.rb', line 87 def measure measure = Benchmark.measure { yield } domain.log_bm measure end |
#parse_conditions(*conditions, &apply) ⇒ Object
Parses a conditions array like it is found with #where and #having and calls the block for each condition bit. Returns self.
Example:
parse_conditions(conditions) { |bit| manager.where(bit) }
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/flounder/query/base.rb', line 100 def parse_conditions *conditions, &apply conditions = conditions.dup resolve_entity = entity # is the first argument an entity? if yes, interpret field names relative # to that entity. if conditions.size > 1 && entity_like?(conditions.first) resolve_entity = convert_to_entity(conditions.shift) end # is this a hash? extract the first element if conditions.size == 1 && conditions.first.kind_of?(Hash) conditions = conditions.first conditions.each do |k, v| apply.call( transform_tuple(resolve_entity, k, v)) end return self end # or maybe this is a Flounder::Expression::Expr? if conditions.size == 1 && conditions.first.kind_of?(Flounder::Expression::Expr) condition = conditions.first apply.call( Arel::Nodes::SqlLiteral.new(condition.to_sql)) return self end # maybe conditions is of the second form? conditions.each do |cond_str, *values| apply.call( Arel::Nodes::SqlLiteral.new( rewrite_bind_variables(cond_str, bind_values.size, values.size))) bind_values.concat values end return self end |
#to_sql ⇒ Object
Kickers
49 50 51 52 53 54 |
# File 'lib/flounder/query/base.rb', line 49 def to_sql prepare_kick manager.to_sql.tap { |sql| domain.log_sql(sql) } end |
#where(*conditions) ⇒ Object
Restricts the result returned to only those records that match the conditions.
Example:
query.where(id: 1) # ... WHERE id = 1 ...
query.where(:id => :user_id) # ... WHERE id = user_id
query.where(:id.noteq => 1) # ... WHERE id != 1
39 40 41 |
# File 'lib/flounder/query/base.rb', line 39 def where *conditions parse_conditions(*conditions) { |bit| manager.where(bit) } end |
#with(name, query) ⇒ Object
43 44 45 46 |
# File 'lib/flounder/query/base.rb', line 43 def with name, query # Nodes::TableAlias.new(relation, name) manager.with(query.manager) end |