Class | DataMapper::Adapters::Sql::Commands::LoadCommand |
In: |
lib/data_mapper/adapters/sql/commands/load_command.rb
lib/data_mapper/adapters/sql/commands/load_command.rb |
Parent: | Object |
conditions | [R] | |
conditions | [R] | |
database_context | [R] | |
database_context | [R] | |
options | [R] | |
options | [R] |
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 131 131: def initialize(adapter, database_context, primary_class, options = {}) 132: @adapter, @database_context, @primary_class = adapter, database_context, primary_class 133: 134: # BEGIN: Partion out the options hash into general options, 135: # and conditions. 136: standard_find_options = @adapter.class::FIND_OPTIONS 137: conditions_hash = {} 138: @options = {} 139: 140: options.each do |key,value| 141: if standard_find_options.include?(key) && key != :conditions 142: @options[key] = value 143: else 144: conditions_hash[key] = value 145: end 146: end 147: # END 148: 149: @order = @options[:order] 150: @limit = @options[:limit] 151: @offset = @options[:offset] 152: @reload = @options[:reload] 153: @instance_id = conditions_hash[:id] 154: @conditions = parse_conditions(conditions_hash) 155: @loaders = Hash.new { |h,k| h[k] = Loader.new(self, k) } 156: end
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 131 131: def initialize(adapter, database_context, primary_class, options = {}) 132: @adapter, @database_context, @primary_class = adapter, database_context, primary_class 133: 134: # BEGIN: Partion out the options hash into general options, 135: # and conditions. 136: standard_find_options = @adapter.class::FIND_OPTIONS 137: conditions_hash = {} 138: @options = {} 139: 140: options.each do |key,value| 141: if standard_find_options.include?(key) && key != :conditions 142: @options[key] = value 143: else 144: conditions_hash[key] = value 145: end 146: end 147: # END 148: 149: @order = @options[:order] 150: @limit = @options[:limit] 151: @offset = @options[:offset] 152: @reload = @options[:reload] 153: @instance_id = conditions_hash[:id] 154: @conditions = parse_conditions(conditions_hash) 155: @loaders = Hash.new { |h,k| h[k] = Loader.new(self, k) } 156: end
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 322 322: def self.qualify_columns? 323: @qualify_columns 324: end
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 322 322: def self.qualify_columns? 323: @qualify_columns 324: end
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 197 197: def call 198: 199: # Check to see if the query is for a specific id and return if found 200: # 201: # NOTE: If the :id option is an Array: 202: # We could search for loaded instance ids and reject from 203: # the Array for already loaded instances, but working under the 204: # assumption that we'll probably have to issue a query to find 205: # at-least some of the instances we're looking for, it's faster to 206: # just skip that and go straight for the query. 207: unless reload? || @instance_id.blank? || @instance_id.is_a?(Array) 208: # If the id is for only a single record, attempt to find it. 209: if instance = @database_context.identity_map.get(@primary_class, @instance_id) 210: return [instance] 211: end 212: end 213: 214: results = [] 215: 216: # Execute the statement and load the objects. 217: @adapter.connection do |db| 218: sql, *parameters = to_parameterized_sql 219: command = db.create_command(sql) 220: command.execute_reader(*parameters) do |reader| 221: if @options.has_key?(:intercept_load) 222: load(reader, &@options[:intercept_load]) 223: else 224: load(reader) 225: end 226: end 227: end 228: 229: results += @loaders[@primary_class].loaded_set 230: 231: return results 232: end
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 197 197: def call 198: 199: # Check to see if the query is for a specific id and return if found 200: # 201: # NOTE: If the :id option is an Array: 202: # We could search for loaded instance ids and reject from 203: # the Array for already loaded instances, but working under the 204: # assumption that we'll probably have to issue a query to find 205: # at-least some of the instances we're looking for, it's faster to 206: # just skip that and go straight for the query. 207: unless reload? || @instance_id.blank? || @instance_id.is_a?(Array) 208: # If the id is for only a single record, attempt to find it. 209: if instance = @database_context.identity_map.get(@primary_class, @instance_id) 210: return [instance] 211: end 212: end 213: 214: results = [] 215: 216: # Execute the statement and load the objects. 217: @adapter.connection do |db| 218: sql, *parameters = to_parameterized_sql 219: command = db.create_command(sql) 220: command.execute_reader(*parameters) do |reader| 221: if @options.has_key?(:intercept_load) 222: load(reader, &@options[:intercept_load]) 223: else 224: load(reader) 225: end 226: end 227: end 228: 229: results += @loaders[@primary_class].loaded_set 230: 231: return results 232: end
Access the Conditions instance
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 173 173: def conditions 174: @conditions 175: end
Access the Conditions instance
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 173 173: def conditions 174: @conditions 175: end
Are any conditions present?
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 256 256: def conditions_empty? 257: @conditions.empty? 258: end
Are any conditions present?
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 256 256: def conditions_empty? 257: @conditions.empty? 258: end
expression_to_sql takes a set of arguments, and turns them into a an Array of generated SQL, followed by optional Values to interpolate as SQL-Parameters.
Parameters: clause The name of the column as a Symbol, a raw-SQL String, a Mappings::Column instance, or a Symbol::Operator. value The Value for the condition. collector An Array representing all conditions that is appended to by expression_to_sql
Returns: Undefined Output. The work performed is added to the collector argument. Example:
conditions = [] expression_to_sql(:name, 'Bob', conditions) => +undefined return value+ conditions.inspect => ["name = ?", 'Bob']
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 344 344: def expression_to_sql(clause, value, collector) 345: qualify_columns = qualify_columns? 346: 347: case clause 348: when Symbol::Operator then 349: operator = case clause.type 350: when :gt then '>' 351: when :gte then '>=' 352: when :lt then '<' 353: when :lte then '<=' 354: when :not then inequality_operator(value) 355: when :eql then equality_operator(value) 356: when :like then equality_operator(value, 'LIKE') 357: when :in then equality_operator(value) 358: else raise ArgumentError.new('Operator type not supported') 359: end 360: collector << ["#{primary_class_table[clause].to_sql(qualify_columns)} #{operator} ?", value] 361: when Symbol then 362: collector << ["#{primary_class_table[clause].to_sql(qualify_columns)} #{equality_operator(value)} ?", value] 363: when String then 364: collector << [clause, *value] 365: when Mappings::Column then 366: collector << ["#{clause.to_sql(qualify_columns)} #{equality_operator(value)} ?", value] 367: else raise "CAN HAS CRASH? #{clause.inspect}" 368: end 369: rescue => e 370: if e.is_a?(ConditionsError) 371: raise e 372: else 373: raise ConditionsError.new(clause, value, e) 374: end 375: end
expression_to_sql takes a set of arguments, and turns them into a an Array of generated SQL, followed by optional Values to interpolate as SQL-Parameters.
Parameters: clause The name of the column as a Symbol, a raw-SQL String, a Mappings::Column instance, or a Symbol::Operator. value The Value for the condition. collector An Array representing all conditions that is appended to by expression_to_sql
Returns: Undefined Output. The work performed is added to the collector argument. Example:
conditions = [] expression_to_sql(:name, 'Bob', conditions) => +undefined return value+ conditions.inspect => ["name = ?", 'Bob']
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 344 344: def expression_to_sql(clause, value, collector) 345: qualify_columns = qualify_columns? 346: 347: case clause 348: when Symbol::Operator then 349: operator = case clause.type 350: when :gt then '>' 351: when :gte then '>=' 352: when :lt then '<' 353: when :lte then '<=' 354: when :not then inequality_operator(value) 355: when :eql then equality_operator(value) 356: when :like then equality_operator(value, 'LIKE') 357: when :in then equality_operator(value) 358: else raise ArgumentError.new('Operator type not supported') 359: end 360: collector << ["#{primary_class_table[clause].to_sql(qualify_columns)} #{operator} ?", value] 361: when Symbol then 362: collector << ["#{primary_class_table[clause].to_sql(qualify_columns)} #{equality_operator(value)} ?", value] 363: when String then 364: collector << [clause, *value] 365: when Mappings::Column then 366: collector << ["#{clause.to_sql(qualify_columns)} #{equality_operator(value)} ?", value] 367: else raise "CAN HAS CRASH? #{clause.inspect}" 368: end 369: rescue => e 370: if e.is_a?(ConditionsError) 371: raise e 372: else 373: raise ConditionsError.new(clause, value, e) 374: end 375: end
Display an overview of load options at a glance.
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 159 159: def inspect 160: "#<\#{self.class.name}:0x%x\n@database=\#{@adapter.name}\n@reload=\#{@reload.inspect}\n@order=\#{@order.inspect}\n@limit=\#{@limit.inspect}\n@offset=\#{@offset.inspect}\n@options=\#{@options.inspect}>\n".compress_lines % (object_id * 2) 161: end
Display an overview of load options at a glance.
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 159 159: def inspect 160: "#<\#{self.class.name}:0x%x\n@database=\#{@adapter.name}\n@reload=\#{@reload.inspect}\n@order=\#{@order.inspect}\n@limit=\#{@limit.inspect}\n@offset=\#{@offset.inspect}\n@options=\#{@options.inspect}>\n".compress_lines % (object_id * 2) 161: end
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 234 234: def load(reader) 235: # The following blocks are identical aside from the yield. 236: # It's written this way to avoid a conditional within each 237: # iterator, and to take advantage of the performance of 238: # yield vs. Proc#call. 239: if block_given? 240: reader.each do 241: @loaders.each_pair do |klass,loader| 242: row = reader.current_row 243: yield(loader.materialize(row), @columns, row) 244: end 245: end 246: else 247: reader.each do 248: @loaders.each_pair do |klass,loader| 249: loader.materialize(reader.current_row) 250: end 251: end 252: end 253: end
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 234 234: def load(reader) 235: # The following blocks are identical aside from the yield. 236: # It's written this way to avoid a conditional within each 237: # iterator, and to take advantage of the performance of 238: # yield vs. Proc#call. 239: if block_given? 240: reader.each do 241: @loaders.each_pair do |klass,loader| 242: row = reader.current_row 243: yield(loader.materialize(row), @columns, row) 244: end 245: end 246: else 247: reader.each do 248: @loaders.each_pair do |klass,loader| 249: loader.materialize(reader.current_row) 250: end 251: end 252: end 253: end
If more than one table is involved in the query, the column definitions should be qualified by the table name. ie: people.name This method determines wether that needs to happen or not. Note: After the first call, the calculations are avoided by overwriting this method with a simple getter.
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 320 320: def qualify_columns? 321: @qualify_columns = !(included_associations.empty? && shallow_included_associations.empty?) 322: def self.qualify_columns? 323: @qualify_columns 324: end 325: @qualify_columns 326: end
If more than one table is involved in the query, the column definitions should be qualified by the table name. ie: people.name This method determines wether that needs to happen or not. Note: After the first call, the calculations are avoided by overwriting this method with a simple getter.
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 320 320: def qualify_columns? 321: @qualify_columns = !(included_associations.empty? && shallow_included_associations.empty?) 322: def self.qualify_columns? 323: @qualify_columns 324: end 325: @qualify_columns 326: end
If true then force the command to reload any objects already existing in the IdentityMap when executing.
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 179 179: def reload? 180: @reload 181: end
If true then force the command to reload any objects already existing in the IdentityMap when executing.
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 179 179: def reload? 180: @reload 181: end
Generate a select statement based on the initialization arguments.
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 262 262: def to_parameterized_sql 263: parameters = [] 264: 265: sql = 'SELECT ' << columns_for_select.join(', ') 266: sql << ' FROM ' << from_table_name 267: 268: included_associations.each do |association| 269: sql << ' ' << association.to_sql 270: end 271: 272: shallow_included_associations.each do |association| 273: sql << ' ' << association.to_shallow_sql 274: end 275: 276: unless conditions_empty? 277: sql << ' WHERE (' 278: 279: last_index = @conditions.size 280: current_index = 0 281: 282: @conditions.each do |condition| 283: case condition 284: when String then sql << condition 285: when Array then 286: sql << condition.shift 287: parameters += condition 288: else 289: raise "Unable to parse condition: #{condition.inspect}" if condition 290: end 291: 292: if (current_index += 1) == last_index 293: sql << ')' 294: else 295: sql << ') AND (' 296: end 297: end 298: end # unless conditions_empty? 299: 300: unless @order.nil? 301: sql << ' ORDER BY ' << @order.to_s 302: end 303: 304: unless @limit.nil? 305: sql << ' LIMIT ' << @limit.to_s 306: end 307: 308: unless @offset.nil? 309: sql << ' OFFSET ' << @offset.to_s 310: end 311: 312: parameters.unshift(sql) 313: end
Generate a select statement based on the initialization arguments.
# File lib/data_mapper/adapters/sql/commands/load_command.rb, line 262 262: def to_parameterized_sql 263: parameters = [] 264: 265: sql = 'SELECT ' << columns_for_select.join(', ') 266: sql << ' FROM ' << from_table_name 267: 268: included_associations.each do |association| 269: sql << ' ' << association.to_sql 270: end 271: 272: shallow_included_associations.each do |association| 273: sql << ' ' << association.to_shallow_sql 274: end 275: 276: unless conditions_empty? 277: sql << ' WHERE (' 278: 279: last_index = @conditions.size 280: current_index = 0 281: 282: @conditions.each do |condition| 283: case condition 284: when String then sql << condition 285: when Array then 286: sql << condition.shift 287: parameters += condition 288: else 289: raise "Unable to parse condition: #{condition.inspect}" if condition 290: end 291: 292: if (current_index += 1) == last_index 293: sql << ')' 294: else 295: sql << ') AND (' 296: end 297: end 298: end # unless conditions_empty? 299: 300: unless @order.nil? 301: sql << ' ORDER BY ' << @order.to_s 302: end 303: 304: unless @limit.nil? 305: sql << ' LIMIT ' << @limit.to_s 306: end 307: 308: unless @offset.nil? 309: sql << ' OFFSET ' << @offset.to_s 310: end 311: 312: parameters.unshift(sql) 313: end