Composer Version Change

This commit is contained in:
2024-02-05 00:00:23 +08:00
parent 20678a6a0c
commit 6f751ead83
789 changed files with 135417 additions and 18510 deletions
@@ -0,0 +1,45 @@
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Database\Statement;
/**
* Contains a setter for marking a Statement as buffered
*
* @internal
*/
trait BufferResultsTrait
{
/**
* Whether to buffer results in php
*
* @var bool
*/
protected $_bufferResults = true;
/**
* Whether to buffer results in php
*
* @param bool $buffer Toggle buffering
* @return $this
*/
public function bufferResults(bool $buffer)
{
$this->_bufferResults = $buffer;
return $this;
}
}
+361
View File
@@ -0,0 +1,361 @@
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Database\Statement;
use Cake\Database\DriverInterface;
use Cake\Database\StatementInterface;
use Cake\Database\TypeConverterTrait;
use Iterator;
/**
* A statement decorator that implements buffered results.
*
* This statement decorator will save fetched results in memory, allowing
* the iterator to be rewound and reused.
*
* @template-implements \Iterator<mixed>
*/
class BufferedStatement implements Iterator, StatementInterface
{
use TypeConverterTrait;
/**
* If true, all rows were fetched
*
* @var bool
*/
protected $_allFetched = false;
/**
* The decorated statement
*
* @var \Cake\Database\StatementInterface
*/
protected $statement;
/**
* The driver for the statement
*
* @var \Cake\Database\DriverInterface
*/
protected $_driver;
/**
* The in-memory cache containing results from previous iterators
*
* @var array<int, array>
*/
protected $buffer = [];
/**
* Whether this statement has already been executed
*
* @var bool
*/
protected $_hasExecuted = false;
/**
* The current iterator index.
*
* @var int
*/
protected $index = 0;
/**
* Constructor
*
* @param \Cake\Database\StatementInterface $statement Statement implementation such as PDOStatement
* @param \Cake\Database\DriverInterface $driver Driver instance
*/
public function __construct(StatementInterface $statement, DriverInterface $driver)
{
$this->statement = $statement;
$this->_driver = $driver;
}
/**
* Returns the connection driver.
*
* @return \Cake\Database\DriverInterface
*/
protected function getDriver(): DriverInterface
{
return $this->_driver;
}
/**
* Magic getter to return $queryString as read-only.
*
* @param string $property internal property to get
* @return string|null
*/
public function __get(string $property)
{
if ($property === 'queryString') {
/** @psalm-suppress NoInterfaceProperties */
return $this->statement->queryString;
}
return null;
}
/**
* @inheritDoc
*/
public function bindValue($column, $value, $type = 'string'): void
{
$this->statement->bindValue($column, $value, $type);
}
/**
* @inheritDoc
*/
public function closeCursor(): void
{
$this->statement->closeCursor();
}
/**
* @inheritDoc
*/
public function columnCount(): int
{
return $this->statement->columnCount();
}
/**
* @inheritDoc
*/
public function errorCode()
{
return $this->statement->errorCode();
}
/**
* @inheritDoc
*/
public function errorInfo(): array
{
return $this->statement->errorInfo();
}
/**
* @inheritDoc
*/
public function execute(?array $params = null): bool
{
$this->_reset();
$this->_hasExecuted = true;
return $this->statement->execute($params);
}
/**
* @inheritDoc
*/
public function fetchColumn(int $position)
{
$result = $this->fetch(static::FETCH_TYPE_NUM);
if ($result !== false && isset($result[$position])) {
return $result[$position];
}
return false;
}
/**
* Statements can be passed as argument for count() to return the number
* for affected rows from last execution.
*
* @return int
*/
public function count(): int
{
return $this->rowCount();
}
/**
* @inheritDoc
*/
public function bind(array $params, array $types): void
{
$this->statement->bind($params, $types);
}
/**
* @inheritDoc
*/
public function lastInsertId(?string $table = null, ?string $column = null)
{
return $this->statement->lastInsertId($table, $column);
}
/**
* {@inheritDoc}
*
* @param string|int $type The type to fetch.
* @return array|false
*/
public function fetch($type = self::FETCH_TYPE_NUM)
{
if ($this->_allFetched) {
$row = false;
if (isset($this->buffer[$this->index])) {
$row = $this->buffer[$this->index];
}
$this->index += 1;
if ($row && $type === static::FETCH_TYPE_NUM) {
return array_values($row);
}
return $row;
}
$record = $this->statement->fetch($type);
if ($record === false) {
$this->_allFetched = true;
$this->statement->closeCursor();
return false;
}
$this->buffer[] = $record;
return $record;
}
/**
* @return array
*/
public function fetchAssoc(): array
{
$result = $this->fetch(static::FETCH_TYPE_ASSOC);
return $result ?: [];
}
/**
* @inheritDoc
*/
public function fetchAll($type = self::FETCH_TYPE_NUM)
{
if ($this->_allFetched) {
return $this->buffer;
}
$results = $this->statement->fetchAll($type);
if ($results !== false) {
$this->buffer = array_merge($this->buffer, $results);
}
$this->_allFetched = true;
$this->statement->closeCursor();
return $this->buffer;
}
/**
* @inheritDoc
*/
public function rowCount(): int
{
if (!$this->_allFetched) {
$this->fetchAll(static::FETCH_TYPE_ASSOC);
}
return count($this->buffer);
}
/**
* Reset all properties
*
* @return void
*/
protected function _reset(): void
{
$this->buffer = [];
$this->_allFetched = false;
$this->index = 0;
}
/**
* Returns the current key in the iterator
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function key()
{
return $this->index;
}
/**
* Returns the current record in the iterator
*
* @return mixed
*/
#[\ReturnTypeWillChange]
public function current()
{
return $this->buffer[$this->index];
}
/**
* Rewinds the collection
*
* @return void
*/
public function rewind(): void
{
$this->index = 0;
}
/**
* Returns whether the iterator has more elements
*
* @return bool
*/
public function valid(): bool
{
$old = $this->index;
$row = $this->fetch(self::FETCH_TYPE_ASSOC);
// Restore the index as fetch() increments during
// the cache scenario.
$this->index = $old;
return $row !== false;
}
/**
* Advances the iterator pointer to the next element
*
* @return void
*/
public function next(): void
{
$this->index += 1;
}
/**
* Get the wrapped statement
*
* @return \Cake\Database\StatementInterface
*/
public function getInnerStatement(): StatementInterface
{
return $this->statement;
}
}
+77
View File
@@ -0,0 +1,77 @@
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Database\Statement;
use Cake\Database\DriverInterface;
use Cake\Database\StatementInterface;
/**
* Wraps a statement in a callback that allows row results
* to be modified when being fetched.
*
* This is used by CakePHP to eagerly load association data.
*/
class CallbackStatement extends StatementDecorator
{
/**
* A callback function to be applied to results.
*
* @var callable
*/
protected $_callback;
/**
* Constructor
*
* @param \Cake\Database\StatementInterface $statement The statement to decorate.
* @param \Cake\Database\DriverInterface $driver The driver instance used by the statement.
* @param callable $callback The callback to apply to results before they are returned.
*/
public function __construct(StatementInterface $statement, DriverInterface $driver, callable $callback)
{
parent::__construct($statement, $driver);
$this->_callback = $callback;
}
/**
* Fetch a row from the statement.
*
* The result will be processed by the callback when it is not `false`.
*
* @param string|int $type Either 'num' or 'assoc' to indicate the result format you would like.
* @return array|false
*/
public function fetch($type = parent::FETCH_TYPE_NUM)
{
$callback = $this->_callback;
$row = $this->_statement->fetch($type);
return $row === false ? $row : $callback($row);
}
/**
* {@inheritDoc}
*
* Each row in the result will be processed by the callback when it is not `false.
*/
public function fetchAll($type = parent::FETCH_TYPE_NUM)
{
$results = $this->_statement->fetchAll($type);
return $results !== false ? array_map($this->_callback, $results) : false;
}
}
+46
View File
@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Database\Statement;
use PDO;
/**
* Statement class meant to be used by a MySQL PDO driver
*
* @internal
*/
class MysqlStatement extends PDOStatement
{
use BufferResultsTrait;
/**
* @inheritDoc
*/
public function execute(?array $params = null): bool
{
$connection = $this->_driver->getConnection();
try {
$connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, $this->_bufferResults);
$result = $this->_statement->execute($params);
} finally {
$connection->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
}
return $result;
}
}
+176
View File
@@ -0,0 +1,176 @@
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Database\Statement;
use Cake\Core\Exception\CakeException;
use Cake\Database\DriverInterface;
use PDO;
use PDOStatement as Statement;
use function Cake\Core\getTypeName;
/**
* Decorator for \PDOStatement class mainly used for converting human readable
* fetch modes into PDO constants.
*/
class PDOStatement extends StatementDecorator
{
/**
* PDOStatement instance
*
* @var \PDOStatement
*/
protected $_statement;
/**
* Constructor
*
* @param \PDOStatement $statement Original statement to be decorated.
* @param \Cake\Database\DriverInterface $driver Driver instance.
*/
public function __construct(Statement $statement, DriverInterface $driver)
{
$this->_statement = $statement;
$this->_driver = $driver;
}
/**
* Magic getter to return PDOStatement::$queryString as read-only.
*
* @param string $property internal property to get
* @return string|null
*/
public function __get(string $property)
{
if ($property === 'queryString' && isset($this->_statement->queryString)) {
return $this->_statement->queryString;
}
return null;
}
/**
* Assign a value to a positional or named variable in prepared query. If using
* positional variables you need to start with index one, if using named params then
* just use the name in any order.
*
* You can pass PDO compatible constants for binding values with a type or optionally
* any type name registered in the Type class. Any value will be converted to the valid type
* representation if needed.
*
* It is not allowed to combine positional and named variables in the same statement
*
* ### Examples:
*
* ```
* $statement->bindValue(1, 'a title');
* $statement->bindValue(2, 5, PDO::INT);
* $statement->bindValue('active', true, 'boolean');
* $statement->bindValue(5, new \DateTime(), 'date');
* ```
*
* @param string|int $column name or param position to be bound
* @param mixed $value The value to bind to variable in query
* @param string|int|null $type PDO type or name of configured Type class
* @return void
*/
public function bindValue($column, $value, $type = 'string'): void
{
if ($type === null) {
$type = 'string';
}
if (!is_int($type)) {
[$value, $type] = $this->cast($value, $type);
}
$this->_statement->bindValue($column, $value, $type);
}
/**
* Returns the next row for the result set after executing this statement.
* Rows can be fetched to contain columns as names or positions. If no
* rows are left in result set, this method will return false
*
* ### Example:
*
* ```
* $statement = $connection->prepare('SELECT id, title from articles');
* $statement->execute();
* print_r($statement->fetch('assoc')); // will show ['id' => 1, 'title' => 'a title']
* ```
*
* @param string|int $type 'num' for positional columns, assoc for named columns
* @return mixed Result array containing columns and values or false if no results
* are left
*/
public function fetch($type = parent::FETCH_TYPE_NUM)
{
if ($type === static::FETCH_TYPE_NUM) {
return $this->_statement->fetch(PDO::FETCH_NUM);
}
if ($type === static::FETCH_TYPE_ASSOC) {
return $this->_statement->fetch(PDO::FETCH_ASSOC);
}
if ($type === static::FETCH_TYPE_OBJ) {
return $this->_statement->fetch(PDO::FETCH_OBJ);
}
if (!is_int($type)) {
throw new CakeException(sprintf(
'Fetch type for PDOStatement must be an integer, found `%s` instead',
getTypeName($type)
));
}
return $this->_statement->fetch($type);
}
/**
* Returns an array with all rows resulting from executing this statement
*
* ### Example:
*
* ```
* $statement = $connection->prepare('SELECT id, title from articles');
* $statement->execute();
* print_r($statement->fetchAll('assoc')); // will show [0 => ['id' => 1, 'title' => 'a title']]
* ```
*
* @param string|int $type num for fetching columns as positional keys or assoc for column names as keys
* @return array|false list of all results from database for this statement, false on failure
* @psalm-assert string $type
*/
public function fetchAll($type = parent::FETCH_TYPE_NUM)
{
if ($type === static::FETCH_TYPE_NUM) {
return $this->_statement->fetchAll(PDO::FETCH_NUM);
}
if ($type === static::FETCH_TYPE_ASSOC) {
return $this->_statement->fetchAll(PDO::FETCH_ASSOC);
}
if ($type === static::FETCH_TYPE_OBJ) {
return $this->_statement->fetchAll(PDO::FETCH_OBJ);
}
if (!is_int($type)) {
throw new CakeException(sprintf(
'Fetch type for PDOStatement must be an integer, found `%s` instead',
getTypeName($type)
));
}
return $this->_statement->fetchAll($type);
}
}
+70
View File
@@ -0,0 +1,70 @@
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Database\Statement;
/**
* Statement class meant to be used by an Sqlite driver
*
* @internal
*/
class SqliteStatement extends StatementDecorator
{
use BufferResultsTrait;
/**
* @inheritDoc
*/
public function execute(?array $params = null): bool
{
if ($this->_statement instanceof BufferedStatement) {
$this->_statement = $this->_statement->getInnerStatement();
}
if ($this->_bufferResults) {
$this->_statement = new BufferedStatement($this->_statement, $this->_driver);
}
return $this->_statement->execute($params);
}
/**
* Returns the number of rows returned of affected by last execution
*
* @return int
*/
public function rowCount(): int
{
/** @psalm-suppress NoInterfaceProperties */
if (
$this->_statement->queryString &&
preg_match('/^(?:DELETE|UPDATE|INSERT)/i', $this->_statement->queryString)
) {
$changes = $this->_driver->prepare('SELECT CHANGES()');
$changes->execute();
$row = $changes->fetch();
$changes->closeCursor();
if (!$row) {
return 0;
}
return (int)$row[0];
}
return parent::rowCount();
}
}
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Database\Statement;
use PDO;
/**
* Statement class meant to be used by an Sqlserver driver
*
* @internal
*/
class SqlserverStatement extends PDOStatement
{
/**
* {@inheritDoc}
*
* The SQL Server PDO driver requires that binary parameters be bound with the SQLSRV_ENCODING_BINARY attribute.
* This overrides the PDOStatement::bindValue method in order to bind binary columns using the required attribute.
*
* @param string|int $column name or param position to be bound
* @param mixed $value The value to bind to variable in query
* @param string|int|null $type PDO type or name of configured Type class
* @return void
*/
public function bindValue($column, $value, $type = 'string'): void
{
if ($type === null) {
$type = 'string';
}
if (!is_int($type)) {
[$value, $type] = $this->cast($value, $type);
}
if ($type === PDO::PARAM_LOB) {
$this->_statement->bindParam($column, $value, $type, 0, PDO::SQLSRV_ENCODING_BINARY);
} else {
$this->_statement->bindValue($column, $value, $type);
}
}
}
+373
View File
@@ -0,0 +1,373 @@
<?php
declare(strict_types=1);
/**
* CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
* Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
*
* Licensed under The MIT License
* For full copyright and license information, please see the LICENSE.txt
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
* @link https://cakephp.org CakePHP(tm) Project
* @since 3.0.0
* @license https://opensource.org/licenses/mit-license.php MIT License
*/
namespace Cake\Database\Statement;
use Cake\Database\DriverInterface;
use Cake\Database\StatementInterface;
use Cake\Database\TypeConverterTrait;
use Countable;
use IteratorAggregate;
/**
* Represents a database statement. Statements contains queries that can be
* executed multiple times by binding different values on each call. This class
* also helps convert values to their valid representation for the corresponding
* types.
*
* This class is but a decorator of an actual statement implementation, such as
* PDOStatement.
*
* @property-read string $queryString
* @template-implements \IteratorAggregate<string, \Cake\Database\StatementInterface>
*/
class StatementDecorator implements StatementInterface, Countable, IteratorAggregate
{
use TypeConverterTrait;
/**
* Statement instance implementation, such as PDOStatement
* or any other custom implementation.
*
* @var \Cake\Database\StatementInterface
*/
protected $_statement;
/**
* Reference to the driver object associated to this statement.
*
* @var \Cake\Database\DriverInterface
*/
protected $_driver;
/**
* Whether this statement has already been executed
*
* @var bool
*/
protected $_hasExecuted = false;
/**
* Constructor
*
* @param \Cake\Database\StatementInterface $statement Statement implementation
* such as PDOStatement.
* @param \Cake\Database\DriverInterface $driver Driver instance
*/
public function __construct(StatementInterface $statement, DriverInterface $driver)
{
$this->_statement = $statement;
$this->_driver = $driver;
}
/**
* Returns the connection driver.
*
* @return \Cake\Database\DriverInterface
*/
protected function getDriver(): DriverInterface
{
return $this->_driver;
}
/**
* Magic getter to return $queryString as read-only.
*
* @param string $property internal property to get
* @return string|null
*/
public function __get(string $property)
{
if ($property === 'queryString') {
/** @psalm-suppress NoInterfaceProperties */
return $this->_statement->queryString;
}
return null;
}
/**
* Assign a value to a positional or named variable in prepared query. If using
* positional variables you need to start with index one, if using named params then
* just use the name in any order.
*
* It is not allowed to combine positional and named variables in the same statement.
*
* ### Examples:
*
* ```
* $statement->bindValue(1, 'a title');
* $statement->bindValue('active', true, 'boolean');
* $statement->bindValue(5, new \DateTime(), 'date');
* ```
*
* @param string|int $column name or param position to be bound
* @param mixed $value The value to bind to variable in query
* @param string|int|null $type name of configured Type class
* @return void
*/
public function bindValue($column, $value, $type = 'string'): void
{
$this->_statement->bindValue($column, $value, $type);
}
/**
* Closes a cursor in the database, freeing up any resources and memory
* allocated to it. In most cases you don't need to call this method, as it is
* automatically called after fetching all results from the result set.
*
* @return void
*/
public function closeCursor(): void
{
$this->_statement->closeCursor();
}
/**
* Returns the number of columns this statement's results will contain.
*
* ### Example:
*
* ```
* $statement = $connection->prepare('SELECT id, title from articles');
* $statement->execute();
* echo $statement->columnCount(); // outputs 2
* ```
*
* @return int
*/
public function columnCount(): int
{
return $this->_statement->columnCount();
}
/**
* Returns the error code for the last error that occurred when executing this statement.
*
* @return string|int
*/
public function errorCode()
{
return $this->_statement->errorCode();
}
/**
* Returns the error information for the last error that occurred when executing
* this statement.
*
* @return array
*/
public function errorInfo(): array
{
return $this->_statement->errorInfo();
}
/**
* Executes the statement by sending the SQL query to the database. It can optionally
* take an array or arguments to be bound to the query variables. Please note
* that binding parameters from this method will not perform any custom type conversion
* as it would normally happen when calling `bindValue`.
*
* @param array|null $params list of values to be bound to query
* @return bool true on success, false otherwise
*/
public function execute(?array $params = null): bool
{
$this->_hasExecuted = true;
return $this->_statement->execute($params);
}
/**
* Returns the next row for the result set after executing this statement.
* Rows can be fetched to contain columns as names or positions. If no
* rows are left in result set, this method will return false.
*
* ### Example:
*
* ```
* $statement = $connection->prepare('SELECT id, title from articles');
* $statement->execute();
* print_r($statement->fetch('assoc')); // will show ['id' => 1, 'title' => 'a title']
* ```
*
* @param string|int $type 'num' for positional columns, assoc for named columns
* @return mixed Result array containing columns and values or false if no results
* are left
*/
public function fetch($type = self::FETCH_TYPE_NUM)
{
return $this->_statement->fetch($type);
}
/**
* Returns the next row in a result set as an associative array. Calling this function is the same as calling
* $statement->fetch(StatementDecorator::FETCH_TYPE_ASSOC). If no results are found an empty array is returned.
*
* @return array
*/
public function fetchAssoc(): array
{
$result = $this->fetch(static::FETCH_TYPE_ASSOC);
return $result ?: [];
}
/**
* Returns the value of the result at position.
*
* @param int $position The numeric position of the column to retrieve in the result
* @return mixed Returns the specific value of the column designated at $position
*/
public function fetchColumn(int $position)
{
$result = $this->fetch(static::FETCH_TYPE_NUM);
if ($result && isset($result[$position])) {
return $result[$position];
}
return false;
}
/**
* Returns an array with all rows resulting from executing this statement.
*
* ### Example:
*
* ```
* $statement = $connection->prepare('SELECT id, title from articles');
* $statement->execute();
* print_r($statement->fetchAll('assoc')); // will show [0 => ['id' => 1, 'title' => 'a title']]
* ```
*
* @param string|int $type num for fetching columns as positional keys or assoc for column names as keys
* @return array|false List of all results from database for this statement. False on failure.
*/
public function fetchAll($type = self::FETCH_TYPE_NUM)
{
return $this->_statement->fetchAll($type);
}
/**
* Returns the number of rows affected by this SQL statement.
*
* ### Example:
*
* ```
* $statement = $connection->prepare('SELECT id, title from articles');
* $statement->execute();
* print_r($statement->rowCount()); // will show 1
* ```
*
* @return int
*/
public function rowCount(): int
{
return $this->_statement->rowCount();
}
/**
* Statements are iterable as arrays, this method will return
* the iterator object for traversing all items in the result.
*
* ### Example:
*
* ```
* $statement = $connection->prepare('SELECT id, title from articles');
* foreach ($statement as $row) {
* //do stuff
* }
* ```
*
* @return \Cake\Database\StatementInterface
* @psalm-suppress ImplementedReturnTypeMismatch
*/
#[\ReturnTypeWillChange]
public function getIterator()
{
if (!$this->_hasExecuted) {
$this->execute();
}
return $this->_statement;
}
/**
* Statements can be passed as argument for count() to return the number
* for affected rows from last execution.
*
* @return int
*/
public function count(): int
{
return $this->rowCount();
}
/**
* Binds a set of values to statement object with corresponding type.
*
* @param array $params list of values to be bound
* @param array $types list of types to be used, keys should match those in $params
* @return void
*/
public function bind(array $params, array $types): void
{
if (empty($params)) {
return;
}
$anonymousParams = is_int(key($params));
$offset = 1;
foreach ($params as $index => $value) {
$type = $types[$index] ?? null;
if ($anonymousParams) {
/** @psalm-suppress InvalidOperand */
$index += $offset;
}
$this->bindValue($index, $value, $type);
}
}
/**
* Returns the latest primary inserted using this statement.
*
* @param string|null $table table name or sequence to get last insert value from
* @param string|null $column the name of the column representing the primary key
* @return string|int
*/
public function lastInsertId(?string $table = null, ?string $column = null)
{
if ($column && $this->columnCount()) {
$row = $this->fetch(static::FETCH_TYPE_ASSOC);
if ($row && isset($row[$column])) {
return $row[$column];
}
}
return $this->_driver->lastInsertId($table, $column);
}
/**
* Returns the statement object that was decorated by this class.
*
* @return \Cake\Database\StatementInterface
*/
public function getInnerStatement()
{
return $this->_statement;
}
}