# rubocop:disable Naming/UncommunicativeMethodParamName
require_relative "association_loader"
require "simple/sql/reflection"
class ::Simple::SQL::Result::Records < ::Simple::SQL::Result
Reflection = ::Simple::SQL::Reflection
def initialize(records, target_type:, pg_source_oid:) # :nodoc:
# expect! records.first => Hash unless records.empty?
super(records)
@hash_records = records
@target_type = target_type
@pg_source_oid = pg_source_oid
@associations = []
materialize
end
# -- preload associations -------------------------------------------------
AssociationLoader = ::Simple::SQL::Result::AssociationLoader
# Preloads an association.
#
# This can now be used as follows:
#
# scope = SQL::Scope.new("SELECT * FROM users")
# results = SQL.all scope, into: :struct
# results.preload(:organization)
#
# The preload method uses foreign key definitions in the database to figure out
# which table to load from.
#
# This method is only available if into: was set in the call to SQL.all.
# It raises an error otherwise.
#
# Parameters:
#
# - association: the name of the association.
# - as: the target name of the association.
# - order_by: if set describes ordering; see Scope#order_by.
# - limit: if set describes limits; see Scope#order_by.
def preload(association, as: nil, order_by: nil, limit: nil)
expect! association => Symbol
expect! as => [nil, Symbol]
# resolve oid into table and schema name.
#
# [TODO] is this still correct?
schema, host_table = Reflection.lookup_pg_class @pg_source_oid
AssociationLoader.preload @hash_records, association,
host_table: host_table, schema: schema, as: as,
order_by: order_by, limit: limit
@associations << association
materialize
end
private
# convert the records into the target type.
RowConverter = ::Simple::SQL::Helpers::RowConverter
def materialize
records = @hash_records
if @target_type != Hash
schema, host_table = Reflection.lookup_pg_class(@pg_source_oid)
records = RowConverter.convert_row(records, associations: @associations,
into: @target_type,
fq_table_name: "#{schema}.#{host_table}")
end
replace(records)
end
end