DBIO
view release on metacpan or search on metacpan
lib/DBIO/Storage.pm view on Meta::CPAN
} catch {
$self->throw_exception($_);
}
}
else {
require DBIO::Storage::Statistics;
DBIO::Storage::Statistics->new
}
};
}
sub debugcb {
my $self = shift;
if ($self->debugobj->can('callback')) {
return $self->debugobj->callback(@_);
}
}
sub deploy { die "Virtual method!" }
sub connect_info { die "Virtual method!" }
# --- DBIO-private connect attributes (karr #66) --------------------------
# Single authoritative source for the attribute names a caller may pass in
# connect_info that are DBIO-private and must NEVER reach DBI->connect. Both
# connect-info paths consume these lists -- the sync normalizer
# (DBIO::Storage::DBI::_normalize_connect_info) and the async strip
# (DBIO::Storage::Async::connect_info) -- so the two paths can never drift on
# what counts as DBIO-private. They live on this shared base (the common
# ancestor of both DBI and Async storage) rather than on DBIO::Storage::DBI, so
# the async base can reach them without a new Async->DBI dependency direction.
# Storage-config options: routed to the storage, kept out of DBI->connect.
# (cursor_class is a storage option too, but carries its own component_class
# accessor, so it is appended at the split sites rather than listed here.)
sub _dbio_storage_option_names {
qw/
on_connect_call on_disconnect_call on_connect_do on_disconnect_do
disable_sth_caching unsafe auto_savepoint
/;
}
# SQL-maker options: routed to the sql_maker, kept out of DBI->connect.
sub _dbio_sql_maker_option_names {
qw/ quote_char name_sep quote_names /;
}
sub select { die "Virtual method!" }
sub insert { die "Virtual method!" }
sub update { die "Virtual method!" }
sub delete { die "Virtual method!" }
sub select_single { die "Virtual method!" }
# Live async backend (a DBIO::Storage::Async) or undef when none configured.
# Overridden in DBIO::Storage::DBI to do real discovery. Base = no backend.
sub _async_storage { undef }
# The connect-time async mode name (ADR 0030), or undef for a sync instance.
# Overridden by the _async_mode accessor on DBIO::Storage::DBI; the base stub
# keeps non-DBI storages on the sync path (their *_async croak).
sub _async_mode { undef }
# Shared dispatch for the six *_async methods (ADR 0030). Three outcomes:
# - an embedded backend is live -> route ${op}_async to it (real async)
# - the instance is in 'immediate' -> run $op synchronously, wrap the result
# mode (no backend, mode chosen) in an immediately-resolved future
# - the instance is sync -> croak loudly: *_async was called but no
# (no async mode chosen) async mode was chosen at connect time
# _async_storage croaks on its own for a chosen-but-unavailable mode.
sub _run_async {
my ($self, $op, @args) = @_;
if (my $async = $self->_async_storage) {
my $method = "${op}_async";
return $async->$method(@args);
}
$self->throw_exception(
"not an async connection -- connect with { async => ... } to use ${op}_async"
) unless defined $self->_async_mode;
my $fc = $self->future_class;
my @r = eval { $self->$op(@args) };
return $@ ? $fc->fail($@) : $fc->done(@r);
}
sub select_async { shift->_run_async('select', @_) }
sub select_single_async { shift->_run_async('select_single', @_) }
sub insert_async { shift->_run_async('insert', @_) }
sub update_async { shift->_run_async('update', @_) }
sub delete_async { shift->_run_async('delete', @_) }
sub txn_do_async { shift->_run_async('txn_do', @_) }
sub future_class {
my $self = shift;
if (ref $self and my $async = $self->_async_storage) {
return $async->future_class;
}
require DBIO::Future::Immediate;
'DBIO::Future::Immediate';
}
sub columns_info_for { die "Virtual method!" }
# Type registry: maps type names to behavior descriptors, keyed by class so
# subclasses can add or override entries. Use type_info() for MRO-aware lookup.
my %_type_registry;
sub register_type {
my ($class, $type_name, $info) = @_;
$_type_registry{$class}{$type_name} = $info;
}
sub type_info {
my ($class, $type_name) = @_;
for my $pkg (@{ mro::get_linear_isa($class) }) {
return $_type_registry{$pkg}{$type_name}
if exists $_type_registry{$pkg}
&& exists $_type_registry{$pkg}{$type_name};
}
return undef;
}
sub all_type_names {
my ($class) = @_;
my %seen;
for my $pkg (@{ mro::get_linear_isa($class) }) {
$seen{$_}++ for keys %{ $_type_registry{$pkg} || {} };
}
return keys %seen;
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
( run in 1.177 second using v1.01-cache-2.11-cpan-600a1bdf6e4 )