Database-Join
view release on metacpan or search on metacpan
lib/Database/Join.pm view on Meta::CPAN
return $self->{_schema_cache} if $self->{_schema_cache};
# Hash slice assignment (@merged{keys} = values) is O(M) per database;
# the previous (%merged = (%merged, %s)) pattern was O(NÃM) per iteration,
# totalling O(N²ÃM) over all databases for the same result.
my %merged;
for my $i (0 .. $#{ $self->{_dbs} }) {
my $s = $self->{_dbs}[$i]->schema() // {};
my $local_jc = $self->{_join_map}{$i};
if ($local_jc && $local_jc ne $self->{_join_col}) {
for my $col (keys %{$s}) {
$merged{$col} = $s->{$col} unless $col eq $local_jc;
}
} else {
@merged{keys %{$s}} = values %{$s};
}
}
delete @merged{keys %{ $self->{_removed_cols} }}
if %{ $self->{_removed_cols} };
$self->{_schema_cache} = \%merged;
return $self->{_schema_cache};
}
=head2 updated
=head3 SYNOPSIS
my $ts = $join->updated();
=head3 DESCRIPTION
Returns the Unix timestamp of the most recent modification across all
component databases. This is the maximum of all individual C<updated()>
return values.
Use this to implement simple cache-invalidation logic: if C<updated()>
has advanced since your last snapshot, re-query.
=head3 API SPECIFICATION
=head4 Input
None.
=head4 Output
Unix timestamp (positive integer).
=head3 EXAMPLE
my $last_modified = $join->updated();
if ($last_modified > $my_cache_timestamp) {
$my_cache = $join->selectall_arrayref();
$my_cache_timestamp = $last_modified;
}
=cut
sub updated {
my ($self) = @_;
return max(map { $_->updated() } @{ $self->{_dbs} });
}
=head2 set_logger
=head3 SYNOPSIS
$join->set_logger($log);
=head3 DESCRIPTION
Attaches a new logger object to the join and propagates it to every component
database. The logger is used for diagnostic output by all component databases.
=head3 API SPECIFICATION
=head4 Input
$log Positional: a logger object (required).
Must support whatever interface Database::Abstraction expects.
=head4 Output
Returns C<$self> for method chaining.
=head3 EXAMPLE
# Log::Any is used here as an example; any object that implements
# debug() and info() (or whichever methods your component databases
# call internally) works equally well.
use Log::Any qw($log);
my $join = Database::Join->new(databases => [$db1, $db2], join_column => 'entry');
$join->set_logger($log);
# $log is now used by $join and by $db1 and $db2
=cut
sub set_logger {
my ($self, $logger) = @_;
croak 'Usage: set_logger($logger)' unless defined $logger;
$self->{_logger} = $logger;
$_->set_logger($logger) for @{ $self->{_dbs} };
return $self;
}
=head2 add_database
=head3 SYNOPSIS
# Positional: database object as first argument
$join->add_database($db);
# Named: equivalent to the above
$join->add_database(database => $db);
( run in 1.933 second using v1.01-cache-2.11-cpan-6736b670a1e )