mirror of
https://github.com/DBD-SQLite/DBD-SQLite
synced 2025-06-07 06:08:38 -04:00
refactored primary_key_info to support attached databases
This commit is contained in:
parent
d851a2c12b
commit
8261b0d4ee
3 changed files with 97 additions and 27 deletions
2
Changes
2
Changes
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
}
|
Loading…
Add table
Reference in a new issue