<?php
/**
 * @copyright (c) Kufer Software GmbH, Loisachstrasse 4, D-84453 Mühldorf
 */



class DBOperationMSSQL extends DBOperation
{
  
  public function __construct($connectionInfo, $pDBnr)
  {
    
    
    

    parent::__construct($connectionInfo, $pDBnr);
    
    ini_set('mssql.datetimeconvert', '0');
    
    
    
    $tmp = ini_get('mssql.textsize');
    if ($tmp == '' || ((int)$tmp < 16384)) {
      ini_set('mssql.textsize', '16384');
    }
    $tmp = ini_get('max_execution_time');
    if ($tmp == '' || ((int)$tmp <= 30)) {
      ini_set('max_execution_time', '60');
    }
  }

  
  public function connect_db($dbserver, $dbname, $dbuser, $dbpass)
  {
    
    $this->connection = @mssql_connect($dbserver, $dbuser, $dbpass) or $this->throwCriticalError("Die Verbindung zum MSSQL-Datenbankserver '" . $dbserver . "' konnte nicht hergestellt werden!");
    @mssql_select_db($dbname, $this->connection) or $this->throwCriticalError("Die Verbindung zur Datenbank '" . $dbname . "' konnte nicht hergestellt werden!");

    
    $this->execute('SET LANGUAGE deutsch;');
  }

  
  public function query($sql)
  {
    $this->openConnection();
    $this->resultset = @mssql_query($sql, $this->connection) or $this->throwCriticalError('Das SQL-Statement enthält Fehler!<br />', $sql);

    return true;
  }

  
  public function execute($sql)
  {
    $this->openConnection();
    @mssql_query($sql, $this->connection);
    
    return true;
  }

  
  public function rowcount()
  {
    if (isset($this->resultset)) {
      return mssql_num_rows($this->resultset);
    } else {
      return -1;
    }
  }

  
  public function selectrow($rownr)
  { 
    if ($rownr < $this->rowcount() && $rownr > -1) {
      if (mssql_data_seek($this->resultset, $rownr)) {
        $this->actualrow = $rownr;
        
        
        
        $this->currentRow = array_change_key_case(mssql_fetch_array($this->resultset), CASE_LOWER);
        mssql_data_seek($this->resultset, $rownr);

        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }

  
  public function fieldbyname($name)
  {
    $normalfieldname = StringOperations::strtolower($name);

    if (isset($this->currentRow[$normalfieldname])) {
      $value = $this->currentRow[$normalfieldname];
      
      if (StringOperations::substr($value, StringOperations::strlen($value) - 1, 1) == \StringOperations::chr_windows1252(32)) {
        $value = StringOperations::substr($value, 0, StringOperations::strlen($value) - 1);
      }
      
      
      return $value;
    } else {
      return '';
    } 
  }

  
  public function fieldExists($name)
  {
    $count = mssql_num_fields($this->resultset);
    for ($i = 0;$i < $count;$i++) {
      if (StringOperations::strtoupper($name) == StringOperations::strtoupper(mssql_field_name($this->resultset, $i))) {
        return true;
      }
    }

    return false;
  }

  
  public function getLastID($tablename)
  {
    $this->clear();
    $this->query('SELECT @@IDENTITY LID');
    $this->selectrow(0);

    return abs($this->fieldbyName('LID'));
  }

  
  public function getError()
  {
    return mssql_get_last_message() . '<br />';
  }

  
  public function getDBName()
  {
    return 'MSSQL';
  }

  public function beginTransaction()
  {
    $this->execute('BEGIN TRANSACTION;');
  }

  public function commitTransaction()
  {
    $this->execute('COMMIT TRANSACTION;');
  }

  
  public function rollbackTransaction()
  {
    $this->execute('ROLLBACK TRANSACTION;');
  }

  public function closeConnection()
  {
    @mssql_close($this->connection);
    $this->connection = false;
    Connections::CloseConnection($this->dbnr);
  }

  
  public function checkConnection($pCheckTables = true)
  {
    if (!function_exists('mssql_connect')) {
      return false;
    }
    $conInfo = DBConnectionInfo::getInstance();
    if ($this->dbnr == 1) {
      $dbserver = $conInfo->db_server;
      $dbname = $conInfo->db_name;
      $dbuser = $conInfo->db_user;
      $dbpass = $conInfo->db_password;
    } else {
      $dbserver = $conInfo->db2_server;
      $dbname = $conInfo->db2_name;
      $dbuser = $conInfo->db2_user;
      $dbpass = $conInfo->db2_password;
    }
    
    $connection = @mssql_connect($dbserver, $dbuser, $dbpass);

    
    if (!$connection) {
      return false;
    }
    
    @mssql_query('SET LANGUAGE deutsch;', $connection);

    
    if (!@mssql_select_db($dbname, $connection)) {
      return false;
    }

    if ($pCheckTables) {
      $res = @mssql_query('select top 1 id from aussenst', $connection);
      if (!$res) {
        return false;
      }

      $res = @mssql_query('select top 1 id from kategorien', $connection);
      if (!$res) {
        return false;
      }
    }

    
    
    $this->connect_db($dbserver, $dbname, $dbuser, $dbpass);

    return true;
  }

  public function getColumnsOfTable(string $table): array
  {
    $result = array();

    $this->clear();
    $this->query("SELECT name FROM sys.columns WHERE object_id = OBJECT_ID('dbo.$table')");
    for ($i = 0; $i < $this->rowcount(); ++$i) {
      $this->selectrow($i);
      $result[] = $this->fieldbyname('name');
    }

    return $result;
  }

  
  public function checkTableExists($pTableName, $pRefreshCache = false)
  {
    if (self::$_tableExistsCache == null) {
      self::$_tableExistsCache = array();
    }

    if (!$pRefreshCache && isset(self::$_tableExistsCache[$pTableName])) {
      return self::$_tableExistsCache[$pTableName];
    }

    $sql = 'SELECT * FROM [' . $this->connectionInfo->db_name . "].information_schema.TABLES WHERE table_name = '" . $pTableName . "'";
    $this->clear();
    $this->query($sql);
    self::$_tableExistsCache[$pTableName] = ($this->rowcount() == 1);

    return self::$_tableExistsCache[$pTableName];
  }
}