def find_by_sql(*args)
sql = nil
query = nil
bind_values = []
properties = nil
do_reload = false
repository_name = default_repository_name
args.each do |arg|
if arg.is_a?(String)
sql = arg
elsif arg.is_a?(Array)
sql = arg.first
bind_values = arg[1..-1]
elsif arg.is_a?(DataMapper::Query)
query = arg
elsif arg.is_a?(Hash)
repository_name = arg.delete(:repository) if arg.include?(:repository)
properties = Array(arg.delete(:properties)) if arg.include?(:properties)
do_reload = arg.delete(:reload) if arg.include?(:reload)
raise "unknown options to #find_by_sql: #{arg.inspect}" unless arg.empty?
end
end
repository = repository(repository_name)
raise "#find_by_sql only available for Repositories served by a DataObjectsAdapter" unless repository.adapter.is_a?(DataMapper::Adapters::DataObjectsAdapter)
if query
sql = repository.adapter.send(:read_statement, query)
bind_values = query.bind_values
end
raise "#find_by_sql requires a query of some kind to work" unless sql
properties ||= self.properties(repository.name)
Collection.new(Query.new(repository, self)) do |collection|
repository.adapter.send(:with_connection) do |connection|
command = connection.create_command(sql)
begin
reader = command.execute_reader(*bind_values)
while(reader.next!)
collection.load(reader.values)
end
ensure
reader.close if reader
end
end
end
end