home *** CD-ROM | disk | FTP | other *** search
/ PC Professionell 2004 December / PCpro_2004_12.ISO / files / webserver / xampp / xampp-perl-addon-1.4.9-installer.exe / mysqlPP.pm < prev    next >
Encoding:
Perl POD Document  |  2003-01-27  |  17.1 KB  |  855 lines

  1. package DBD::mysqlPP;
  2. use strict;
  3.  
  4. use DBI;
  5. use Carp;
  6. use vars qw($VERSION $err $errstr $state $drh);
  7.  
  8. $VERSION = '0.04';
  9. $err = 0;
  10. $errstr = '';
  11. $state = undef;
  12. $drh = undef;
  13.  
  14. sub driver
  15. {
  16.     return $drh if $drh;
  17.  
  18.     my $class = shift;
  19.     my $attr  = shift;
  20.     $class .= '::dr';
  21.  
  22.     $drh = DBI::_new_drh($class, {
  23.         Name        => 'mysqlPP',
  24.         Version     => $VERSION,
  25.         Err         => \$DBD::mysqlPP::err,
  26.         Errstr      => \$DBD::mysqlPP::errstr,
  27.         State       => \$DBD::mysqlPP::state,
  28.         Attribution => 'DBD::mysqlPP by Hiroyuki OYAMA',
  29.     }, {});
  30. }
  31.  
  32.  
  33. sub _parse_dsn
  34. {
  35.     my $class = shift;
  36.     my ($dsn, $args) = @_;
  37.     my($hash, $var, $val);
  38.     return if ! defined $dsn;
  39.  
  40.     while (length $dsn) {
  41.         if ($dsn =~ /([^:;]*)[:;](.*)/) {
  42.             $val = $1;
  43.             $dsn = $2;
  44.         }
  45.         else {
  46.             $val = $dsn;
  47.             $dsn = '';
  48.         }
  49.         if ($val =~ /([^=]*)=(.*)/) {
  50.             $var = $1;
  51.             $val = $2;
  52.             if ($var eq 'hostname' || $var eq 'host') {
  53.                 $hash->{'host'} = $val;
  54.             }
  55.             elsif ($var eq 'db' || $var eq 'dbname') {
  56.                 $hash->{'database'} = $val;
  57.             }
  58.             else {
  59.                 $hash->{$var} = $val;
  60.             }
  61.         }
  62.         else {
  63.             for $var (@$args) {
  64.                 if (!defined($hash->{$var})) {
  65.                     $hash->{$var} = $val;
  66.                     last;
  67.                 }
  68.             }
  69.         }
  70.     }
  71.     return $hash;
  72. }
  73.  
  74.  
  75. sub _parse_dsn_host
  76. {
  77.     my($class, $dsn) = @_;
  78.     my $hash = $class->_parse_dsn($dsn, ['host', 'port']);
  79.     ($hash->{'host'}, $hash->{'port'});
  80. }
  81.  
  82.  
  83.  
  84. package DBD::mysqlPP::dr;
  85.  
  86. $DBD::mysqlPP::dr::imp_data_size = 0;
  87.  
  88. use Net::MySQL;
  89. use strict;
  90.  
  91.  
  92. sub connect
  93. {
  94.     my $drh = shift;
  95.     my ($dsn, $user, $password, $attrhash) = @_;
  96.  
  97.     my $data_source_info = DBD::mysqlPP->_parse_dsn(
  98.         $dsn, ['database', 'host', 'port'],
  99.     );
  100.     $user     ||= '';
  101.     $password ||= '';
  102.  
  103.     my $dbh = DBI::_new_dbh($drh, {
  104.         Name         => $dsn,
  105.         USER         => $user,
  106.         CURRENT_USRE => $user,
  107.     }, {});
  108.     eval {
  109.         my $mysql = Net::MySQL->new(
  110.             hostname => $data_source_info->{host},
  111.             port     => $data_source_info->{port},
  112.             database => $data_source_info->{database},
  113.             user     => $user,
  114.             password => $password,
  115.             debug    => $attrhash->{protocol_dump},
  116.         );
  117.         $dbh->STORE(mysqlpp_connection => $mysql);
  118.         $dbh->STORE(thread_id => $mysql->{server_thread_id});
  119.     };
  120.     if ($@) {
  121.         return $dbh->DBI::set_err(1, $@);
  122.     }
  123.     return $dbh;
  124. }
  125.  
  126.  
  127. sub data_sources
  128. {
  129.     return ("dbi:mysqlPP:");
  130. }
  131.  
  132.  
  133. sub disconnect_all {}
  134.  
  135.  
  136.  
  137. package DBD::mysqlPP::db;
  138.  
  139. $DBD::mysqlPP::db::imp_data_size = 0;
  140. use strict;
  141.  
  142.  
  143. # Patterns referred to 'mysql_sub_escape_string()' of libmysql.c
  144. sub quote
  145. {
  146.     my $dbh = shift;
  147.     my ($statement, $type) = @_;
  148.     return 'NULL' unless defined $statement;
  149.  
  150.     for ($statement) {
  151.         s/\\/\\\\/g;
  152.         s/\0/\\0/g;
  153.         s/\n/\\n/g;
  154.         s/\r/\\r/g;
  155.         s/'/\\'/g;
  156.         s/"/\\"/g;
  157.         s/\x1a/\\Z/g;
  158.     }
  159.     return "'$statement'";
  160. }
  161.  
  162. sub _count_param
  163. {
  164.     my @statement = split //, shift;
  165.     my $num = 0;
  166.  
  167.     while (defined(my $c = shift @statement)) {
  168.         if ($c eq '"' || $c eq "'") {
  169.             my $end = $c;
  170.             while (defined(my $c = shift @statement)) {
  171.                 last if $c eq $end;
  172.                 @statement = splice @statement, 2 if $c eq '\\';
  173.             }
  174.         }
  175.         elsif ($c eq '?') {
  176.             $num++;
  177.         }
  178.     }
  179.     return $num;
  180. }
  181.  
  182. sub prepare
  183. {
  184.     my $dbh = shift;
  185.     my ($statement, @attribs) = @_;
  186.  
  187.     my $sth = DBI::_new_sth($dbh, {
  188.         Statement => $statement,
  189.     });
  190.     $sth->STORE(mysqlpp_handle => $dbh->FETCH('mysqlpp_connection'));
  191.     $sth->STORE(mysqlpp_params => []);
  192.     $sth->STORE(NUM_OF_PARAMS => _count_param($statement));
  193.     $sth;
  194. }
  195.  
  196.  
  197. sub commit
  198. {
  199.     my $dbh = shift;
  200.     if ($dbh->FETCH('Warn')) {
  201.         warn 'Commit ineffective while AutoCommit is on';
  202.     }
  203.     1;
  204. }
  205.  
  206.  
  207. sub rollback
  208. {
  209.     my $dbh = shift;
  210.     if ($dbh->FETCH('Warn')) {
  211.         warn 'Rollback ineffective while AutoCommit is on';
  212.     }
  213.     1;
  214. }
  215.  
  216.  
  217. sub tables
  218. {
  219.     my $dbh = shift;
  220.     my @args = @_;
  221.     my $mysql = $dbh->FETCH('mysqlpp_connection');
  222.  
  223.     my @database_list;
  224.     eval {
  225.         $mysql->query('show tables');
  226.         die $mysql->get_error_message if $mysql->is_error;
  227.         if ($mysql->has_selected_record) {
  228.             my $record = $mysql->create_record_iterator;
  229.             while (my $db_name = $record->each) {
  230.                 push @database_list, $db_name->[0];
  231.             }
  232.         }
  233.     };
  234.     if ($@) {
  235.         warn $mysql->get_error_message;
  236.     }
  237.     return $mysql->is_error
  238.         ? undef
  239.         : @database_list;
  240. }
  241.  
  242.  
  243. sub _ListDBs
  244. {
  245.     my $dbh = shift;
  246.     my @args = @_;
  247.     my $mysql = $dbh->FETCH('mysqlpp_connection');
  248.  
  249.     my @database_list;
  250.     eval {
  251.         $mysql->query('show databases');
  252.         die $mysql->get_error_message if $mysql->is_error;
  253.         if ($mysql->has_selected_record) {
  254.             my $record = $mysql->create_record_iterator;
  255.             while (my $db_name = $record->each) {
  256.                 push @database_list, $db_name->[0];
  257.             }
  258.         }
  259.     };
  260.     if ($@) {
  261.         warn $mysql->get_error_message;
  262.     }
  263.     return $mysql->is_error
  264.         ? undef
  265.         : @database_list;
  266. }
  267.  
  268.  
  269. sub _ListTables
  270. {
  271.     my $dbh = shift;
  272.     return $dbh->tables;
  273. }
  274.  
  275.  
  276. sub disconnect
  277. {
  278.     return 1;
  279. }
  280.  
  281.  
  282. sub FETCH
  283. {
  284.     my $dbh = shift;
  285.     my $key = shift;
  286.  
  287.     return 1 if $key eq 'AutoCommit';
  288.     return $dbh->{$key} if $key =~ /^(?:mysqlpp_.*|thread_id|mysql_insertid)$/;
  289.     return $dbh->SUPER::FETCH($key);
  290. }
  291.  
  292.  
  293. sub STORE
  294. {
  295.     my $dbh = shift;
  296.     my ($key, $value) = @_;
  297.  
  298.     if ($key eq 'AutoCommit') {
  299.         die "Can't disable AutoCommit" unless $value;
  300.         return 1;
  301.     }
  302.     elsif ($key =~ /^(?:mysqlpp_.*|thread_id|mysql_insertid)$/) {
  303.         $dbh->{$key} = $value;
  304.         return 1;
  305.     }
  306.     return $dbh->SUPER::STORE($key, $value);
  307. }
  308.  
  309.  
  310. sub DESTROY
  311. {
  312.     my $dbh = shift;
  313.     my $mysql = $dbh->FETCH('mysqlpp_connection');
  314.     $mysql->close;
  315. }
  316.  
  317.  
  318. package DBD::mysqlPP::st;
  319.  
  320. $DBD::mysqlPP::st::imp_data_size = 0;
  321. use strict;
  322.  
  323.  
  324. sub bind_param
  325. {
  326.     my $sth = shift;
  327.     my ($index, $value, $attr) = @_;
  328.     my $type = (ref $attr) ? $attr->{TYPE} : $attr;
  329.     if ($type) {
  330.         my $dbh = $sth->{Database};
  331.         $value = $dbh->quote($sth, $type);
  332.     }
  333.     my $params = $sth->FETCH('mysqlpp_param');
  334.     $params->[$index - 1] = $value;
  335. }
  336.  
  337.  
  338.  
  339. sub execute
  340. {
  341.     my $sth = shift;
  342.     my @bind_values = @_;
  343.     my $params = (@bind_values) ?
  344.         \@bind_values : $sth->FETCH('mysqlpp_params');
  345.     my $num_param = $sth->FETCH('NUM_OF_PARAMS');
  346.     if (@$params != $num_param) {
  347.         # ...
  348.     }
  349.     my $statement = $sth->{Statement};
  350.     for (my $i = 0; $i < $num_param; $i++) {
  351.         my $dbh = $sth->{Database};
  352.         my $quoted_param = $dbh->quote($params->[$i]);
  353.         $statement =~ s/\?/$quoted_param/e;
  354.     }
  355.     my $mysql = $sth->FETCH('mysqlpp_handle');
  356.     my $result = eval {
  357.         $sth->{mysqlpp_record_iterator} = undef;
  358.         $mysql->query($statement);
  359.         die if $mysql->is_error;
  360.  
  361.         my $dbh = $sth->{Database};
  362.         $dbh->STORE(mysqlpp_insertid => $mysql->get_insert_id);
  363.         $dbh->STORE(mysql_insertid => $mysql->get_insert_id);
  364.  
  365.         $sth->{mysqlpp_rows} = $mysql->get_affected_rows_length;
  366.         if ($mysql->has_selected_record) {
  367.             my $record = $mysql->create_record_iterator;
  368.             $sth->{mysqlpp_record_iterator} = $record;
  369.             $sth->STORE(NUM_OF_FIELDS => $record->get_field_length);
  370.             $sth->STORE(NAME => [ $record->get_field_names ]);
  371.         }
  372.         $mysql->get_affected_rows_length;
  373.     };
  374.     if ($@) {
  375.         $sth->DBI::set_err(
  376.             $mysql->get_error_code, $mysql->get_error_message
  377.         );
  378.         return undef;
  379.     }
  380.  
  381.     return $mysql->is_error
  382.         ? undef : $result
  383.             ? $result : '0E0';
  384. }
  385.  
  386.  
  387. sub fetch
  388. {
  389.     my $sth = shift;
  390.  
  391.     my $iterator = $sth->FETCH('mysqlpp_record_iterator');
  392.     my $row = $iterator->each;
  393.     return undef unless $row;
  394.  
  395.     if ($sth->FETCH('ChopBlanks')) {
  396.         map {s/\s+$//} @$row;
  397.     }
  398.     return $sth->_set_fbav($row);
  399. }
  400. *fetchrow_arrayref = \&fetch;
  401.  
  402.  
  403. sub rows
  404. {
  405.     my $sth = shift;
  406.     $sth->FETCH('mysqlpp_rows');
  407. }
  408.  
  409.  
  410. sub FETCH
  411. {
  412.     my $dbh = shift;
  413.     my $key = shift;
  414.  
  415.     return 1 if $key eq 'AutoCommit';
  416.     return $dbh->{NAME} if $key eq 'NAME';
  417.     return $dbh->{$key} if $key =~ /^mysqlpp_/;
  418.     return $dbh->SUPER::FETCH($key);
  419. }
  420.  
  421.  
  422. sub STORE
  423. {
  424.     my $dbh = shift;
  425.     my ($key, $value) = @_;
  426.  
  427.     if ($key eq 'AutoCommit') {
  428.         die "Can't disable AutoCommit" unless $value;
  429.         return 1;
  430.     }
  431.     elsif ($key eq 'NAME') {
  432.         $dbh->{NAME} = $value;
  433.         return 1;
  434.     }
  435.     elsif ($key =~ /^mysqlpp_/) {
  436.         $dbh->{$key} = $value;
  437.         return 1;
  438.     }
  439.     return $dbh->SUPER::STORE($key, $value);
  440. }
  441.  
  442.  
  443. sub DESTROY
  444. {
  445.     my $dbh = shift;
  446.  
  447. }
  448.  
  449.  
  450. 1;
  451. __END__
  452.  
  453. =head1 NAME
  454.  
  455. DBD::mysqlPP - Pure Perl MySQL driver for the DBI
  456.  
  457. =head1 SYNOPSIS
  458.  
  459.     use DBI;
  460.  
  461.     $dsn = "dbi:mysqlPP:database=$database;host=$hostname";
  462.  
  463.     $dbh = DBI->connect($dsn, $user, $password);
  464.  
  465.     $drh = DBI->install_driver("mysqlPP");
  466.  
  467.     $sth = $dbh->prepare("SELECT * FROM foo WHERE bla");
  468.     $sth->execute;
  469.     $numRows = $sth->rows;
  470.     $numFields = $sth->{'NUM_OF_FIELDS'};
  471.     $sth->finish;
  472.  
  473. =head1 EXAMPLE
  474.  
  475.   #!/usr/bin/perl
  476.  
  477.   use strict;
  478.   use DBI;
  479.  
  480.   # Connect to the database.
  481.   my $dbh = DBI->connect("dbi:mysqlPP:database=test;host=localhost",
  482.                          "joe", "joe's password",
  483.                          {'RaiseError' => 1});
  484.  
  485.   # Drop table 'foo'. This may fail, if 'foo' doesn't exist.
  486.   # Thus we put an eval around it.
  487.   eval { $dbh->do("DROP TABLE foo") };
  488.   print "Dropping foo failed: $@\n" if $@;
  489.  
  490.   # Create a new table 'foo'. This must not fail, thus we don't
  491.   # catch errors.
  492.   $dbh->do("CREATE TABLE foo (id INTEGER, name VARCHAR(20))");
  493.  
  494.   # INSERT some data into 'foo'. We are using $dbh->quote() for
  495.   # quoting the name.
  496.   $dbh->do("INSERT INTO foo VALUES (1, " . $dbh->quote("Tim") . ")");
  497.  
  498.   # Same thing, but using placeholders
  499.   $dbh->do("INSERT INTO foo VALUES (?, ?)", undef, 2, "Jochen");
  500.  
  501.   # Now retrieve data from the table.
  502.   my $sth = $dbh->prepare("SELECT id, name FROM foo");
  503.   $sth->execute();
  504.   while (my $ref = $sth->fetchrow_arrayref()) {
  505.     print "Found a row: id = $ref->[0], name = $ref->[1]\n";
  506.   }
  507.   $sth->finish();
  508.  
  509.   # Disconnect from the database.
  510.   $dbh->disconnect();
  511.  
  512.  
  513. =head1 DESCRIPTION
  514.  
  515. DBD::mysqlPP is a Pure Perl client interface for the MySQL database. This module implements network protool between server and client of MySQL, thus you don't need external MySQL client library like libmysqlclient for this module to work. It means this module enables you to connect to MySQL server from some operation systems which MySQL is not ported. How nifty!
  516.  
  517. From perl you activate the interface with the statement
  518.  
  519.     use DBI;
  520.  
  521. After that you can connect to multiple MySQL database servers
  522. and send multiple queries to any of them via a simple object oriented
  523. interface. Two types of objects are available: database handles and
  524. statement handles. Perl returns a database handle to the connect
  525. method like so:
  526.  
  527.   $dbh = DBI->connect("dbi:mysqlPP:database=$db;host=$host",
  528.               $user, $password, {RaiseError => 1});
  529.  
  530. Once you have connected to a database, you can can execute SQL
  531. statements with:
  532.  
  533.   my $query = sprintf("INSERT INTO foo VALUES (%d, %s)",
  534.               $number, $dbh->quote("name"));
  535.   $dbh->do($query);
  536.  
  537. See L<DBI(3)> for details on the quote and do methods. An alternative
  538. approach is
  539.  
  540.   $dbh->do("INSERT INTO foo VALUES (?, ?)", undef,
  541.        $number, $name);
  542.  
  543. in which case the quote method is executed automatically. See also
  544. the bind_param method in L<DBI(3)>. See L<DATABASE HANDLES> below
  545. for more details on database handles.
  546.  
  547. If you want to retrieve results, you need to create a so-called
  548. statement handle with:
  549.  
  550.   $sth = $dbh->prepare("SELECT id, name FROM $table");
  551.   $sth->execute();
  552.  
  553. This statement handle can be used for multiple things. First of all
  554. you can retreive a row of data:
  555.  
  556.   my $row = $sth->fetchow_arrayref();
  557.  
  558. If your table has columns ID and NAME, then $row will be array ref with
  559. index 0 and 1. See L<STATEMENT HANDLES> below for more details on
  560. statement handles.
  561.  
  562. I's more formal approach:
  563.  
  564.  
  565. =head2 Class Methods
  566.  
  567. =over
  568.  
  569. =item B<connect>
  570.  
  571.     use DBI;
  572.  
  573.     $dsn = "dbi:mysqlPP:$database";
  574.     $dsn = "dbi:mysqlPP:database=$database;host=$hostname";
  575.     $dsn = "dbi:mysqlPP:database=$database;host=$hostname;port=$port";
  576.  
  577.     $dbh = DBI->connect($dsn, $user, $password);
  578.  
  579. A C<database> must always be specified.
  580.  
  581. =over
  582.  
  583. =item host
  584.  
  585. The hostname, if not specified or specified as '', will default to an
  586. MySQL daemon running on the local machine on the default port
  587. for the INET socket.
  588.  
  589. =item port
  590.  
  591. Port where MySQL daemon listens to. default is 3306.
  592.  
  593. =back
  594.  
  595. =back
  596.  
  597. =head2 MetaData Method
  598.  
  599. =over 4
  600.  
  601. =item B<tables>
  602.  
  603.     @names = $dbh->tables;
  604.  
  605. Returns a list of table and view names, possibly including a schema prefix. This list should include all tables that can be used in a "SELECT" statement without further qualification.
  606.  
  607. =back
  608.  
  609. =head2 Private MetaData Methods
  610.  
  611. =over 4
  612.  
  613. =item ListDBs
  614.  
  615.     @dbs = $dbh->func('_ListDBs');
  616.  
  617. Returns a list of all databases managed by the MySQL daemon.
  618.  
  619. =item ListTables
  620.  
  621. B<WARNING>: This method is obsolete due to DBI's $dbh->tables().
  622.  
  623.     @tables = $dbh->func('_ListTables');
  624.  
  625. Once connected to the desired database on the desired mysql daemon with the "DBI-"connect()> method, we may extract a list of the tables that have been created within that database.
  626.  
  627. "ListTables" returns an array containing the names of all the tables present within the selected database. If no tables have been created, an empty list is returned.
  628.  
  629.     @tables = $dbh->func('_ListTables');
  630.     foreach $table (@tables) {
  631.         print "Table: $table\n";
  632.     }
  633.  
  634. =back
  635.  
  636.  
  637. =head1 DATABASE HANDLES
  638.  
  639. The DBD::mysqlPP driver supports the following attributes of database
  640. handles (read only):
  641.  
  642.   $insertid = $dbh->{'mysqlpp_insertid'};
  643.   $insertid = $dbh->{'mysql_insertid'};
  644.  
  645. =head1 STATEMENT HANDLES
  646.  
  647. The statement handles of DBD::mysqlPP support a number
  648. of attributes. You access these by using, for example,
  649.  
  650.   my $numFields = $sth->{'NUM_OF_FIELDS'};
  651.  
  652. =over
  653.  
  654. =item mysqlpp_insertid/mysql_insertid
  655.  
  656. MySQL has the ability to choose unique key values automatically. If this
  657. happened, the new ID will be stored in this attribute. An alternative
  658. way for accessing this attribute is via $dbh->{'mysqlpp_insertid'}.
  659. (Note we are using the $dbh in this case!)
  660.  
  661. =item NUM_OF_FIELDS
  662.  
  663. Number of fields returned by a I<SELECT> statement. You may use this for checking whether a statement returned a result.
  664. A zero value indicates a non-SELECT statement like I<INSERT>, I<DELETE> or I<UPDATE>.
  665.  
  666. =back
  667.  
  668. =head1 INSTALLATION
  669.  
  670. To install this module type the following:
  671.  
  672.    perl Makefile.PL
  673.    make
  674.    make test
  675.    make install
  676.  
  677. =head1 SUPPORT OPERATING SYSTEM
  678.  
  679. This module has been tested on these OSes.
  680.  
  681. =over 4
  682.  
  683. =item * MacOS 9.x
  684.  
  685. with MacPerl5.6.1r.
  686.  
  687. =item * MacOS X
  688.  
  689. with perl5.6.0 build for darwin.
  690.  
  691. =item * Windows2000
  692.  
  693. with ActivePerl5.6.1 build631.
  694.  
  695. =item * FreeBSD 3.4 and 4.x
  696.  
  697. with perl5.6.1 build for i386-freebsd.
  698.  
  699. with perl5.005_03 build for i386-freebsd.
  700.  
  701. =back
  702.  
  703. =head1 DEPENDENCIES
  704.  
  705. This module requires these other modules and libraries:
  706.  
  707.   DBI
  708.   Net::MySQL
  709.  
  710. B<Net::MySQL> is a Pure Perl client interface for the MySQL database.
  711.  
  712. B<Net::MySQL> implements network protool between server and client of
  713. MySQL, thus you don't need external MySQL client library like
  714. libmysqlclient for this module to work. It means this module enables
  715. you to connect to MySQL server from some operation systems which MySQL
  716. is not ported. How nifty!
  717.  
  718. =head1 DIFFERENCE FROM "DBD::mysql"
  719.  
  720. The function of B<DBD::mysql> which cannot be used by B<DBD::mysqlPP> is described.
  721.  
  722. =head2 Parameter of Cnstructor
  723.  
  724. Cannot be used.
  725.  
  726. =over 4
  727.  
  728. =item * msql_configfile
  729.  
  730. =item * mysql_compression
  731.  
  732. =item * mysql_read_default_file/mysql_read_default_group
  733.  
  734. =item * mysql_socket
  735.  
  736. =back
  737.  
  738. =head2 Private MetaData Methods
  739.  
  740. These methods cannot be used for $drh.
  741.  
  742. =over 4
  743.  
  744. =item * ListDBs
  745.  
  746. =item * ListTables
  747.  
  748.  
  749. =back
  750.  
  751. =head2 Server Administration
  752.  
  753. All func() method cannot be used.
  754.  
  755. =over 4
  756.  
  757. =item * func('createdb')
  758.  
  759. =item * func('dropdb')
  760.  
  761. =item * func('shutdown')
  762.  
  763. =item * func('reload')
  764.  
  765. =back
  766.  
  767. =head2 Database Handles
  768.  
  769. Cannot be used
  770.  
  771. =over 4
  772.  
  773. =item * $dbh->{info}
  774.  
  775. =back
  776.  
  777. =head2 Statement Handles
  778.  
  779. A different part.
  780.  
  781. =over 4
  782.  
  783. =item * The return value of I<execute('SELECT * from table')>
  784.  
  785. Although B<DBD::mysql> makes a return value the number of searched records SQL of I<SELECT> is performed, B<DBD::mysqlPP> surely returns I<0E0>.
  786.  
  787. =back
  788.  
  789. Cannot be used.
  790.  
  791. =over 4
  792.  
  793. =item * 'mysql_use_result' attribute
  794.  
  795. =item * 'ChopBlanks' attribute
  796.  
  797. =item * 'is_blob' attribute
  798.  
  799. =item * 'is_key' attribute
  800.  
  801. =item * 'is_num' attribute
  802.  
  803. =item * 'is_pri_key' attribute
  804.  
  805. =item * 'is_not_null' attribute
  806.  
  807. =item * 'length'/'max_length' attribute
  808.  
  809. =item * 'NUUABLE' attribute
  810.  
  811. =item * 'table' attribute
  812.  
  813. =item * 'TYPE' attribute
  814.  
  815. =item * 'mysql_type' attribute
  816.  
  817. =item * 'mysql_type_name' attributei
  818.  
  819. =back
  820.  
  821. =head2 SQL Extensions
  822.  
  823. Cannot be used.
  824.  
  825. =over 4
  826.  
  827. =item * LISTFIELDS
  828.  
  829. =item * LISTINDEX
  830.  
  831. =back
  832.  
  833. =head1 TODO
  834.  
  835. Encryption of the password independent of I<Math::BigInt>.
  836.  
  837. Enables access to much metadata.
  838.  
  839. =head1 SEE ALSO
  840.  
  841. L<Net::MySQL>, L<DBD::mysql>
  842.  
  843. =head1 AUTHORS
  844.  
  845. Hiroyuki OYAMA E<lt>oyama@module.jpE<gt>
  846.  
  847. =head1 COPYRIGHT AND LICENCE
  848.  
  849. Copyright (C) 2002 Hiroyuki OYAMA. Japan. All rights reserved.
  850.  
  851. This library is free software; you can redistribute it and/or modify
  852. it under the same terms as Perl itself.
  853.  
  854. =cut
  855.