monetdb.pm

来自「这个是内存数据库的客户端」· PM 代码 · 共 884 行 · 第 1/2 页

PM
884
字号
package DBD::monetdb;use strict;use sigtrap;use DBI();use MonetDB::CLI();our $VERSION = '0.09';our $drh = undef;require DBD::monetdb::GetInfo;require DBD::monetdb::TypeInfo;sub driver {    return $drh if $drh;    my ($class, $attr) = @_;    $drh = DBI::_new_drh($class .'::dr', {        Name        => 'monetdb',        Version     => $VERSION,        Attribution => 'DBD::monetdb by Martin Kersten, Arjan Scherpenisse and Steffen Goeldner',    });}sub CLONE {    undef $drh;}package DBD::monetdb::dr;$DBD::monetdb::dr::imp_data_size = 0;sub connect {    my ($drh, $dsn, $user, $password, $attr) = @_;    my %dsn;    for ( split /;|:/, $dsn ||'') {        if ( my ( $k, $v ) = /(.*?)=(.*)/) {            $k = 'host'     if $k eq 'hostname';            $k = 'database' if $k eq 'dbname' || $k eq 'db';            $dsn{$k} = $v;            next;        }        for my $k ( qw(host port database language) ) {            $dsn{$k} = $_, last unless defined $dsn{$k};        }    }    my $lang  = $dsn{language} || 'sql';    my $host  = $dsn{host} || 'localhost';    my $port  = $dsn{port} || 50000;    $user     ||= 'monetdb';    $password ||= 'monetdb';    my $cxn = eval { MonetDB::CLI->connect($host, $port, $user, $password, $lang) };    return $drh->set_err(-1, $@) if $@;    my ($outer, $dbh) = DBI::_new_dbh($drh, { Name => $dsn });    $dbh->STORE('Active', 1 );    $dbh->{monetdb_connection} = $cxn;    $dbh->{monetdb_language} = $lang;    return $outer;}sub data_sources {    return ('dbi:monetdb:');}package DBD::monetdb::db;$DBD::monetdb::db::imp_data_size = 0;sub ping {    my ($dbh) = @_;    my $statement = $dbh->{monetdb_language} eq 'sql' ? 'select 7' : 'print(7);';    my $rv = $dbh->selectrow_array($statement) || 0;    $dbh->set_err(undef, undef);    $rv == 7 ? 1 : 0;}sub quote {    my ($dbh, $value, $type) = @_;    return $dbh->{monetdb_language} eq 'sql' ? 'NULL' : 'nil'        unless defined $value;    for ($value) {      s/	/\\t/g;      s/\\/\\\\/g;      s/\n/\\n/g;      s/\r/\\r/g;      s/"/\\"/g;      s/'/''/g;    }    $type ||= DBI::SQL_VARCHAR();    my $prefix = $DBD::monetdb::TypeInfo::prefixes{$type} || '';    my $suffix = $DBD::monetdb::TypeInfo::suffixes{$type} || '';    if ( $dbh->{monetdb_language} ne 'sql') {        $prefix = q(") if $prefix eq q(');        $suffix = q(") if $suffix eq q(');    }    return $prefix . $value . $suffix;}sub _count_param {    my @statement = split //, shift;    my $num = 0;    while (defined(my $c = shift @statement)) {        if ($c eq '"' || $c eq "'") {            my $end = $c;            while (defined(my $c = shift @statement)) {                last if $c eq $end;                @statement = splice @statement, 2 if $c eq '\\';            }        }        elsif ($c eq '?') {            $num++;        }    }    return $num;}sub prepare {    my ($dbh, $statement, $attr) = @_;    my $cxn = $dbh->{monetdb_connection};    my $hdl = eval { $cxn->new_handle };    return $dbh->set_err(-1, $@) if $@;    my ($outer, $sth) = DBI::_new_sth($dbh, { Statement => $statement });    $sth->STORE('NUM_OF_PARAMS', _count_param($statement));    $sth->{monetdb_hdl} = $hdl;    $sth->{monetdb_params} = [];    $sth->{monetdb_types} = [];    $sth->{monetdb_rows} = -1;    return $outer;}sub commit {    my($dbh) = @_;    if ($dbh->FETCH('AutoCommit')) {        warn 'Commit ineffective while AutoCommit is on' if $dbh->FETCH('Warn');        return 0;    }    if ($dbh->{monetdb_language} eq 'sql') {        return $dbh->do('commit')            && $dbh->do('start transaction');    }    else {        return $dbh->do('commit();');    }}sub rollback {    my($dbh) = @_;    if ($dbh->FETCH('AutoCommit')) {        warn 'Rollback ineffective while AutoCommit is on' if $dbh->FETCH('Warn');        return 0;    }    if ($dbh->{monetdb_language} eq 'sql') {        return $dbh->do('rollback')            && $dbh->do('start transaction');    }    else {        return $dbh->do('abort();');    }}*get_info = \&DBD::monetdb::GetInfo::get_info;sub monetdb_catalog_info {    my($dbh) = @_;    my $sql = <<'SQL';select cast( null as varchar( 128 ) ) as table_cat     , cast( null as varchar( 128 ) ) as table_schem     , cast( null as varchar( 128 ) ) as table_name     , cast( null as varchar( 254 ) ) as table_type     , cast( null as varchar( 254 ) ) as remarks where 0 = 1 order by table_catSQL    my $sth = $dbh->prepare($sql) or return;    $sth->execute or return;    return $sth;}sub monetdb_schema_info {    my($dbh) = @_;    my $sql = <<'SQL';select cast( null as varchar( 128 ) ) as table_cat     , "name"                         as table_schem     , cast( null as varchar( 128 ) ) as table_name     , cast( null as varchar( 254 ) ) as table_type     , cast( null as varchar( 254 ) ) as remarks  from sys."schemas" order by table_schemSQL    my $sth = $dbh->prepare($sql) or return;    $sth->execute or return;    return $sth;}my $ttp = { 'TABLE'           => 't."istable" = true  and t."system" = false and t."temporary" = 0','SYSTEM TABLE'    => 't."istable" = true  and t."system" = true  and t."temporary" = 0','LOCAL TEMPORARY' => 't."istable" = true  and t."system" = false and t."temporary" = 1','VIEW'            => 't."istable" = false                                             '};sub monetdb_tabletype_info {    my($dbh) = @_;    my $sql = <<"SQL";select distinct       cast( null as varchar( 128 ) ) as table_cat     , cast( null as varchar( 128 ) ) as table_schem     , cast( null as varchar( 128 ) ) as table_name     , case         when $ttp->{'TABLE'          } then cast('TABLE'               as varchar( 254 ) )         when $ttp->{'SYSTEM TABLE'   } then cast('SYSTEM TABLE'        as varchar( 254 ) )         when $ttp->{'LOCAL TEMPORARY'} then cast('LOCAL TEMPORARY'     as varchar( 254 ) )         when $ttp->{'VIEW'           } then cast('VIEW'                as varchar( 254 ) )         else                                cast('INTERNAL TABLE TYPE' as varchar( 254 ) )       end                            as table_type     , cast( null as varchar( 254 ) ) as remarks  from sys."tables" t order by table_typeSQL    my $sth = $dbh->prepare($sql) or return;    $sth->execute or return;    return $sth;}sub monetdb_table_info {    my($dbh, $c, $s, $t, $tt) = @_;    my $sql = <<"SQL";select cast( null as varchar( 128 ) ) as table_cat     , s."name"                       as table_schem     , t."name"                       as table_name     , case         when $ttp->{'TABLE'          } then cast('TABLE'               as varchar( 254 ) )         when $ttp->{'SYSTEM TABLE'   } then cast('SYSTEM TABLE'        as varchar( 254 ) )         when $ttp->{'LOCAL TEMPORARY'} then cast('LOCAL TEMPORARY'     as varchar( 254 ) )         when $ttp->{'VIEW'           } then cast('VIEW'                as varchar( 254 ) )         else                                cast('INTERNAL TABLE TYPE' as varchar( 254 ) )       end                            as table_type     , cast( null as varchar( 254 ) ) as remarks  from sys."schemas" s     , sys."tables"  t where t."schema_id" = s."id"SQL    my @bv = ();    $sql .= qq(   and s."name"   like ?\n), push @bv, $s if $s;    $sql .= qq(   and t."name"   like ?\n), push @bv, $t if $t;    if ( @$tt ) {        $sql .= "   and ( 1 = 0\n";        for ( @$tt ) {            my $p = $ttp->{uc $_};            $sql .= "      or $p\n" if $p;        }        $sql .= "       )\n";    }    $sql .=   " order by table_type, table_schem, table_name\n";    my $sth = $dbh->prepare($sql) or return;    $sth->execute(@bv) or return;    $dbh->set_err(0,"Catalog parameter '$c' ignored") if defined $c;    return $sth;}sub table_info {    my($dbh, $c, $s, $t, $tt) = @_;    if ( defined $c && defined $s && defined $t ) {        if    ( $c eq '%' && $s eq ''  && $t eq '') {            return monetdb_catalog_info($dbh);        }        elsif ( $c eq ''  && $s eq '%' && $t eq '') {            return monetdb_schema_info($dbh);        }        elsif ( $c eq ''  && $s eq ''  && $t eq '' && defined $tt && $tt eq '%') {            return monetdb_tabletype_info($dbh);        }    }    my @tt;    if ( defined $tt ) {        @tt = split /,/, $tt;        s/^\s*'?//, s/'?\s*$// for @tt;    }    return monetdb_table_info($dbh, $c, $s, $t, \@tt);}sub column_info {    my($dbh, $catalog, $schema, $table, $column) = @_;    my $sql = <<'SQL';select cast( null            as varchar( 128 ) ) as table_cat     , s."name"                                  as table_schem     , t."name"                                  as table_name     , c."name"                                  as column_name     , cast( 0               as smallint       ) as data_type          -- ...     , c."type"                                  as type_name          -- TODO     , cast( c."type_digits" as integer        ) as column_size        -- TODO     , cast( null            as integer        ) as buffer_length      -- TODO     , cast( c."type_scale"  as smallint       ) as decimal_digits     -- TODO     , cast( null            as smallint       ) as num_prec_radix     -- TODO     , case c."null"         when false then cast( 0 as smallint )  -- SQL_NO_NULLS         when true  then cast( 1 as smallint )  -- SQL_NULLABLE       end                                       as nullable     , cast( null            as varchar( 254 ) ) as remarks     , c."default"                               as column_def     , cast( 0               as smallint       ) as sql_data_type      -- ...     , cast( null            as smallint       ) as sql_datetime_sub   -- ...     , cast( null            as integer        ) as char_octet_length  -- TODO     , cast( c."number" + 1  as integer        ) as ordinal_position     , case c."null"         when false then cast('NO'  as varchar( 254 ) )         when true  then cast('YES' as varchar( 254 ) )       end                                       as is_nullable  from sys."schemas" s     , sys."tables"  t     , sys."columns" c where t."schema_id" = s."id"   and c."table_id"  = t."id"SQL    my @bv = ();    $sql .= qq(   and s."name"   like ?\n), push @bv, $schema if $schema;    $sql .= qq(   and t."name"   like ?\n), push @bv, $table  if $table;    $sql .= qq(   and c."name"   like ?\n), push @bv, $column if $column;    $sql .=   " order by table_cat, table_schem, table_name, ordinal_position\n";    my $sth = $dbh->prepare($sql) or return;    $sth->execute(@bv) or return;    $dbh->set_err(0,"Catalog parameter '$catalog' ignored") if defined $catalog;    my $rows;    while ( my $row = $sth->fetch ) {        $row->[ 4] = $DBD::monetdb::TypeInfo::typeinfo{$row->[5]}->[ 1];        $row->[13] = $DBD::monetdb::TypeInfo::typeinfo{$row->[5]}->[15];        $row->[14] = $DBD::monetdb::TypeInfo::typeinfo{$row->[5]}->[16];        push @$rows, [ @$row ];    }    return DBI->connect('dbi:Sponge:','','', { RaiseError => 1 } )->prepare(        $sth->{Statement},        { rows => $rows, NAME => $sth->{NAME}, TYPE => $sth->{TYPE} }    );}sub primary_key_info {    my($dbh, $catalog, $schema, $table) = @_;    return $dbh->set_err(-1,'Undefined schema','HY009') unless defined $schema;    return $dbh->set_err(-1,'Undefined table' ,'HY009') unless defined $table;    my $sql = <<'SQL';select cast( null        as varchar( 128 ) ) as table_cat     , s."name"                              as table_schem     , t."name"                              as table_name     , c."column"                            as column_name     , cast( c."nr" + 1  as smallint       ) as key_seq     , k."name"                              as pk_name  from sys."schemas"     s     , sys."tables"      t     , sys."keys"        k     , sys."keycolumns"  c where t."schema_id"   = s."id"   and k."table_id"    = t."id"   and c."id"          = k."id"   and s."name"        = ?   and t."name"        = ?   and k."type"        = 0 order by table_schem, table_name, key_seqSQL    my $sth = $dbh->prepare($sql) or return;    $sth->execute($schema, $table) or return;    $dbh->set_err(0,"Catalog parameter '$catalog' ignored") if defined $catalog;    return $sth;}sub foreign_key_info {    my($dbh, $c1, $s1, $t1, $c2, $s2, $t2) = @_;    my $sql = <<'SQL';select cast( null         as varchar( 128 ) ) as uk_table_cat     , uks."name"                             as uk_table_schem     , ukt."name"                             as uk_table_name     , ukc."column"                           as uk_column_name     , cast( null         as varchar( 128 ) ) as fk_table_cat     , fks."name"                             as fk_table_schem     , fkt."name"                             as fk_table_name     , fkc."column"                           as fk_column_name     , cast( fkc."nr" + 1 as smallint       ) as ordinal_position     , cast( 3            as smallint       ) as update_rule    -- SQL_NO_ACTION     , cast( 3            as smallint       ) as delete_rule    -- SQL_NO_ACTION     , fkk."name"                             as fk_name     , ukk."name"                             as uk_name     , cast( 7            as smallint       ) as deferability   -- SQL_NOT_DEFERRABLE     , case  ukk."type"         when 0 then cast('PRIMARY'   as varchar( 7 ) )         when 1 then cast('UNIQUE'    as varchar( 7 ) )         else        cast( ukk."type" as varchar( 7 ) )       end                                    as unique_or_primary  from sys."schemas"    uks     , sys."tables"     ukt     , sys."keys"       ukk     , sys."keycolumns" ukc     , sys."schemas"    fks     , sys."tables"     fkt     , sys."keys"       fkk     , sys."keycolumns" fkc where ukt."schema_id"  = uks."id"   and ukk."table_id"   = ukt."id"

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?