DBIx-QuickORM
view release on metacpan or search on metacpan
lib/DBIx/QuickORM.pm view on Meta::CPAN
$params{+DBS} //= {};
$params{+SCHEMAS} //= {};
$params{+SERVERS} //= {};
return bless(\%params, $class);
}
sub quick {
my $class = shift;
my %params = @_;
my $creds = delete $params{credentials};
my $connect = delete $params{connect};
my $types = delete $params{auto_types} // [];
my $dialect = delete $params{dialect};
my $autorow = delete $params{autorow}; # 0 = off (default), 1 = generated namespace, or a class-name prefix
my $row_manager = delete $params{row_manager} // 'DBIx::QuickORM::RowManager::Cached';
my $no_volatile = delete $params{no_volatile}; # 1 = every table, or an arrayref of table names
croak "Unknown parameter(s) to quick(): " . join(', ', sort keys %params) if keys %params;
croak "'no_volatile' must be a true scalar (every table) or an arrayref of table names"
if defined($no_volatile) && ref($no_volatile) && ref($no_volatile) ne 'ARRAY';
croak "quick() requires exactly one of 'credentials' or 'connect'"
unless (($creds ? 1 : 0) + ($connect ? 1 : 0)) == 1;
croak "'credentials' must be a hashref" if $creds && ref($creds) ne 'HASH';
croak "'connect' must be a coderef" if $connect && ref($connect) ne 'CODE';
croak "'auto_types' must be an arrayref" if ref($types) ne 'ARRAY';
my ($dialect_class, $db_name) = $class->_quick_detect($dialect, $creds, $connect);
require DBIx::QuickORM::DB;
my %db_params = (dialect => $dialect_class, db_name => $db_name);
if ($creds) {
if (my @bad = grep { $_ !~ /^(?:dsn|user|pass|attrs|dbd)$/ } keys %$creds) {
croak "Unknown credentials key(s): " . join(', ' => sort @bad) . " (valid: dsn, user, pass, attrs, dbd)";
}
$db_params{dsn} = $creds->{dsn} if defined $creds->{dsn};
$db_params{user} = $creds->{user} if defined $creds->{user};
$db_params{pass} = $creds->{pass} if defined $creds->{pass};
$db_params{attributes} = $creds->{attrs} if defined $creds->{attrs};
$db_params{dbi_driver} = $creds->{dbd} if defined $creds->{dbd};
}
else {
$db_params{connect} = $connect;
}
my $db = DBIx::QuickORM::DB->new(%db_params);
my (%type_map, %affinities);
for my $type (@$types) {
my $type_class = load_class($type, 'DBIx::QuickORM::Type') or croak "Could not load type '$type': $@";
$type_class->qorm_register_type(\%type_map, \%affinities);
}
my %autofill_args = (types => \%type_map, affinities => \%affinities, hooks => {}, skip => {});
$autofill_args{no_volatile} = $no_volatile if defined $no_volatile;
if ($autorow) {
my $base = "$autorow" eq '1' ? $class->_generate_autorow_base : $autorow;
$autofill_args{hooks}{post_table} = [$class->_autorow_hook($base, undef, (caller)[1])];
}
my $autofill = DBIx::QuickORM::Schema::Autofill->new(%autofill_args);
load_class($row_manager) or croak "Could not load row_manager '$row_manager': $@"
unless ref $row_manager;
require DBIx::QuickORM::ORM;
my $orm = DBIx::QuickORM::ORM->new(db => $db, autofill => $autofill, row_manager => $row_manager);
return $orm->connection;
}
sub _generate_autorow_base {
my $class = shift;
state $counter = 0;
$counter++;
return "DBIx::QuickORM::Row::Auto${counter}";
}
sub _autorow_hook {
my $class = shift;
my ($base, $name_to_class, $caller_file) = @_;
$name_to_class //= sub {
my $name = shift;
my @parts = split /_/, $name;
return join '' => map { ucfirst(lc($_)) } @parts;
};
local $@;
my $parent = load_class($base);
unless ($parent) {
# Only fall back to the stock Row class when the base genuinely does not
# exist on disk; a base that exists but fails to compile must surface
# its error rather than silently losing the user's methods.
my $err = $@;
die $err unless $err =~ m/Can't locate .+ in \@INC/;
$parent = load_class('DBIx::QuickORM::Row') or die $@;
}
return sub {
my %params = @_;
my $autofill = $params{autofill};
my $table = $params{table};
my $postfix = $name_to_class->($table->{name});
my $package = "$base\::$postfix";
local $@;
unless (load_class($package)) {
# A missing per-table row class is expected (autofill generates it);
# a compile error in an existing one must not be swallowed.
my $err = $@;
die $err unless $err =~ m/Can't locate .+ in \@INC/;
}
my $isa = do { no strict 'refs'; \@{"$package\::ISA"} };
push @$isa => $parent unless @$isa;
my $file = $package;
( run in 2.261 seconds using v1.01-cache-2.11-cpan-ad19def0cd9 )