<?php
/**
 * @copyright (c) Kufer Software GmbH, Oderstraße 7, D-84453 Mühldorf
 */


abstract class DBWorkGenerated extends DBWork
{
  
  protected $_dataModulFields;

  
  public function getCurrentRow($pRefreshCache = false)
  {
    $tmp = $this->getNewObject();

    return $this->load($tmp);
  }

  
  public function load($pDm)
  {
    foreach ($this->_dataModulFields as $varName) {
      $pDm->{$varName} = $this->getDatamodulValue($varName, $this->translateVarName($varName));
    }

    return $pDm;
  }

  
  public function getAll(): array
  {
    $sql = "SELECT $this->select FROM " . $this->getTableName();
    $where = $this->getSearchSQL('');
    if ($where != '') {
      $where = trim($where);
      if (StringOperations::startsWith($where, 'and ', false)) {
        $sql .= ' WHERE ' . StringOperations::substr($where, 4);
      } elseif (StringOperations::startsWith($where, 'or ', false)) {
        $sql .= ' WHERE ' . StringOperations::substr($where, 3);
      }
    }
    if ($this->orderby != '') {
      $sql .= $this->getCompleteOrderByDefault($this->orderby);
    }
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getAllRows();
  }

  private function getQueryBuilderForGetOne($pId, $pIdFieldName): \SelectQueryBuilder
  {
    $queryBuilder = $this->getSelectQueryBuilder();
    $queryBuilder->select($this->select)
            ->from($this->getTableName())
            ->where(':idFieldName: = :id:')
            ->paramFieldname('idFieldName', $pIdFieldName)
            ->paramInt('id', $pId);

    return $queryBuilder;
  }

  public function getOne($pId, $pIdFieldName = 'id', $pPrefix = '', $pRefreshCache = false)
  {
    $queryBuilder = $this->getQueryBuilderForGetOne($pId, $pIdFieldName);
    $queryBuilder->addToWhere($this->getSearchSQL($pPrefix));

    return $this->queryGetFirstRow($queryBuilder->getSQL(), $pRefreshCache);
  }

  public function getOneOrNull($pId, $pIdFieldName = 'id', $pPrefix = '', $pRefreshCache = false)
  {
    $queryBuilder = $this->getQueryBuilderForGetOne($pId, $pIdFieldName);
    $queryBuilder->addToWhere($this->getSearchSQL($pPrefix));

    return $this->queryGetFirstRowOrNull($queryBuilder->getSQL(), $pRefreshCache);
  }

  public function getOneNoFilter($pId, $pIdFieldName = 'id', $pRefreshCache = false)
  {
    $queryBuilder = $this->getQueryBuilderForGetOne($pId, $pIdFieldName);

    return $this->queryGetFirstRow($queryBuilder->getSQL(), $pRefreshCache);
  }

  public function queryGetFirstRow($sql, $pRefreshCache = false)
  {
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getFirstRow($pRefreshCache);
  }

  public function queryGetFirstRowOrNull($sql, $pRefreshCache = false)
  {
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getFirstRowOrNull($pRefreshCache);
  }

  
  public function getSome($pIdAry, string $pIdFieldName = 'id', string $pPrefix = '', bool $pRefreshCache = false): array
  {
    if (!is_array($pIdAry) || count($pIdAry) === 0) {
      return array();
    }

    $sql = $this->getSomeQuery($pIdAry, $pIdFieldName, $pPrefix, false);
    $this->dboperation->clear();
    $this->dboperation->query($sql);
    $dbResult = $this->getAllRows($pRefreshCache);
    $hasNotKeyNr = $pIdFieldName === 'nr' && !\ArrayOperations::any($dbResult, static function(object $obj): bool {
      return isset($obj->{'nr'});
    });

    
    if ($hasNotKeyNr) {
      $dbResultById = \ArrayOperations::setAttributAsKey($dbResult, 'id');
    } else {
      $dbResultById = \ArrayOperations::setAttributAsKey($dbResult, $pIdFieldName);
    }
    $orderedResult = array();
    foreach ($pIdAry as $id) {
      if (isset($dbResultById[$id])) {
        $orderedResult[] = $dbResultById[$id];
      }
    }

    return $orderedResult;
  }

  
  public function getSomeWithOrderBy($pIdAry, string $pIdFieldName = 'id', string $pPrefix = '', bool $pRefreshCache = false): array
  {
    if (!is_array($pIdAry) || count($pIdAry) === 0) {
      return array();
    }

    $sql = $this->getSomeQuery($pIdAry, $pIdFieldName, $pPrefix, true);
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getAllRows($pRefreshCache);
  }

  
  protected function getSomeQuery(array $pIdAry, string $pIdFieldName, string $pPrefix, bool $pWithOrderBy): string
  {
    $cleanIds = $this->dboperation->getInts4Sql($pIdAry);
    $idFieldName = $this->dboperation->getString4Sql($pIdFieldName);

    $sql = $this->getStdSelect() . $this->getStdFrom()
      . ' WHERE ' . $idFieldName
      . ' IN (' . \StringOperations::convertArray2InList($cleanIds) . ')'
      . $this->getSearchSQL($pPrefix);

    if ($pWithOrderBy && $this->orderby != '') {
      $sql .= $this->getCompleteOrderByDefault($this->orderby);
    }

    return $sql;
  }

  
  public function getSomeBySearch(): array
  {
    $sql = "SELECT $this->select FROM " . $this->getTableName();
    $where = $this->getSearchSQL('');
    if ($where != '') {
      $sql .= ' WHERE ' . StringOperations::substr($where, 4);
    }
    if ($this->orderby != '') {
      $sql .= $this->getCompleteOrderByDefault($this->orderby);
    }
    $this->dboperation->clear();
    $this->dboperation->query($sql);

    return $this->getAllRows();
  }

  protected function getStdSelect(): string
  {
    return 'SELECT ' . $this->select;
  }

  public function getStdFrom(): string
  {
    return ' FROM ' . $this->getTableName();
  }

  
  public function insertOne($pDatamodul, $pDummyField, string $pIdFieldName = 'id', bool $pDontProtocol = false, bool $pDmzBetrieb = false): int
  {
    $pDatamodul->id = $this->insertRecord($this->getTableName(), $pIdFieldName, $pDummyField, false);
    if (!$pDontProtocol) {
      $this->saveChanging($this->getTableName(), '', '', $pDatamodul->id, 'id', 'I', $pDmzBetrieb);
    }
    $orgDatamodul = $this->getOneNoFilter($pDatamodul->id);
    $this->updateObject($pDatamodul, $orgDatamodul, $this->getTableName(), $pIdFieldName, 'A', $pDontProtocol, $pDmzBetrieb);
    $this->setActionIDs();

    return $pDatamodul->id;
  }

  
  public function deleteOne(int $pId, string $pIdFieldName = 'id', bool $pDontProtocol = false, bool $pDmzBetrieb = false): void
  {
    $id = $this->dboperation->getInt4Sql($pId);
    $idFieldName = $this->dboperation->getString4Sql($pIdFieldName);
    $sql = 'DELETE FROM ' . $this->getTableName() . ' WHERE ' . $idFieldName . '=' . $id;
    $this->dboperation->clear();
    $this->dboperation->execute($sql);
    if (!$pDontProtocol) {
      $this->saveChanging($this->getTableName(), '', '', "'" . $pId . "'", '', 'D', $pDmzBetrieb);
    }
    $this->setActionIDs();
  }
}