# Copyright 1999-2012. Parallels IP Holdings GmbH. All Rights Reserved.
package Db::DbConnect;

use Db::Connection;
use Logging;
use XmlNode;
use CommonPacker;

sub getDbConnect {
  my ($myDbType, $myDbUser, $myDbPasswd, $myDbDB, $myDbHost,
      $continueAfterError, $myDbSocket, $variables, $utf, $port) = @_;

  my $connection;

  if ($myDbType eq 'Pg') {
    $myDbType = 'postgresql';
  }

  my %params;
  $params{'name'} = $myDbDB;
  $params{'user'} = $myDbUser;
  $params{'password'} = $myDbPasswd;
  $params{'host'} = $myDbHost if $myDbHost;
  $params{'socket'} = $myDbSocket if $myDbSocket;
  $params{'port'} = $port if $port;
  $params{'preload_dirs'} = $variables if $variables;
  $params{'type'} = $myDbType;

  $connection = Db::Connection::getConnection(%params);
  
  my $this = 0;
  
  if (ref($connection) =~ /Db::Connection/) {

    $this =
      {
       'DISCONNECT' => sub { return $connection->disconnect(@_); },
       'EXECUTE' => sub { return $connection->execute_rownum(@_); },
       'FETCHROW' => sub { return $connection->fetchrow(@_); },
       'FETCHHASH' => sub { return $connection->fetchhash(@_); },
       'FINISH' => sub { return $connection->finish(@_); },
       'PING' => sub { return $connection->ping(@_); },
       'USER' => sub { return $myDbUser; },
       'PASSWORD' => sub { return $myDbPasswd; },
       'HOST' => sub { return $myDbHost; },
       'CONNECTION' => $connection,
      };

  }
  
  return $this;
}

#
# end class for handle database
#
sub addDbUsers {
  my ($dbNode, $dbName, $wrapUserMysql, $allowedUsers) = @_;

  Logging::debug("Dumping $dbName database users");

  $dbName =~ s/_/\\_/g;

  my (@users, $dbUser, $ptrRow);
  my $sql = "SELECT DISTINCT User FROM db WHERE Db = '$dbName'";

  if ($wrapUserMysql->{'EXECUTE'}->($sql) == 0) { # bug 94641
    my $sql = "SELECT DISTINCT User FROM db WHERE Db LIKE '$dbName'";
    $wrapUserMysql->{'FINISH'}->();
    $wrapUserMysql->{'EXECUTE'}->($sql);
  }

  my @allowedUserList = defined $allowedUsers ? @$allowedUsers : ();
  while ($ptrRow = $wrapUserMysql->{'FETCHROW'}->()) {
    my $username = (@{$ptrRow})[0];
    if ((not defined $allowedUsers) or grep { $username eq $_ } @allowedUserList) {
        push @users, $username;
    }
  }
  $wrapUserMysql->{'FINISH'}->();

  foreach $dbUser (@users) {
    addDbUser($dbNode, $dbUser, $wrapUserMysql);
  }
}

sub addDbUser {
  my ($dbNode, $user, $wrapUserMysql, $passwordNode, $accessHosts) = @_;

  Logging::debug("Dumping mysql user '$user'");

  my ( $item );

  if ( ref( $wrapUserMysql ) =~ /HASH/ &&
       ref( $wrapUserMysql->{'EXECUTE'} ) =~ /CODE/ ) {

    my ($sql,$ptrRow,@accesshosts,$accesshost);

    $sql = "SELECT password,host FROM user WHERE user='$user'";

    if ( $wrapUserMysql->{'EXECUTE'}->( $sql ) ) {
      $item = XmlNode->new('dbuser', 'attributes' => {'name' => $user} );
      while ( $ptrRow = $wrapUserMysql->{'FETCHROW'}->() ) {
        unless ( ref($passwordNode) =~ /HASH/ ) {
          $passwordNode = CommonPacker::makePasswordNode( $ptrRow->[0] );
        }
        push @accesshosts, $ptrRow->[1];
      }

      if ( $passwordNode ) {
        $item->{'ADDCHILD'}->( $passwordNode );
      }

      if (defined($accessHosts) && ref($accessHosts) =~ /ARRAY/) {
        @accesshosts = @{$accessHosts};
      }

      foreach $accesshost ( @accesshosts ) {
        $item->{'ADDCHILD'}->( XmlNode->new( 'accesshost', 'content' => $accesshost ) );
      }

      my $dbsitem = XmlNode->new('db-server');
      $dbsitem->setAttribute('type', 'mysql');
      $dbsitem->addChild(XmlNode->new('host', 'content' => 'localhost'));
      $dbsitem->addChild(XmlNode->new('port', 'content' => 3306));
      $item->addChild($dbsitem);

      $dbNode->{'ADDCHILD'}->( $item );
    }

    $wrapUserMysql->{'FINISH'}->();
  }

  return $item;
}


1;
