From bf6655a534a6775d30cafa67bd801276bda1d98d Mon Sep 17 00:00:00 2001 From: polo Date: Tue, 13 Aug 2024 23:45:21 +0200 Subject: =?UTF-8?q?VERSION=200.2=20doctrine=20ORM=20et=20entit=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/doctrine/dbal/src/Driver/Mysqli/Result.php | 164 ++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 vendor/doctrine/dbal/src/Driver/Mysqli/Result.php (limited to 'vendor/doctrine/dbal/src/Driver/Mysqli/Result.php') diff --git a/vendor/doctrine/dbal/src/Driver/Mysqli/Result.php b/vendor/doctrine/dbal/src/Driver/Mysqli/Result.php new file mode 100644 index 0000000..8d3c47a --- /dev/null +++ b/vendor/doctrine/dbal/src/Driver/Mysqli/Result.php @@ -0,0 +1,164 @@ + + */ + private readonly array $columnNames; + + /** @var mixed[] */ + private array $boundValues = []; + + /** + * @internal The result can be only instantiated by its driver connection or statement. + * + * @throws Exception + */ + public function __construct(private readonly mysqli_stmt $statement) + { + $meta = $statement->result_metadata(); + $this->hasColumns = $meta !== false; + $this->columnNames = $meta !== false ? array_column($meta->fetch_fields(), 'name') : []; + + if ($meta === false) { + return; + } + + $meta->free(); + + // Store result of every execution which has it. Otherwise it will be impossible + // to execute a new statement in case if the previous one has non-fetched rows + // @link http://dev.mysql.com/doc/refman/5.7/en/commands-out-of-sync.html + $this->statement->store_result(); + + // Bind row values _after_ storing the result. Otherwise, if mysqli is compiled with libmysql, + // it will have to allocate as much memory as it may be needed for the given column type + // (e.g. for a LONGBLOB column it's 4 gigabytes) + // @link https://bugs.php.net/bug.php?id=51386#1270673122 + // + // Make sure that the values are bound after each execution. Otherwise, if free() has been + // previously called on the result, the values are unbound making the statement unusable. + // + // It's also important that row values are bound after _each_ call to store_result(). Otherwise, + // if mysqli is compiled with libmysql, subsequently fetched string values will get truncated + // to the length of the ones fetched during the previous execution. + $this->boundValues = array_fill(0, count($this->columnNames), null); + + // The following is necessary as PHP cannot handle references to properties properly + $refs = &$this->boundValues; + + if (! $this->statement->bind_result(...$refs)) { + throw StatementError::new($this->statement); + } + } + + public function fetchNumeric(): array|false + { + try { + $ret = $this->statement->fetch(); + } catch (mysqli_sql_exception $e) { + throw StatementError::upcast($e); + } + + if ($ret === false) { + throw StatementError::new($this->statement); + } + + if ($ret === null) { + return false; + } + + $values = []; + + foreach ($this->boundValues as $v) { + $values[] = $v; + } + + return $values; + } + + public function fetchAssociative(): array|false + { + $values = $this->fetchNumeric(); + + if ($values === false) { + return false; + } + + return array_combine($this->columnNames, $values); + } + + public function fetchOne(): mixed + { + return FetchUtils::fetchOne($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllNumeric(): array + { + return FetchUtils::fetchAllNumeric($this); + } + + /** + * {@inheritDoc} + */ + public function fetchAllAssociative(): array + { + return FetchUtils::fetchAllAssociative($this); + } + + /** + * {@inheritDoc} + */ + public function fetchFirstColumn(): array + { + return FetchUtils::fetchFirstColumn($this); + } + + public function rowCount(): int|string + { + if ($this->hasColumns) { + return $this->statement->num_rows; + } + + return $this->statement->affected_rows; + } + + public function columnCount(): int + { + return $this->statement->field_count; + } + + public function free(): void + { + $this->statement->free_result(); + } +} -- cgit v1.2.3