1
0
Fork 0
mirror of https://github.com/DBD-SQLite/DBD-SQLite synced 2025-06-07 14:19:10 -04:00

refactored primary_key_info to support attached databases

This commit is contained in:
Kenichi Ishigaki 2012-09-12 07:19:34 +00:00
parent d851a2c12b
commit 8261b0d4ee
3 changed files with 97 additions and 27 deletions

View file

@ -21,6 +21,8 @@ Changes for Perl extension DBD-SQLite
- Resolved #64177: ping() wipes out the errstr (ISHIGAKI)
- Resolved #79576: (patch) bind_param don't work with PADTMP
scalars (VOVKASM)
- Refactored primary_key_info to support attached databases
(ISHIGAKI)
1.37 Thu 12 Jun 2012
- Updated to SQLite 3.7.12.1 (ISHIGAKI)

View file

@ -377,40 +377,46 @@ END_SQL
sub primary_key_info {
my ($dbh, $catalog, $schema, $table, $attr) = @_;
unless ($schema) {
# for backward compat
my $table_info = $dbh->table_info($catalog, $schema, $table);
while(my $info = $table_info->fetchrow_hashref) {
next unless uc $info->{TABLE_TYPE} eq 'TABLE';
if ($info->{TABLE_NAME} eq $table) {
$schema = $info->{TABLE_SCHEM};
last;
}
}
}
# placeholder doesn't seem to work here
my $quoted_table = $dbh->quote($table);
my $psth = $dbh->prepare("PRAGMA table_info($quoted_table)");
$psth->execute;
my $databases = $dbh->selectall_arrayref("PRAGMA database_list", {Slice => {}});
my @pk_info;
while(my $col = $psth->fetchrow_hashref) {
if ($col->{pk}) { # we now have this!
push @pk_info, {
TABLE_SCHEM => $schema,
TABLE_NAME => $table,
COLUMN_NAME => $col->{name},
KEY_SEQ => scalar @pk_info + 1,
PK_NAME => 'PRIMARY KEY',
};
for my $database (@$databases) {
my $dbname = $database->{name};
next if defined $schema && $schema ne '%' && $schema ne $dbname;
my $quoted_dbname = $dbh->quote_identifier($dbname);
my $master_table =
($dbname eq 'main') ? 'sqlite_master' :
($dbname eq 'temp') ? 'sqlite_temp_master' :
$quoted_dbname.'.sqlite_master';
my $sth = $dbh->prepare("SELECT name FROM $master_table WHERE type = ?");
$sth->execute("table");
while(my $row = $sth->fetchrow_hashref) {
my $tbname = $row->{name};
next if defined $table && $table ne '%' && $table ne $tbname;
my $quoted_tbname = $dbh->quote_identifier($tbname);
my $t_sth = $dbh->prepare("PRAGMA $quoted_dbname.table_info($quoted_tbname)");
$t_sth->execute;
while(my $col = $t_sth->fetchrow_hashref) {
next unless $col->{pk};
push @pk_info, {
TABLE_SCHEM => $dbname,
TABLE_NAME => $tbname,
COLUMN_NAME => $col->{name},
KEY_SEQ => scalar @pk_info + 1,
PK_NAME => 'PRIMARY KEY',
};
}
}
}
my $sponge = DBI->connect("DBI:Sponge:", '','')
or return $dbh->DBI::set_err($DBI::err, "DBI::Sponge: $DBI::errstr");
my @names = qw(TABLE_CAT TABLE_SCHEM TABLE_NAME COLUMN_NAME KEY_SEQ PK_NAME);
my $sth = $sponge->prepare( "primary_key_info $table", {
my $sth = $sponge->prepare( "primary_key_info", {
rows => [ map { [ @{$_}{@names} ] } @pk_info ],
NUM_OF_FIELDS => scalar @names,
NAME => \@names,

View file

@ -10,7 +10,7 @@ use t::lib::Test qw/connect_ok/;
use Test::More;
use Test::NoWarnings;
plan tests => 5 * 5 + 1;
plan tests => (5 * 5) + (3 * 6 + 1) + 1;
for my $quote ('', qw/' " ` []/) {
my ($begin_quote, $end_quote) = (substr($quote, 0, 1), substr($quote, -1, 1));
@ -26,3 +26,65 @@ for my $quote ('', qw/' " ` []/) {
($pk) = $dbh->primary_key(undef, undef, 'foo');
ok $pk eq 'id';
}
{
my $dbh = connect_ok();
$dbh->do("create table foo (id integer primary key)");
$dbh->do("attach database ':memory:' as remote");
$dbh->do("create table remote.bar (name text, primary key(name))");
$dbh->do("create temporary table baz (tmp primary key)");
{
my $sth = $dbh->primary_key_info(undef, undef, 'foo');
my @pk_info;
while(my $row = $sth->fetchrow_hashref) { push @pk_info, $row };
is @pk_info => 1, "found 1 pk in a table";
is $pk_info[0]{TABLE_SCHEM} => 'main', "scheme is correct";
is $pk_info[0]{COLUMN_NAME} => 'id', "pk name is correct";
}
{
my $sth = $dbh->primary_key_info(undef, 'main', undef);
my @pk_info;
while(my $row = $sth->fetchrow_hashref) { push @pk_info, $row };
is @pk_info => 1, "found 1 pk in a table";
is $pk_info[0]{TABLE_SCHEM} => 'main', "scheme is correct";
is $pk_info[0]{COLUMN_NAME} => 'id', "pk name is correct";
}
{
my $sth = $dbh->primary_key_info(undef, undef, 'bar');
my @pk_info;
while(my $row = $sth->fetchrow_hashref) { push @pk_info, $row };
is @pk_info => 1, "found 1 pk in an attached table";
is $pk_info[0]{TABLE_SCHEM} => 'remote', "scheme is correct";
is $pk_info[0]{COLUMN_NAME} => 'name', "pk name is correct";
}
{
my $sth = $dbh->primary_key_info(undef, 'remote', undef);
my @pk_info;
while(my $row = $sth->fetchrow_hashref) { push @pk_info, $row };
is @pk_info => 1, "found 1 pk in an attached table";
is $pk_info[0]{TABLE_SCHEM} => 'remote', "scheme is correct";
is $pk_info[0]{COLUMN_NAME} => 'name', "pk name is correct";
}
{
my $sth = $dbh->primary_key_info(undef, 'temp', undef);
my @pk_info;
while(my $row = $sth->fetchrow_hashref) { push @pk_info, $row };
is @pk_info => 1, "found 1 pk in a table";
is $pk_info[0]{TABLE_SCHEM} => 'temp', "scheme is correct";
is $pk_info[0]{COLUMN_NAME} => 'tmp', "pk name is correct";
}
{
my $sth = $dbh->primary_key_info(undef, undef, 'baz');
my @pk_info;
while(my $row = $sth->fetchrow_hashref) { push @pk_info, $row };
is @pk_info => 1, "found 1 pk in an attached table";
is $pk_info[0]{TABLE_SCHEM} => 'temp', "scheme is correct";
is $pk_info[0]{COLUMN_NAME} => 'tmp', "pk name is correct";
}
}