<?php
namespace nur\sery\db\sqlite;

use nur\sery\db\_private\_base;
use nur\sery\ValueException;
use SQLite3;
use SQLite3Stmt;

class _query_base extends _base {
  protected static function verifix(&$sql, ?array &$bindinds=null, ?array &$meta=null): void {
    if (is_array($sql)) {
      $prefix = $sql[0] ?? null;
      if ($prefix === null) {
        throw new ValueException("requête invalide");
      } elseif (_query_create::isa($prefix)) {
        $sql = _query_create::parse($sql, $bindinds);
      } elseif (_query_select::isa($prefix)) {
        $sql = _query_select::parse($sql, $bindinds);
      } elseif (_query_insert::isa($prefix)) {
        $sql = _query_insert::parse($sql, $bindinds);
      } elseif (_query_update::isa($prefix)) {
        $sql = _query_update::parse($sql, $bindinds);
      } elseif (_query_delete::isa($prefix)) {
        $sql = _query_delete::parse($sql, $bindinds);
      } elseif (_query_generic::isa($prefix)) {
        $sql = _query_generic::parse($sql, $bindinds);
      } else {
        throw SqliteException::wrap(ValueException::invalid_kind($sql, "query"));
      }
    } elseif (!is_string($sql)) {
      $sql = strval($sql);
    }
  }

  const DEBUG_QUERIES = false;

  function useStmt(SQLite3 $db, ?SQLite3Stmt &$stmt=null, ?string &$sql=null): bool {
    if (static::DEBUG_QUERIES) error_log($this->sql); #XXX
    if ($this->bindings !== null) {
      /** @var SQLite3Stmt $stmt */
      $stmt = SqliteException::check($db, $db->prepare($this->sql));
      $close = true;
      try {
        foreach ($this->bindings as $param => $value) {
          SqliteException::check($db, $stmt->bindValue($param, $value));
        }
        $close = false;
        return true;
      } finally {
        if ($close) $stmt->close();
      }
    } else {
      $sql = $this->sql;
      return false;
    }
  }
}
