# Copyright 1999-2016. Parallels IP Holdings GmbH. All Rights Reserved. package Db::MysqlDbiBackend; use strict; use Db::DbiBackend; use Db::MysqlUtils; use vars qw|@ISA|; @ISA = qw|Db::DbiBackend|; # # 'name', 'user', 'password'[, 'host'][, 'socket'][, 'port'][, 'utf8names'] # sub _init { my ($self, %params) = @_; $self->SUPER::_init(%params, 'type'=>'mysql'); if (defined $params{host} and defined $params{socket}) { return "socket & host are mutually exclusive"; } $self->{socket} = $params{socket} if defined $params{socket}; $self->{port} = $params{port} if defined $params{port}; $self->{utf8names} = $params{utf8names} if defined $params{utf8names}; $self->{connRetries} = (defined $params{connRetries}) ? $params{connRetries} : 0; } sub _composeDbiAddress { my ($self) = @_; my $address = $self->SUPER::_composeDbiAddress(); $address .= ";mysql_socket=$self->{socket}" if defined $self->{socket}; $address .= ";port=$self->{port}" if defined $self->{port}; # $address .= ';mysql_server_prepare=1'; # do not turn on prepared statements because of issues in perl-DBD-MySQL (https://rt.cpan.org/Public/Bug/Display.html?id=75570, https://rt.cpan.org/Public/Bug/Display.html?id=80394) return $address; } sub connect { my ($self) = @_; my $retry = 0; while (!$self->SUPER::connect()) { return if (++$retry > $self->{connRetries}); sleep 1; Logging::debug("Connection to mysql database failed. Try again..."); } if ($self->{utf8names} && Db::MysqlUtils::doesSupportCharacterSets($self)) { $self->execute(Db::MysqlUtils::getCharacterSetsSupportSql()); $self->execute(Db::MysqlUtils::getNamesCharacterSetsSupportSql()); } return 1; } sub _execute { my ($self, $sql, $quiet, @params) = @_; die($self->{errstr}) if !$self->{dbh}; $self->{result} = $self->{dbh}->prepare($self->_getSqlTemplate($sql)); if (!$self->{result}) { Logging::warning("Unable to prepare SQL for execution: $DBI::errstr"); $self->_set_errstr("Unable to prepare SQL ( for execution: $DBI::errstr"); return; } my $res = $self->{result}->execute(@params); if (!defined $res && $DBI::err != 2006) { Logging::warning("Unable to execute SQL: $DBI::errstr. SQL query: $sql"); $self->_set_errstr("Unable to execute SQL: $DBI::errstr"); return; } return $res; } sub execute { my ($self, $sql, $quiet, @params) = @_; my $res = $self->_execute($sql, $quiet, @params); return $res if $res; # # Reconnect on timeout # Logging::debug("Timeout occurred during mysql query execution. Reconnecting."); $self->{dbh}->disconnect(); die($self->{errstr}) if !$self->connect(); return $self->_execute($sql, $quiet, @params); } 1;