# Copyright 1999-2012. 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};
  return $address;
}

sub connect {
  my ($self) = @_;

  my $retry = 0;
  while (!$self->SUPER::connect()) {
    return if ($self->errcode() != 1040 # Too many connections
      || ++$retry > $self->{connRetries});
    sleep 1;
  }

  if ($self->{utf8names} && Db::MysqlUtils::doesSupportCharacterSets($self)) {
    $self->execute(Db::MysqlUtils::getCharacterSetsSupportSql());
    $self->execute(Db::MysqlUtils::getNamesCharacterSetsSupportSql());
  }

  return 1;
}

sub execute {
  my ($self, $sql) = @_;

  $self->{result} = $self->{dbh}->prepare($sql);
  if (!$self->{result}) {
    Logging::error("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();
  if (!defined $res && $DBI::err != 2006) {
    Logging::error("Unable to execute SQL: $DBI::errstr");
    $self->_set_errstr("Unable to execute SQL: $DBI::errstr");
    return;
  }

  return $res if $res;

  #
  # Reconnect on timeout
  #
  Logging::debug("Timeout occured during mysql query. Reconnecting.");
  $self->{dbh}->disconnect();
  die if !$self->connect();

  return $self->SUPER::execute($sql);
}

1;
