<?php namespace nur\m\pgsql; use nur\b\IllegalAccessException; use nur\m\base\OneRowIterator; use nur\m\base\Query; use nur\m\IQuery; use nur\m\IRowIncarnation; use nur\m\IRowIterator; class PgsqlQuery extends Query { /** @var PgsqlConn */ protected $conn; protected function newRowIncarnation(): IRowIncarnation { return new PgsqlRowIncarnation(); } protected function newRowIterator(?string $sql, ?array &$bindings=null, ?IRowIncarnation $incarnation=null): IRowIterator { return new PgsqlRowIterator($this->conn, $sql, $bindings, $incarnation); } function __construct(PgsqlConn $conn, ?string $sql=null, ?array $filter=null, ?IRowIncarnation $incarnation=null) { $this->conn = $conn; if ($incarnation === null) $incarnation = $this->newRowIncarnation(); $this->setIncarnation($incarnation); $this->select($sql, $filter); } protected function _execute(bool $commit): IRowIterator { $sql = $this->validateFilter(); if ($sql === null) $sql = $this->sql; $incarnation = $this->incarnation; switch ($this->type) { case self::TYPE_SELECT: $incarnation->createBindings($bindings, $this->filter); return $this->newRowIterator($sql, $bindings, $incarnation); case self::TYPE_UPDATE; $incarnation->createBindings($bindings, $this->filter, $this->row, $this->results); $incarnation->prepareBindings($bindings); ["num_rows" => $numRows ] = $this->conn->_execute($sql, $bindings, PgsqlConn::EXECUTE_PARAMS_DML_UPDATE); $incarnation->loadResults($this->results, $bindings); if ($commit) $this->commit(); return new OneRowIterator([ "num_rows" => $numRows, ]); case self::TYPE_INSERT: $incarnation->createBindings($bindings, $this->filter, $this->row, $this->results); $incarnation->prepareBindings($bindings); ["insert_id" => $insertId ] = $this->conn->_execute($sql, $bindings, PgsqlConn::EXECUTE_PARAMS_DML_INSERT); $incarnation->loadResults($this->results, $bindings); if ($commit) $this->commit(); return new OneRowIterator([ "insert_id" => $insertId, ]); default: throw IllegalAccessException::unexpected_state(); } } function beginTransaction(): IQuery { $this->conn->beginTransaction(); return $this; } function commit(): IQuery { $this->conn->commit(); return $this; } function rollback(): IQuery { $this->conn->rollback(); return $this; } const SELECT_TABLE_NAME = <<<EOT select to_regclass(:name) as name EOT; function tableExists(string $tableName): bool { return $this->select(self::SELECT_TABLE_NAME, [ "name" => $tableName, ])->firstVal("name") !== null; } }