statement = $statement; } private static bool $constructed = false; private static string $resultImplementation; /** * Determines which MariaDBResult implementation should be used. * * @internal */ public static function construct(): void { if(self::$constructed !== false) throw new RuntimeException('Static constructor was already called.'); self::$constructed = true; self::$resultImplementation = function_exists('mysqli_stmt_get_result') ? MariaDBResultNative::class : MariaDBResultLib::class; } public function getParameterCount(): int { return $this->statement->param_count; } public function addParameter(int $ordinal, mixed $value, int $type = DbType::AUTO): void { if($ordinal < 1 || $ordinal > $this->getParameterCount()) throw new InvalidArgumentException('$ordinal is not a valid parameter number.'); $this->params[$ordinal - 1] = new MariaDBParameter($ordinal, $type, $value); } /** * Gets the last error code. * * @return int Last error code. */ public function getLastErrorCode(): int { return $this->statement->errno; } /** * Gets the last error string. * * @return string Last error string. */ public function getLastErrorString(): string { return $this->statement->error; } /** * Gets the current SQL State of this statement. * * @return string Current SQL State. */ public function getSQLState(): string { return $this->statement->sqlstate; } /** * Gets a list of errors from the last command. * * @return array List of last errors. */ public function getLastErrors(): array { return MariaDBWarning::fromLastErrors($this->statement->error_list); } /** * Gets list of warnings. * * The result of SHOW WARNINGS; * * @return array List of warnings. */ public function getWarnings(): array { return MariaDBWarning::fromGetWarnings($this->statement->get_warnings()); } public function getResult(): MariaDBResult { return new self::$resultImplementation($this->statement); } public function getLastInsertId(): int|string { return $this->statement->insert_id; } public function execute(): void { $args = ['']; foreach($this->params as $key => $param) { $args[0] .= $param->getBindType(); $type = $param->getDbType(); $value = $param->getValue(); if($type === DbType::NULL) $value = null; elseif($type === DbType::BLOB) { if($value instanceof Stream) { while(($data = $value->read(8192)) !== null) $this->statement->send_long_data($key, $data); } elseif(is_resource($value)) { while($data = fread($value, 8192)) $this->statement->send_long_data($key, $data); } else $this->statement->send_long_data($key, (string)$value); $value = null; } ${"value{$key}"} = $value; $args[] = &${"value{$key}"}; } if(!empty($args[0])) call_user_func_array([$this->statement, 'bind_param'], $args); if(!$this->statement->execute()) throw new QueryExecuteException($this->getLastErrorString(), $this->getLastErrorCode()); } public function reset(): void { $this->params = []; if(!$this->statement->reset()) throw new QueryExecuteException($this->getLastErrorString(), $this->getLastErrorCode()); } public function close(): void { $this->statement->close(); } public function __destruct() { $this->close(); } } MariaDBStatement::construct();