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

#
# This package abstracts the common needs of the
# PostgresqlShellDbBackend and MysqlShellDbBackend: both packages need
# to process fetched result data.
#
# Subclasses must use _set_execute_result() method in their execute() methods.
# It accepts the reference to the array of references to the arrays of data
# $data->[0] must refer to the array of columns, and $data->[1] etc - to the arrays of data.
#

use strict;
use Db::Backend;

use vars qw|@ISA|;

@ISA = qw|Db::Backend|;

sub _init {
  my ($self, %params) = @_;

  $self->SUPER::_init(%params);

  $self->{type} = $params{type};
}

sub disconnect {
}

sub _set_execute_result {
  my ($self, $data) = @_;

  $self->{columns} = shift @{$data};
  $self->{res} = $data;
  $self->{index} = 0;
}

sub rownum {
  my ($self) = @_;
  return scalar(@{$self->{res}});
}

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

  return if $self->{index} >= @{$self->{res}};

  return $self->{res}->[$self->{index}++];
}

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

  my $row = $self->fetchrow();
  return if !$row;

  my $res = {};
  for (my $i = 0; $i < @{$self->{columns}}; ++$i) {
    $res->{$self->{columns}->[$i]} = $row->[$i];
  }

  return $res;
}

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

  delete $self->{columns};
  delete $self->{res};
  delete $self->{index};
}

# noop
sub ping {
  return 1;
}

sub _setDumpCmdline {
  my ($self, $dumpCmdline) = @_;
  $self->{dumpCmdline} = $dumpCmdline;
}

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

  return $self->{dumpCmdline};
}

sub _setFileToRemove {
  my ($self, $file) = @_;
  push @{$self->{fileToRemove}}, $file;
}

sub getFileToRemove {
  my ($self) = @_;
  return @{$self->{fileToRemove}} if defined $self->{fileToRemove};
}

sub _getSql {
  my ($self, $sql, @params) = @_;
  my $paramsCount = scalar(@params);
  my $placeholdersCount = 0;

  $sql =~ s/\?/$self->_getSqlParam(\@params, \$placeholdersCount)/ge;

  if ($paramsCount != $placeholdersCount) {
    return undef;
  }
  return $sql;
}

sub _getSqlParam {
  my ($self, $params, $count) = @_;

  ++${$count};
  if (!@{$params}) {
     return '?';
  }
  my $param = shift(@{$params});
  if (defined($param)) {
    $param =~ s/'/''/g;
    return $param;
  } else {
    return 'NULL';
  }
}

1;
