DBD-mysql

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

* Add Dockerfile (#390)
* More cleanups of unneeded ifdefs (#385)
* Enable auto reconnect for ER_CLIENT_INTERACTION_TIMEOUT
* Try out issue template for GitHub
* 99compression.t: Only test on 8.x
* Only use MYSQL_OPT_COMPRESSION_ALGORITHMS on >=8.0.18
* Replace `mysql_ssl_set()` with `mysql_options()`

2023-10-24 Daniël van Eeden, DBI/DBD community (5.002)
* Add support for compression algorighm selection (#372)
* Correct handling of mysql_enable_utf8mb4 (#363)
* tests: Remove have_transactions usage from 50commit.t
* Makefile: Clearly report that MySQL 8.x is needed and do some cleanup
* add DBD::mysql::client_version() to have the client version without DB connections
* Update version test for v5.x

2023-10-04 Daniël van Eeden, DBI/DBD community (5.001)
* Only support MySQL 8.x as MySQL 5.7 is going EOL soon
* Remove use of MYSQL_OPT_RECONNECT
* Remove option to disable SSL/TLS at compile time
* Only support MySQL 5.7 GA client libraries

Changes  view on Meta::CPAN

  Libraries in mysql_config --libs output can be specified by library name
  with the -l prefix or by absolute path to library name without any prefix.
  Parameters must start with a hyphen, so treat all options without leading
  hyphen in mysql_config --libs output as libraries with full path.
  Partially fixes bug https://rt.cpan.org/Public/Bug/Display.html?id=100898
  Fix by Pali Rohár.
* Fix support for magic scalars (pali)
   (https://github.com/perl5-dbi/DBD-mysql/pull/76)

2016-12-12 Patrick Galbraith, Michiel Beijen, DBI/DBD community (4.041_1)
* Unicode fixes: when using mysql_enable_utf8 or mysql_enable_utf8mb4,
  previous versions of DBD::mysql did not properly encode input statements
  to UTF-8 and retrieved columns were always UTF-8 decoded regardless of the
  column charset.
  Fix by Pali Rohár.
  Reported and feedback on fix by Marc Lehmann
  (https://rt.cpan.org/Public/Bug/Display.html?id=87428)
  Also, the UTF-8 flag was not set for decoded data:
  (https://rt.cpan.org/Public/Bug/Display.html?id=53130)
* Return INTs with ZEROFILL as strings. Reported by Knarf, fix by Pali Rohár.
  (https://rt.cpan.org/Public/Bug/Display.html?id=118977)

Changes  view on Meta::CPAN

2007-3-22 Patrick Galbraith <patg at patg dot net> Jim Winstead <jimw@mysql.com> (4.004)
* Work around a bug in old 3.23 servers by specifying NOT NULL for fields used
  as a primary key in tests. (Bug #20325, reported by Julian Ladisch)
* Add support for mysql_warning_count statement handle attribute. (Bug #25457,
  patch from Philip Stoev)
* Add support for mysql_multi_statements connection option. (RT #12322, based
  on patch from Doug Morris)
* Had to bump to 4.003 do to print statement in mysql.pm that made it
  into the dist. Even though you can delete a file on CPAN, you cannot
  re-upload it if it's the same name. Mea Culpa.
* UTF8-Flag not set with flag mysql_enable_utf8 and column collation utf8_bin patch,
  Joost Diepenmaat, (RT #24738)
* Fixed do_error definition (Scott Hildreth, Tim Bunce)
* Conversion of test suite to Test::More

2007-3-5 Patrick Galbraith <patg at patg dot net> Jim Winstead <jimw@mysql.com> (4.003)
* Fix inclusion of non-primary keys in primary_key_info. (Bug #26786,
  reported and patch by Dave Rolsky)

2007-3-1 Patrick Galbraith <patg at patg dot net> Jim Winstead <jimw@mysql.com> (4.002)
* Fix re-exec of Makefile.PL when forcing $ENV{LANG} to 'C'. (RT #25233,

dbdimp.c  view on Meta::CPAN

                        "imp_dbh->use_server_side_prepare: %d\n",
                        imp_dbh->use_server_side_prepare);

        if ((svp = hv_fetch(hv, "mysql_server_prepare_disable_fallback", 37, FALSE)) && *svp)
          imp_dbh->disable_fallback_for_server_prepare = SvTRUE(*svp);
        if (DBIc_TRACE_LEVEL(imp_xxh) >= 2)
          PerlIO_printf(DBIc_LOGPIO(imp_xxh),
                        "imp_dbh->disable_fallback_for_server_prepare: %d\n",
                        imp_dbh->disable_fallback_for_server_prepare);

        if ((svp = hv_fetch(hv, "mysql_enable_utf8mb4", 20, FALSE)) && *svp && SvTRUE(*svp)) {
          mysql_options(sock, MYSQL_SET_CHARSET_NAME, "utf8mb4");
          imp_dbh->enable_utf8mb4 = TRUE;
        }
        else if ((svp = hv_fetch(hv, "mysql_enable_utf8", 17, FALSE)) && *svp) {
          /* Do not touch imp_dbh->enable_utf8 as we are called earlier
           * than it is set and mysql_options() must be before:
           * mysql_real_connect()
          */
         mysql_options(sock, MYSQL_SET_CHARSET_NAME,
                       (SvTRUE(*svp) ? "utf8" : "latin1"));
         if (DBIc_TRACE_LEVEL(imp_xxh) >= 2)
           PerlIO_printf(DBIc_LOGPIO(imp_xxh),
                         "mysql_options: MYSQL_SET_CHARSET_NAME=%s\n",
                         (SvTRUE(*svp) ? "utf8" : "latin1"));

dbdimp.c  view on Meta::CPAN

		  password ? password : "NULL");

  imp_dbh->stats.auto_reconnects_ok= 0;
  imp_dbh->stats.auto_reconnects_failed= 0;
  imp_dbh->bind_type_guessing= FALSE;
  imp_dbh->bind_comment_placeholders= FALSE;
  imp_dbh->has_transactions= TRUE;
 /* Safer we flip this to TRUE perl side if we detect a mod_perl env. */
  imp_dbh->auto_reconnect = FALSE;

  imp_dbh->enable_utf8 = FALSE;     /* initialize mysql_enable_utf8 */
  imp_dbh->enable_utf8mb4 = FALSE;  /* initialize mysql_enable_utf8mb4 */

  if (!my_login(aTHX_ dbh, imp_dbh))
  {
    if(imp_dbh->pmysql) {
        do_error(dbh, mysql_errno(imp_dbh->pmysql),
                mysql_error(imp_dbh->pmysql) ,mysql_sqlstate(imp_dbh->pmysql));
        Safefree(imp_dbh->pmysql);

    }
    return FALSE;

dbdimp.c  view on Meta::CPAN

  else if (kl == 20 && strEQ(key, "mysql_server_prepare"))
    imp_dbh->use_server_side_prepare = bool_value;
  else if (kl == 37 && strEQ(key, "mysql_server_prepare_disable_fallback"))
    imp_dbh->disable_fallback_for_server_prepare = bool_value;
  else if (kl == 23 && strEQ(key,"mysql_no_autocommit_cmd"))
    imp_dbh->no_autocommit_cmd = bool_value;
  else if (kl == 24 && strEQ(key,"mysql_bind_type_guessing"))
    imp_dbh->bind_type_guessing = bool_value;
  else if (kl == 31 && strEQ(key,"mysql_bind_comment_placeholders"))
    imp_dbh->bind_type_guessing = bool_value;
  else if (kl == 17 && strEQ(key, "mysql_enable_utf8"))
    imp_dbh->enable_utf8 = bool_value;
  else if (kl == 20 && strEQ(key, "mysql_enable_utf8mb4"))
    imp_dbh->enable_utf8mb4 = bool_value;
  else
    return FALSE;				/* Unknown key */

  if (cacheit) /* cache value for later DBI 'quick' fetch? */
    (void)hv_store((HV*)SvRV(dbh), key, kl, cachesv, 0);
  return TRUE;
}

/***************************************************************************

lib/DBD/mysql.pm  view on Meta::CPAN


You can also set it after creation of the database handle:

   $dbh->{mysql_use_result} = 0; # disable
   $dbh->{mysql_use_result} = 1; # enable

You can also set or unset the C<mysql_use_result> setting on your statement
handle, when creating the statement handle or after it has been created.
See L</"STATEMENT HANDLES">.

=item mysql_enable_utf8

This attribute determines whether DBD::mysql should assume strings
stored in the database are utf8.  This feature defaults to off.

When set, a data retrieved from a textual column type (char, varchar,
etc) will have the UTF-8 flag turned on if necessary.  This enables
character semantics on that string.  You will also need to ensure that
your database / table / column is configured to use UTF8. See for more
information the chapter on character set support in the MySQL manual:
L<http://dev.mysql.com/doc/refman/8.0/en/charset.html>

lib/DBD/mysql.pm  view on Meta::CPAN

as text data by calling the C<utf8::downgrade()> function (it dies on wide
Unicode strings with codepoints above U+FF).  See the following example:

  # check that last name contains LATIN CAPITAL LETTER O WITH STROKE (U+D8)
  my $statement = "SELECT * FROM users WHERE last_name LIKE '%\x{D8}%' AND first_name = ? AND data = ?";

  my $wide_string_param = "Andr\x{E9}"; # Andre with LATIN SMALL LETTER E WITH ACUTE (U+E9)

  my $byte_param = "\x{D8}\x{A0}\x{39}\x{F8}"; # some bytes (binary data)

  my $dbh = DBI->connect('DBI:mysql:database', 'username', 'pass', { mysql_enable_utf8mb4 => 1 });

  utf8::upgrade($statement); # UTF-8 fix for DBD::mysql
  my $sth = $dbh->prepare($statement);

  utf8::upgrade($wide_string_param); # UTF-8 fix for DBD::mysql
  $sth->bind_param(1, $wide_string_param);

  utf8::downgrade($byte_param); # byte fix for DBD::mysql
  $sth->bind_param(2, $byte_param, DBI::SQL_BINARY); # set correct binary type

  $sth->execute();

  my $output = $sth->fetchall_arrayref();
  # returned data in $output reference should be already UTF-8 decoded as appropriate

=item mysql_enable_utf8mb4

This is similar to mysql_enable_utf8, but is capable of handling 4-byte
UTF-8 characters.

=item mysql_bind_type_guessing

This attribute causes the driver (emulated prepare statements)
to attempt to guess if a value being bound is a numeric value,
and if so, doesn't quote the value.  This was created by
Dragonchild and is one way to deal with the performance issue
of using quotes in a statement that is inserting or updating a
large numeric value. This was previously called

t/55utf8.t  view on Meta::CPAN

my $utf8_str        = "\x{0100}dam";     # "Adam" with a macron.
my $quoted_utf8_str = "'\x{0100}dam'";

my $blob = "\x{c4}\x{80}dam"; # same as utf8_str but not utf8 encoded
my $quoted_blob = "'\x{c4}\x{80}dam'";

cmp_ok $dbh->quote($utf8_str), 'eq', $quoted_utf8_str, 'testing quoting of utf 8 string';

cmp_ok $dbh->quote($blob), 'eq', $quoted_blob, 'testing quoting of blob';

#ok $dbh->{mysql_enable_utf8}, "mysql_enable_utf8 survive connect()";
$dbh->{mysql_enable_utf8}=1;

# GeomFromText() is deprecated as of MySQL 5.7.6, use ST_GeomFromText() instead
my $geomfromtext = $dbh->{mysql_serverversion} >= 50706 ? 'ST_GeomFromText' : 'GeomFromText';
my $query = <<EOI;
INSERT INTO dbd_mysql_t55utf8 (name, bincol, shape, binutf, profile)
    VALUES (?, ?, $geomfromtext('Point(132865 501937)'), ?, ?)
EOI

ok $dbh->do($query, {}, $utf8_str, $blob, $utf8_str, $utf8_str), "INSERT query $query\n";

t/55utf8_errors.t  view on Meta::CPAN

if ($@) {
    plan skip_all => "no database connection";
}
$dbh->disconnect();

plan tests => 10 * 3;

# All in internal Perl Unicode
my $jpnErr = qr/\x{4ed8}\x{8fd1}.*\x{884c}\x{76ee}/; # Use \x{...} instead \N{U+...} due to Perl 5.12.0 bug

foreach my $mysql_enable_utf8 (0, 1, 2) {
    my %utf8_params = ();
    if ($mysql_enable_utf8 == 1) {
        $utf8_params{'mysql_enable_utf8'} = 1;
        diag "Enabled mysql_enable_utf8.";
    # XXX There are no utf8mb4 error characters
    } elsif ($mysql_enable_utf8 == 2) {
        $utf8_params{'mysql_enable_utf8mb4'} = 1;
        diag "Enabled mysql_enable_utf8mb4.";
    } else {
        diag "Disabled mysql_enable_utf8.";
    }
    $dbh = DBI->connect($test_dsn, $test_user, $test_password,
                       { RaiseError => 1, PrintError => 1, AutoCommit => 1, %utf8_params });

    eval {
        $dbh->do("SET lc_messages = 'ja_JP'");
    } or do {
        $dbh->disconnect();
        plan skip_all => "Server lc_messages ja_JP are needed for this test";
    };

t/55utf8_identifiers.t  view on Meta::CPAN


use Test::More;
use DBI;
use Encode;

use vars qw($test_dsn $test_user $test_password);
use lib 't', '.';
require "lib.pl";

sub for_db {
    my ($mysql_enable_utf8, $value) = @_; # Value is in internal Perl Unicode.

    my $ret;
    if ($mysql_enable_utf8 >= 1) {
        $ret = $value;
    } else {
        $ret = Encode::encode('UTF-8', $value);
    }

    return $ret;
}

my $dbh;
eval {

t/55utf8_identifiers.t  view on Meta::CPAN

# All in internal Perl Unicode
my $jpnTable = "\N{U+8868}"; # Japanese table
my $jpnColumn = "\N{U+6027}\N{U+5225}"; # Japanese column - word "gender"
my $jpnData1 = "\N{U+5c71}\N{U+7530}\N{U+592a}\N{U+90ce}"; # Japanese data - person name
my $jpnData2 = "\N{U+7537}"; # Japanese daya - word "male"
my $chiTable = "\N{U+5927}\N{U+99AC}"; # Chinese table XXX MySQL doesn't support utf8mb4 in table names
my $chiColumn = "\N{U+5C0F}\N{U+96EA}\N{U+4EBA}"; # Chinese column XXX MySQL doesn't support utf8mb4 in column names
my $chiData1 = "\N{U+30001}"; # Chinese data
my $chiData2 = "\N{U+30002}"; # Chinese data

foreach my $mysql_enable_utf8 (0, 1, 2) {
    my %utf8_params = ();
    if ($mysql_enable_utf8 == 1) {
        $utf8_params{'mysql_enable_utf8'} = 1;
        diag "Enabled mysql_enable_utf8.";
    } elsif ($mysql_enable_utf8 == 2) {
        $utf8_params{'mysql_enable_utf8mb4'} = 1;
        diag "Enabled mysql_enable_utf8mb4.";
    } else {
        diag "Disabled mysql_enable_utf8.";
    }
    $dbh = DBI->connect($test_dsn, $test_user, $test_password,
                       { RaiseError => 1, PrintError => 1, AutoCommit => 1, %utf8_params });

    my $jpnTable_db = for_db($mysql_enable_utf8, $jpnTable);
    my $jpnColumn_db = for_db($mysql_enable_utf8, $jpnColumn);
    my $jpnData1_db = for_db($mysql_enable_utf8, $jpnData1);
    my $jpnData2_db = for_db($mysql_enable_utf8, $jpnData2);
    my ($chiTable_db, $chiColumn_db, $chiData1_db, $chiData2_db);
    if ($mysql_enable_utf8 == 0 || $mysql_enable_utf8 == 2) {
        $chiTable_db = for_db($mysql_enable_utf8, $chiTable);
        $chiColumn_db = for_db($mysql_enable_utf8, $chiColumn);
        $chiData1_db = for_db($mysql_enable_utf8, $chiData1);
        $chiData2_db = for_db($mysql_enable_utf8, $chiData2);
    }

    my $sth;
    my $row;

    ok($dbh->do("DROP TABLE IF EXISTS $jpnTable_db"), 'Drop table for Japanese testing.');
    if ($mysql_enable_utf8 == 0 || $mysql_enable_utf8 == 2) {
        ok($dbh->do("DROP TABLE IF EXISTS $chiTable_db"), 'Drop table for Chinese testings.');
    }

    ok($dbh->do(<<"END"
CREATE TABLE IF NOT EXISTS $jpnTable_db (
  name VARCHAR(20),
  $jpnColumn_db CHAR(1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin
END
    ), 'Create temporay table with Japanese characters.');
    if ($mysql_enable_utf8 == 0 || $mysql_enable_utf8 == 2) {
      ok($dbh->do(<<"END"
CREATE TABLE IF NOT EXISTS $chiTable_db (
  name VARCHAR(20),
  $chiColumn_db CHAR(1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin
END
      ), 'Create temporay table with Chinese characters.');
    }

    ok($sth = $dbh->prepare("INSERT INTO $jpnTable_db (name, $jpnColumn_db) VALUES (?, ?)"), 'Prepare insert statement with Japanese values.');
    ok($sth->execute($jpnData1_db, $jpnData2_db), 'Execute insert statement with Japanese values.');
    if ($mysql_enable_utf8 == 0 || $mysql_enable_utf8 == 2) {
        ok($sth = $dbh->prepare("INSERT INTO $chiTable_db (name, $chiColumn_db) VALUES (?, ?)"), 'Prepare insert statement with Chinese values.');
        ok($sth->execute($chiData1_db, $chiData2_db), 'Execute insert statement with Chinese values.');
    }

    ok($sth = $dbh->prepare("SELECT * FROM $jpnTable_db"), 'Prepare select statement with Japanese values.');
    ok($sth->execute(), 'Execute select statement with Japanese values.');
    ok($row = $sth->fetchrow_hashref(), 'Fetch hashref with Japanese values.');
    is($row->{name}, $jpnData1_db, "Japanese value.");
    ok(!exists $row->{$jpnColumn}, 'Not exists Japanese key in internal Perl Unicode.'); # XXX
    is($row->{Encode::encode('UTF-8', $jpnColumn)}, $jpnData2_db, 'Exists Japanese key in octets and value.'); # XXX
    is_deeply($sth->{NAME}, [ 'name', Encode::encode('UTF-8', $jpnColumn) ], 'Statement Japanese column name is in octets.'); # XXX
    is_deeply($sth->{mysql_table}, [ Encode::encode('UTF-8', $jpnTable), Encode::encode('UTF-8', $jpnTable) ], 'Statement Japanese table name is in octets.'); # XXX
    if ($mysql_enable_utf8 == 0 || $mysql_enable_utf8 == 2) {
        ok($sth = $dbh->prepare("SELECT * FROM $chiTable_db"), 'Prepare select statement with Chinese values.');
        ok($sth->execute(), 'Execute select statement with Chinese values.');
        ok($row = $sth->fetchrow_hashref(), 'Fetch hashref with Chinese values.');
        is($row->{name}, $chiData1_db, "Chinese value.");
        ok(!exists $row->{$chiColumn}, 'Not exists Chinese key in internal Perl Unicode.'); # XXX
        is($row->{Encode::encode('UTF-8', $chiColumn)}, $chiData2_db, 'Exists Chinese key in octets and value.'); # XXX
        is_deeply($sth->{NAME}, [ 'name', Encode::encode('UTF-8', $chiColumn) ], 'Statement Chinese column name is in octets.'); # XXX
        is_deeply($sth->{mysql_table}, [ Encode::encode('UTF-8', $chiTable), Encode::encode('UTF-8', $chiTable) ], 'Statement Chinese table name is in octets.'); # XXX
    }

t/gh360.t  view on Meta::CPAN

use Test::More;
use DBI;
use lib 't', '.';
require 'lib.pl';

# https://github.com/perl5-dbi/DBD-mysql/issues/360

my ($dbhA, $dbhB);
use vars qw($test_dsn $test_user $test_password);

my $dsnA = $test_dsn . ';mysql_enable_utf8mb4=1';
eval {$dbhA = DBI->connect($dsnA, $test_user, $test_password,
    { RaiseError => 1, AutoCommit => 1});};

if ($@) {
  diag $@;
  plan skip_all => "no database connection";
}

my $dsnB = $test_dsn;
$dsnB =~ s/DBI:mysql/DBI:mysql(mysql_enable_utf8mb4=1)/;
eval {$dbhB = DBI->connect($dsnB . ';mysql_enable_utf8mb4=1', $test_user, $test_password,
    { RaiseError => 1, AutoCommit => 1});};

plan tests => 2;

ok($dbhA->{mysql_enable_utf8mb4} == 1, 'mysql_enable_utf8mb4 == 1 with regular DSN');

ok($dbhB->{mysql_enable_utf8mb4} == 1, 'mysql_enable_utf8mb4 == 1 with driver DSN');



( run in 0.426 second using v1.01-cache-2.11-cpan-00829025b61 )