2021-01-03 09:28:31 -05:00
< ? php
declare ( strict_types = 1 );
2021-06-04 15:52:51 -04:00
/**
2024-05-23 03:26:56 -04:00
* SPDX - FileCopyrightText : 2021 Nextcloud GmbH and Nextcloud contributors
* SPDX - License - Identifier : AGPL - 3.0 - or - later
2021-01-03 09:28:31 -05:00
*/
namespace OC\DB ;
use Doctrine\DBAL\Statement ;
use OCP\DB\IPreparedStatement ;
use OCP\DB\IResult ;
2024-07-02 06:13:14 -04:00
use OCP\DB\QueryBuilder\IQueryBuilder ;
2021-01-03 09:28:31 -05:00
use PDO ;
/**
* Adapts our public API to what doctrine / dbal exposed with 2.6
*
* The old dbal statement had stateful methods e . g . to fetch data from an executed
* prepared statement . To provide backwards compatibility to apps we need to make
* this class stateful . As soon as those now deprecated exposed methods are gone ,
* we can limit the API of this adapter to the methods that map to the direct dbal
* methods without much magic .
*/
class PreparedStatement implements IPreparedStatement {
2024-07-02 08:50:22 -04:00
use TDoctrineParameterTypeMap ;
2021-01-03 09:28:31 -05:00
/** @var Statement */
private $statement ;
/** @var IResult|null */
private $result ;
public function __construct ( Statement $statement ) {
$this -> statement = $statement ;
}
public function closeCursor () : bool {
$this -> getResult () -> closeCursor ();
return true ;
}
public function fetch ( int $fetchMode = PDO :: FETCH_ASSOC ) {
return $this -> getResult () -> fetch ( $fetchMode );
}
public function fetchAll ( int $fetchMode = PDO :: FETCH_ASSOC ) : array {
return $this -> getResult () -> fetchAll ( $fetchMode );
}
public function fetchColumn () {
return $this -> getResult () -> fetchOne ();
}
public function fetchOne () {
return $this -> getResult () -> fetchOne ();
}
2024-07-02 08:50:22 -04:00
public function bindValue ( $param , $value , $type = IQueryBuilder :: PARAM_STR ) : bool {
$this -> statement -> bindValue ( $param , $value , $this -> convertParameterTypeToDoctrine ( $type ));
2024-07-02 06:13:14 -04:00
return true ;
2021-01-03 09:28:31 -05:00
}
2024-07-02 08:50:22 -04:00
public function bindParam ( $param , & $variable , $type = IQueryBuilder :: PARAM_STR , $length = null ) : bool {
2024-07-02 06:13:14 -04:00
if ( $type !== IQueryBuilder :: PARAM_STR ) {
\OC :: $server -> getLogger () -> warning ( 'PreparedStatement::bindParam() is no longer supported. Use bindValue() instead.' , [ 'exception' => new \BadMethodCallException ( 'bindParam() is no longer supported' )]);
}
$this -> bindValue ( $param , $variable , $type );
return true ;
2021-01-03 09:28:31 -05:00
}
public function execute ( $params = null ) : IResult {
2024-07-01 11:50:12 -04:00
if ( $params !== null ) {
foreach ( $params as $key => $param ) {
if ( is_int ( $key )) {
// Parameter count starts with 1
$this -> bindValue ( $key + 1 , $param );
} else {
$this -> bindValue ( $key , $param );
}
}
}
return ( $this -> result = new ResultAdapter ( $this -> statement -> executeQuery ()));
2021-01-03 09:28:31 -05:00
}
public function rowCount () : int {
return $this -> getResult () -> rowCount ();
}
private function getResult () : IResult {
if ( $this -> result !== null ) {
return $this -> result ;
}
2024-07-01 06:54:47 -04:00
throw new \Exception ( " You have to execute the prepared statement before accessing the results " );
2021-01-03 09:28:31 -05:00
}
}