nur-sery/nur_src/m/pdo/PdoRowIterator.php

94 lines
2.3 KiB
PHP
Raw Normal View History

2023-12-03 22:10:18 +04:00
<?php
namespace nur\m\pdo;
use nur\func;
use nur\m\base\AbstractRowIterator;
use nur\m\IRowIncarnation;
use PDO;
use PDOStatement;
class PdoRowIterator extends AbstractRowIterator {
/** @var PdoConn */
protected $conn;
/** @var string|null */
protected $sql;
/** @var IRowIncarnation|null */
protected $incarnation;
/**
* @var PDOStatement instance de PDOStatement permettant de récupérer les
* lignes résultat
*/
protected $stmt;
/**
* @var callable|null fonction permettant de (re)créer $stmt. par défaut,
* $stmt est créé à partir de $sql et $bindings
*/
protected $createStmtFunc;
function __construct(PdoConn $conn, ?string $sql=null, ?array &$bindings=null, ?IRowIncarnation $incarnation=null) {
parent::__construct();
$this->conn = $conn;
$this->reset($sql, $bindings, $incarnation);
}
function reset(?string $sql, ?array &$bindings=null, ?IRowIncarnation $incarnation=null): self {
if ($bindings === null) $bindings = [];
$this->sql = $sql;
$this->data =& $bindings;
$this->incarnation = $incarnation;
return $this;
}
function initStmt(?PDOStatement $stmt=null, ?callable $createStmtFunc=null): self {
$this->stmt = $stmt;
$this->createStmtFunc = $createStmtFunc;
return $this;
}
/** créer une instance de PDOStatement */
protected function createStmt(): PDOStatement {
$createStmtFunc = $this->createStmtFunc;
if ($createStmtFunc !== null) {
return func::call($createStmtFunc, $this->conn);
} else {
["stmt" => $stmt
] = $this->conn->_execute($this->sql, $this->data, ["stmt" => true]);
return $stmt;
}
}
protected function _setup(): void {
if ($this->stmt === null) {
$incarnation = $this->incarnation;
if ($incarnation !== null) {
$incarnation->prepareBindings($this->data);
}
$this->stmt = $this->createStmt();
}
}
protected function _next() {
return $this->stmt->fetch(PDO::FETCH_ASSOC);
}
protected function _cook(&$row, &$key): void {
if ($this->incarnation !== null) {
$this->incarnation->loadRow($row, $key);
}
}
protected function _teardown(): void {
if ($this->stmt !== null) {
$this->stmt->closeCursor();
$this->stmt = null;
}
}
function key() { return $this->_key(); }
function current() { return $this->_current(); }
}