Class: QueryBuilder::Query
- Inherits:
-
Object
- Object
- QueryBuilder::Query
- Defined in:
- lib/query_builder/query.rb
Instance Attribute Summary collapse
-
#attributes_alias ⇒ Object
Returns the value of attribute attributes_alias.
-
#context ⇒ Object
Returns the value of attribute context.
-
#distinct ⇒ Object
Returns the value of attribute distinct.
-
#error ⇒ Object
Returns the value of attribute error.
-
#group ⇒ Object
Returns the value of attribute group.
-
#having ⇒ Object
Returns the value of attribute having.
-
#key_value_tables ⇒ Object
Returns the value of attribute key_value_tables.
-
#limit ⇒ Object
Returns the value of attribute limit.
-
#main_class ⇒ Object
Return the class of resulting objects (different from default_class if the value has been changed by the query building process).
-
#offset ⇒ Object
Returns the value of attribute offset.
-
#order ⇒ Object
Returns the value of attribute order.
-
#page_size ⇒ Object
Returns the value of attribute page_size.
-
#pagination_key ⇒ Object
Returns the value of attribute pagination_key.
-
#processor_class ⇒ Object
Returns the value of attribute processor_class.
-
#select ⇒ Object
Returns the value of attribute select.
-
#table_alias ⇒ Object
Returns the value of attribute table_alias.
-
#tables ⇒ Object
Returns the value of attribute tables.
-
#where ⇒ Object
Returns the value of attribute where.
Class Method Summary collapse
Instance Method Summary collapse
- #add_filter(filter) ⇒ Object
-
#add_key_value_table(use_name, index_table, key, &block) ⇒ Object
Add a table to ‘import’ a key/value based field.
- #add_select(field, fname) ⇒ Object
-
#add_table(use_name, table_name = nil, avoid_alias = true) ⇒ Object
‘avoid_alias’ is used when parsing the last element so that it takes the real table name (nodes, not no1).
-
#default_class ⇒ Object
Return the default class of resulting objects (usually the base class).
-
#dup ⇒ Object
Duplicate query, avoiding sharing some arrays and hash.
- #filter ⇒ Object
-
#initialize(processor_class) ⇒ Query
constructor
A new instance of Query.
- #main_table ⇒ Object
- #master_class(after_class = ActiveRecord::Base) ⇒ Object
-
#needs_join_table(table_name1, type, table_name2, clause, join_name = nil) ⇒ Object
Use this method to add a join to another table (added only once for each join name).
- #quote_column_name(name) ⇒ Object
- #rebuild_attributes_hash! ⇒ Object
-
#rebuild_tables! ⇒ Object
Used after setting @tables from custom query.
-
#select_keys ⇒ Object
Return all explicit selected keys (currently selection is only available in custom queries) For example, sql such as “SELECT form.*, MAX(form.date) AS last_date” would provice ‘last_date’ key.
-
#sql(bindings, type = :find) ⇒ Object
Convert the query object into an SQL query.
- #table(table_name = main_table, index = 0) ⇒ Object
-
#to_s(type = :find) ⇒ Object
Convert query object to a string.
Constructor Details
#initialize(processor_class) ⇒ Query
Returns a new instance of Query.
15 16 17 18 19 20 21 22 23 24 |
# File 'lib/query_builder/query.rb', line 15 def initialize(processor_class) @processor_class = processor_class @tables = [] @table_alias = {} @join_tables = {} @needed_join_tables = {} @attributes_alias = {} @key_value_tables = {} @where = [] end |
Instance Attribute Details
#attributes_alias ⇒ Object
Returns the value of attribute attributes_alias.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def attributes_alias @attributes_alias end |
#context ⇒ Object
Returns the value of attribute context.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def context @context end |
#distinct ⇒ Object
Returns the value of attribute distinct.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def distinct @distinct end |
#error ⇒ Object
Returns the value of attribute error.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def error @error end |
#group ⇒ Object
Returns the value of attribute group.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def group @group end |
#having ⇒ Object
Returns the value of attribute having.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def having @having end |
#key_value_tables ⇒ Object
Returns the value of attribute key_value_tables.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def key_value_tables @key_value_tables end |
#limit ⇒ Object
Returns the value of attribute limit.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def limit @limit end |
#main_class ⇒ Object
Return the class of resulting objects (different from default_class if the value has been changed by the query building process).
33 34 35 |
# File 'lib/query_builder/query.rb', line 33 def main_class @main_class end |
#offset ⇒ Object
Returns the value of attribute offset.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def offset @offset end |
#order ⇒ Object
Returns the value of attribute order.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def order @order end |
#page_size ⇒ Object
Returns the value of attribute page_size.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def page_size @page_size end |
#pagination_key ⇒ Object
Returns the value of attribute pagination_key.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def pagination_key @pagination_key end |
#processor_class ⇒ Object
Returns the value of attribute processor_class.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def processor_class @processor_class end |
#select ⇒ Object
Returns the value of attribute select.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def select @select end |
#table_alias ⇒ Object
Returns the value of attribute table_alias.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def table_alias @table_alias end |
#tables ⇒ Object
Returns the value of attribute tables.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def tables @tables end |
#where ⇒ Object
Returns the value of attribute where.
5 6 7 |
# File 'lib/query_builder/query.rb', line 5 def where @where end |
Class Method Details
.adapter ⇒ Object
10 11 12 |
# File 'lib/query_builder/query.rb', line 10 def adapter @adapter ||= ActiveRecord::Base.connection.class.name.split('::').last[/(.+)Adapter/,1].downcase end |
Instance Method Details
#add_filter(filter) ⇒ Object
55 56 57 |
# File 'lib/query_builder/query.rb', line 55 def add_filter(filter) @where << filter end |
#add_key_value_table(use_name, index_table, key, &block) ⇒ Object
Add a table to ‘import’ a key/value based field. This method ensures that a given field is only included once for each context.
118 119 120 121 122 123 124 125 126 127 128 129 130 131 |
# File 'lib/query_builder/query.rb', line 118 def add_key_value_table(use_name, index_table, key, &block) key_tables = (@key_value_tables[table] ||= {}) key_table = (key_tables[use_name] ||= {}) if alias_table = key_table[key] # done, the index_table has been used for the given key in the current context else # insert the new table add_table(use_name, index_table, false) alias_table = key_table[key] = table(use_name) # Let caller configure the filter (join). block.call(alias_table) end alias_table end |
#add_select(field, fname) ⇒ Object
133 134 135 136 137 |
# File 'lib/query_builder/query.rb', line 133 def add_select(field, fname) @select ||= ["#{main_table}.*"] @select << "#{field} AS #{quote_column_name(fname)}" @attributes_alias[fname] = field end |
#add_table(use_name, table_name = nil, avoid_alias = true) ⇒ Object
‘avoid_alias’ is used when parsing the last element so that it takes the real table name (nodes, not no1). We need this because we can use ‘OR’ between parts and we thus need the same table reference.
111 112 113 114 |
# File 'lib/query_builder/query.rb', line 111 def add_table(use_name, table_name = nil, avoid_alias = true) alias_name = get_alias(use_name, table_name, avoid_alias) add_alias_to_tables(table_name || use_name, alias_name) end |
#default_class ⇒ Object
Return the default class of resulting objects (usually the base class).
48 49 50 51 52 53 |
# File 'lib/query_builder/query.rb', line 48 def default_class @default_class ||= begin klass = @processor_class.main_class QueryBuilder.resolve_const(klass) end end |
#dup ⇒ Object
Duplicate query, avoiding sharing some arrays and hash
165 166 167 168 169 170 171 |
# File 'lib/query_builder/query.rb', line 165 def dup other = super %w{tables table_alias where tables key_value_tables}.each do |k| other.send("#{k}=", other.send(k).dup) end other end |
#filter ⇒ Object
206 207 208 |
# File 'lib/query_builder/query.rb', line 206 def filter @where.reverse.join(' AND ') end |
#main_table ⇒ Object
26 27 28 29 |
# File 'lib/query_builder/query.rb', line 26 def main_table # @main_table is only used in custom queries @main_table || processor_class.main_table end |
#master_class(after_class = ActiveRecord::Base) ⇒ Object
37 38 39 40 41 42 43 44 45 |
# File 'lib/query_builder/query.rb', line 37 def master_class(after_class = ActiveRecord::Base) klass = main_class klass = klass.first if klass.kind_of?(Array) begin up = klass.superclass return klass if up == after_class end while klass = up return main_class end |
#needs_join_table(table_name1, type, table_name2, clause, join_name = nil) ⇒ Object
Use this method to add a join to another table (added only once for each join name). nodes JOIN idx_nodes_string AS id1 ON … FIXME: can we remove this ? It seems buggy (JOIN in or clauses)
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/query_builder/query.rb', line 146 def needs_join_table(table_name1, type, table_name2, clause, join_name = nil) join_name ||= "#{table_name1}=#{type}=#{table_name2}" @needed_join_tables[join_name] ||= {} @needed_join_tables[join_name][table] ||= begin # define join for this part ('table' = unique for each part) # don't add to list of tables, just get unique alias name second_table = get_alias(table_name2) # create join first_table = table(table_name1) @join_tables[first_table] ||= [] @join_tables[first_table] << "#{type} JOIN #{second_table} ON #{clause.gsub('TABLE1',first_table).gsub('TABLE2',second_table)}" second_table end end |
#quote_column_name(name) ⇒ Object
210 211 212 |
# File 'lib/query_builder/query.rb', line 210 def quote_column_name(name) connection.quote_column_name(name) end |
#rebuild_attributes_hash! ⇒ Object
187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
# File 'lib/query_builder/query.rb', line 187 def rebuild_attributes_hash! @attributes_alias = {} (@select || []).each do |field| if field =~ %r{\A(.*)\s+AS\s+(.+)\Z}i key, value = $2, $1 if key =~ /('|"|`)(.*)\1/ # TODO: is this clean enough unquoting ? key = $2 end @attributes_alias[key] = value elsif field =~ %r{^(\w+\.|)([^\*]+)$} @attributes_alias[$2] = field end end # Force rebuild @select_keys = nil end |
#rebuild_tables! ⇒ Object
Used after setting @tables from custom query.
174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/query_builder/query.rb', line 174 def rebuild_tables! @table_alias = {} @tables.each do |t| if t =~ /\A(.+)\s+AS\s+(.+)\Z/ base, use_name = $1, $2 else base = use_name = t end @table_alias[base] ||= [] @table_alias[base] << use_name end end |
#select_keys ⇒ Object
Return all explicit selected keys (currently selection is only available in custom queries) For example, sql such as “SELECT form.*, MAX(form.date) AS last_date” would provice ‘last_date’ key.
61 62 63 |
# File 'lib/query_builder/query.rb', line 61 def select_keys @select_keys ||= @attributes_alias.keys.compact end |
#sql(bindings, type = :find) ⇒ Object
Convert the query object into an SQL query.
Parameters
- bindings<Binding>
-
Binding context in which to evaluate bind clauses (query arguments).
- type<Symbol>
-
Type of SQL query (:find or :count)
Returns
- NilClass
-
If the query is not valid and “ignore_warnings” was not set to true during initialize.
- String
-
An SQL query, ready for execution (no more bind variables).
Examples
query.sql(binding)
> “SELECT objects.* FROM objects WHERE objects.project_id = 12489”
query.sql(bindings, :count)
> “SELECT COUNT(*) FROM objects WHERE objects.project_id = 12489”
104 105 106 107 |
# File 'lib/query_builder/query.rb', line 104 def sql(bindings, type = :find) statement, bind_values = build_statement(type) statement.gsub('?') { eval_bound_value(bind_values.shift, connection, bindings) } end |
#table(table_name = main_table, index = 0) ⇒ Object
139 140 141 |
# File 'lib/query_builder/query.rb', line 139 def table(table_name = main_table, index = 0) @table_alias[table_name] ? @table_alias[table_name][index - 1] : nil end |
#to_s(type = :find) ⇒ Object
Convert query object to a string. This string should then be evaluated.
Parameters
- type<Symbol>
-
Type of query to build (:find or :count).
Returns
- NilClass
-
If the query is not valid and “ignore_warnings” was not set to true during initialize.
- String
-
A string representing the query with its bind parameters.
Examples
query.to_s
> “[%Qobjects.* FROM objects WHERE objects.project_id = ?, project_id]”
DummyQuery.new(“nodes in site”).to_s
> “%Qobjects.* FROM objects”
query.to_s(:count)
> “[%QCOUNT(*) FROM objects WHERE objects.project_id = ?, project_id]”
83 84 85 86 |
# File 'lib/query_builder/query.rb', line 83 def to_s(type = :find) statement, bind_values = build_statement(type) bind_values.empty? ? "%Q{#{statement}}" : "[#{[["%Q{#{statement}}"] + bind_values].join(', ')}]" end |