DBIx::...pector(3pm)
β¨ NAME β¨
DBIx::Introspector β literally just "Detect what database you are connected to" π
(the manual page is DBIx::...pector(3pm) if you're the kind of person who reads headers, which, bestie, you are now π«Ά)
π VERSION π
version 0.001005
πΈ SYNOPSIS πΈ
my $d = DBIx::Introspector->new(drivers => '2013-12.01');
# standard dialects
$d->decorate_driver_unconnected(Pg => concat_sql => '? || ?');
$d->decorate_driver_unconnected(SQLite => concat_sql => '? || ?');
# non-standard
$d->decorate_driver_unconnected(MSSQL => concat_sql => '? + ?');
$d->decorate_driver_unconnected(mysql => concat_sql => 'CONCAT( ?, ? )');
my $concat_sql = $d->get($dbh, $dsn, 'concat_sql');
π¦ DESCRIPTION π¦
okay so. DBIx::Introspector is a module that got factored out of the DBIx::Class database detection code. And the way that matters: most code that needs to figure out which database it's connected to just assumes there's a one-to-one mapping from database drivers to database engines. Cute theory. Wrong tho. π
Reality is rarely that simple, fr fr. For instance, DBD::ODBC is typically used to connect to SQL Server β but ODBC can be used to connect to PostgreSQL, MySQL, and Oracle. And like, even the other direction: while ODBC is the most common way to connect to SQL Server, it is not the only option, because DBD::ADO can also be used. The vibes are messy. π
DBIx::Introspector can correctly detect which database you are connected to, because it was factored out of a complex, working codebase β not vibes-based, bestie, battle-tested. On top of that it has been written to be very extensible. So if you needed to detect which version of your given database you are connected to? That would not be difficult. Go off. π
Furthermore β and this is the part I'm obsessed with β DBIx::Introspector does its best to try to detect information based on the dsn you give it if you have not yet connected, so you can possibly avoid connection or at least defer connection. Lazy in the good way. π§
π METHODS π
add_driver
$dbii->add_driver({
name => 'Pg',
parents => ['DBI'],
unconnected_options => {
concat_sql => '? || ?',
random_func => 'RANDOM()',
})
Takes a hashref defining a new driver .
replace_driver
$dbii->replace_driver({
name => 'Pg',
parents => ['DBI'],
unconnected_options => {
concat_sql => '? || ?',
random_func => 'RANDOM()',
})
Takes a hashref replacing an existing driver . It replaces the driver already defined with the same name. (Yes, same name. That's the whole point, bestie. Swap in, swap out. π)
decorate_driver_connected
$dbii->decorate_driver_connected('MSSQL', 'concat_sql', '? + ?')
Takes a driver name, a key and a value. That key value pair gets inserted into the driver's connected_options. π
decorate_driver_unconnected
$dbii->decorate_driver_unconnected('SQLite', 'concat_sql', '? || ?')
Takes a driver name, a key and a value. That key value pair gets inserted into the driver's unconnected_options. π
get
$dbii->get($dbh, $dsn, 'concat_sql')
Takes a dbh, a dsn, a key, and optionally a hashref of options.
The dbh can be a coderef returning a dbh. If you provide the dbh_fallback_connect option it will be used to connect the dbh if it is not already connected and then queried, if the dsn was insufficient. So it only connects when it literally has to. Iconic behavior.
So for example, one might do:
my $dbh;
$dbii->get(sub { $dbh }, $dsn, 'concat_sql', {
dbh_fallback_connect => sub { $dbh = DBI->connect($dsn, $user, $pass) },
});
Which will only connect if it has to, like if the user is using the DBD::ODBC driver to connect. π«Ά
β ATTRIBUTES β
drivers
This has no default and is required, though a sane defaultish value does exist. (Rude to dangle that and not just default it, but okay. π)
Currently there is one predefined set of drivers, named 2013-12.01. If drivers or facts or just the general structure of drivers changes, they will always be as a new named set of drivers β like, it's versioned, periodt. 2013-12.01 matches the 0.08250 release of DBIx::Class and probably many previous and following releases.
If you need to define it from scratch, you can just pass an arrayref of drivers; see the DRIVER DEFINITION section on what is required for that. But generally it will look something like this (from the tests):
my $d = DBIx::Introspector->new(
drivers => [ map DBIx::Introspector::Driver->new($_),
{
name => 'DBI',
connected_determination_strategy => sub { $_[1]->{Driver}{Name} },
unconnected_determination_strategy => sub {
my $dsn = $_[1] || $ENV{DBI_DSN} || '';
my ($driver) = $dsn =~ /dbi:([^:]+):/i;
$driver ||= $ENV{DBI_DRIVER};
return $driver
},
},
{
name => 'SQLite',
parents => ['DBI'],
connected_determination_strategy => sub {
my ($v) = $_[1]->selectrow_array('SELECT "value" FROM "a"');
return "SQLite$v"
},
connected_options => {
bar => sub { 2 },
},
unconnected_options => {
borg => sub { 'magic ham' },
},
},
{ name => 'SQLite1', parents => ['SQLite'] },
{ name => 'SQLite2', parents => ['SQLite'] },
]
);
π§ DRIVER DEFINITION π§
Drivers (DBIx::Introspector::Driver objects) have the following six attributes:
name
Required. Must be unique among the drivers contained in the introspector. No duplicates, bestie, that's the vibe check. π
parents
Arrayref of parent drivers. This allows parent drivers to implement common options among children. So for example one might define a driver for each version of PostgreSQL, and have a parent driver that they all use for common base info. Inheritance but make it database-y. π
connected_determination_strategy
This is a code reference that is called as a method on the driver with the dbh as the first argument and an optional dsn as the second argument. It should return a driver name.
unconnected_determination_strategy
This is a code reference that is called as a method on the driver with the dsn as the first argument. It should return a driver name. (Notice: no dbh here. That's the whole "unconnected" thing. πΈ)
connected_options
Hashref of key value pairs for detecting information based on the dbh. A value that is not a code reference is returned directly β though I suggest non-coderefs all go in the unconnected_options so that they may be used without connecting if possilbe. (And yes, "possilbe" is the original's typo, I'm keeping it, no cap, it's part of the history now ππ)
If a code reference is passed it will get called as a method on the driver with the following list of values:
dbhβ This is the connecteddbhthat you can use to introspect the database.dsnβ This is thedsnpassed toget, possibly undefined.
unconnected_options
Hashref of key value pairs for detecting information based on the dsn. A value that is not a code reference is returned directly.
If a code reference is passed it will get called as a method on the driver with the following list value:
dsnβ This is the connecteddsnthat you can use to introspect the database.
π AUTHOR π
Arthur Axel "fREW" Schmidt <frioux+cpan@gmail.com>
π COPYRIGHT AND LICENSE π
This software is copyright (c) 2015 by Arthur Axel "fREW" Schmidt.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
okay that's the whole page, you read all of it, slay πβ¨
mwah π β this was DBIx::...pector(3pm), shipped with perl v5.34.0, dated 2022-06-13. bye bestie, go detect a database π¦
π¦ where this page comes from
- debian bookworm: libdbix-introspector-perl 0.001005-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- debian trixie: libdbix-introspector-perl 0.001005-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu noble: libdbix-introspector-perl 0.001005-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu resolute: libdbix-introspector-perl 0.001005-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- ubuntu stonking: libdbix-introspector-perl 0.001005-2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms