Class: DataMapper::Adapters::Sql::Commands::LoadCommand
- Defined in:
- lib/data_mapper/adapters/sql/commands/load_command.rb
Defined Under Namespace
Classes: ConditionsError, Loader
Instance Attribute Summary collapse
-
#conditions ⇒ Object
readonly
Access the Conditions instance.
-
#database_context ⇒ Object
readonly
Returns the value of attribute database_context.
-
#options ⇒ Object
readonly
Returns the value of attribute options.
Class Method Summary collapse
Instance Method Summary collapse
- #call ⇒ Object
-
#conditions_empty? ⇒ Boolean
Are any conditions present?.
-
#expression_to_sql(clause, value, collector) ⇒ Object
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.
-
#initialize(adapter, database_context, primary_class, options = {}) ⇒ LoadCommand
constructor
A new instance of LoadCommand.
-
#inspect ⇒ Object
Display an overview of load options at a glance.
-
#limit ⇒ Object
Determine if there is a limitation on the number of instances returned in the results.
- #load(reader) ⇒ Object
-
#offset ⇒ Object
Used in conjunction with #limit to page through a set of results.
-
#qualify_columns? ⇒ Boolean
If more than one table is involved in the query, the column definitions should be qualified by the table name.
-
#reload? ⇒ Boolean
If
true
then force the command to reload any objects already existing in the IdentityMap when executing. -
#to_parameterized_sql ⇒ Object
Generate a select statement based on the initialization arguments.
Constructor Details
#initialize(adapter, database_context, primary_class, options = {}) ⇒ LoadCommand
Returns a new instance of LoadCommand.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 123 def initialize(adapter, database_context, primary_class, = {}) @adapter, @database_context, @primary_class = adapter, database_context, primary_class # BEGIN: Partion out the options hash into general options, # and conditions. = @adapter.class::FIND_OPTIONS conditions_hash = {} @options = {} .each do |key,value| if .include?(key) && key != :conditions @options[key] = value else conditions_hash[key] = value end end # END @order = @options[:order] @limit = @options[:limit] @offset = @options[:offset] @reload = @options[:reload] @instance_id = conditions_hash[:id] @conditions = parse_conditions(conditions_hash) @loaders = Hash.new { |h,k| h[k] = Loader.new(self, k) } end |
Instance Attribute Details
#conditions ⇒ Object (readonly)
Access the Conditions instance
164 165 166 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 164 def conditions @conditions end |
#database_context ⇒ Object (readonly)
Returns the value of attribute database_context.
121 122 123 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 121 def database_context @database_context end |
#options ⇒ Object (readonly)
Returns the value of attribute options.
121 122 123 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 121 def @options end |
Class Method Details
.qualify_columns? ⇒ Boolean
313 314 315 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 313 def self.qualify_columns? @qualify_columns end |
Instance Method Details
#call ⇒ Object
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 188 def call # Check to see if the query is for a specific id and return if found # # NOTE: If the :id option is an Array: # We could search for loaded instance ids and reject from # the Array for already loaded instances, but working under the # assumption that we'll probably have to issue a query to find # at-least some of the instances we're looking for, it's faster to # just skip that and go straight for the query. unless reload? || @instance_id.blank? || @instance_id.is_a?(Array) # If the id is for only a single record, attempt to find it. if instance = @database_context.identity_map.get(@primary_class, @instance_id) return [instance] end end results = [] # Execute the statement and load the objects. @adapter.connection do |db| sql, *parameters = to_parameterized_sql command = db.create_command(sql) command.execute_reader(*parameters) do |reader| if @options.has_key?(:intercept_load) load(reader, &@options[:intercept_load]) else load(reader) end end end results += @loaders[@primary_class].loaded_set return results end |
#conditions_empty? ⇒ Boolean
Are any conditions present?
247 248 249 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 247 def conditions_empty? @conditions.empty? end |
#expression_to_sql(clause, value, collector) ⇒ Object
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']
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 335 def expression_to_sql(clause, value, collector) qualify_columns = qualify_columns? case clause when Symbol::Operator then operator = case clause.type when :gt then '>' when :gte then '>=' when :lt then '<' when :lte then '<=' when :not then inequality_operator(value) when :eql then equality_operator(value) when :like then equality_operator(value, 'LIKE') when :in then equality_operator(value) else raise ArgumentError.new('Operator type not supported') end collector << ["#{primary_class_table[clause].to_sql(qualify_columns)} #{operator} ?", value] when Symbol then collector << ["#{primary_class_table[clause].to_sql(qualify_columns)} #{equality_operator(value)} ?", value] when String then collector << [clause, *value] when Mappings::Column then collector << ["#{clause.to_sql(qualify_columns)} #{equality_operator(value)} ?", value] else raise "CAN HAS CRASH? #{clause.inspect}" end rescue => e raise ConditionsError.new(clause, value, e) end |
#inspect ⇒ Object
Display an overview of load options at a glance.
151 152 153 154 155 156 157 158 159 160 161 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 151 def inspect <<-EOS.compress_lines % (object_id * 2) #<#{self.class.name}:0x%x @database=#{@adapter.name} @reload=#{@reload.inspect} @order=#{@order.inspect} @limit=#{@limit.inspect} @offset=#{@offset.inspect} @options=#{@options.inspect}> EOS end |
#limit ⇒ Object
Determine if there is a limitation on the number of instances returned in the results. If nil
, no limit is set. Can be used in conjunction with #offset for paging through a set of results.
178 179 180 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 178 def limit @limit end |
#load(reader) ⇒ Object
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 225 def load(reader) # The following blocks are identical aside from the yield. # It's written this way to avoid a conditional within each # iterator, and to take advantage of the performance of # yield vs. Proc#call. if block_given? reader.each do @loaders.each_pair do |klass,loader| row = reader.current_row yield(loader.materialize(row), @columns, row) end end else reader.each do @loaders.each_pair do |klass,loader| loader.materialize(reader.current_row) end end end end |
#offset ⇒ Object
Used in conjunction with #limit to page through a set of results.
184 185 186 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 184 def offset @offset end |
#qualify_columns? ⇒ Boolean
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.
311 312 313 314 315 316 317 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 311 def qualify_columns? @qualify_columns = !(included_associations.empty? && shallow_included_associations.empty?) def self.qualify_columns? @qualify_columns end @qualify_columns end |
#reload? ⇒ Boolean
If true
then force the command to reload any objects already existing in the IdentityMap when executing.
170 171 172 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 170 def reload? @reload end |
#to_parameterized_sql ⇒ Object
Generate a select statement based on the initialization arguments.
253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 |
# File 'lib/data_mapper/adapters/sql/commands/load_command.rb', line 253 def to_parameterized_sql parameters = [] sql = 'SELECT ' << columns_for_select.join(', ') sql << ' FROM ' << from_table_name included_associations.each do |association| sql << ' ' << association.to_sql end shallow_included_associations.each do |association| sql << ' ' << association.to_shallow_sql end unless conditions_empty? sql << ' WHERE (' last_index = @conditions.size current_index = 0 @conditions.each do |condition| case condition when String then sql << condition when Array then sql << condition.shift parameters += condition else raise "Unable to parse condition: #{condition.inspect}" if condition end if (current_index += 1) == last_index sql << ')' else sql << ') AND (' end end end # unless conditions_empty? unless @order.nil? sql << ' ORDER BY ' << @order.to_s end unless @limit.nil? sql << ' LIMIT ' << @limit.to_s end unless @offset.nil? sql << ' OFFSET ' << @offset.to_s end parameters.unshift(sql) end |