Skip to content

Commit

Permalink
Merge pull request #1962 from MasterOdin/mpeveler-feat-query-params
Browse files Browse the repository at this point in the history
Add optional $params argument to query/execute adapter methods
  • Loading branch information
dereuromark authored Jun 17, 2021
2 parents 986a355 + 5132b12 commit 7525393
Show file tree
Hide file tree
Showing 14 changed files with 203 additions and 24 deletions.
15 changes: 14 additions & 1 deletion docs/en/migrations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ Executing Queries
Queries can be executed with the ``execute()`` and ``query()`` methods. The
``execute()`` method returns the number of affected rows whereas the
``query()`` method returns the result as a
`PDOStatement <http://php.net/manual/en/class.pdostatement.php>`_
`PDOStatement <http://php.net/manual/en/class.pdostatement.php>`_. Both methods
accept an optional second parameter ``$params`` which is an array of elements,
and if used will cause the underlying connection to use a prepared statement.

.. code-block:: php
Expand All @@ -193,6 +195,11 @@ Queries can be executed with the ``execute()`` and ``query()`` methods. The
// query()
$stmt = $this->query('SELECT * FROM users'); // returns PDOStatement
$rows = $stmt->fetchAll(); // returns the result as an array
// using prepared queries
$count = $this->execute('DELETE FROM users WHERE id = ?', [5]);
$stmt = $this->query('SELECT * FROM users WHERE id > 5'); // returns PDOStatement
$rows = $stmt->fetchAll();
}
/**
Expand All @@ -213,6 +220,12 @@ Queries can be executed with the ``execute()`` and ``query()`` methods. The
DELIMITERs during insertion of stored procedures or triggers which
don't support DELIMITERs.

.. note::

If you wish to execute multiple queries at once, you may not also use the prepared
variant of these functions. When using prepared queries, PDO can only execute
them one at a time.

.. warning::

When using ``execute()`` or ``query()`` with a batch of queries, PDO doesn't
Expand Down
6 changes: 4 additions & 2 deletions src/Phinx/Db/Adapter/AdapterInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -256,9 +256,10 @@ public function rollbackTransaction();
* Executes a SQL statement and returns the number of affected rows.
*
* @param string $sql SQL
* @param array $params parameters to use for prepared query
* @return int
*/
public function execute($sql);
public function execute($sql, array $params = []);

/**
* Executes a list of migration actions for the given table
Expand All @@ -282,9 +283,10 @@ public function getQueryBuilder();
* The return type depends on the underlying adapter being used.
*
* @param string $sql SQL
* @param array $params parameters to use for prepared query
* @return mixed
*/
public function query($sql);
public function query($sql, array $params = []);

/**
* Executes a query and returns only one row as an array.
Expand Down
8 changes: 4 additions & 4 deletions src/Phinx/Db/Adapter/AdapterWrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,17 +151,17 @@ public function disconnect()
/**
* @inheritDoc
*/
public function execute($sql)
public function execute($sql, array $params = [])
{
return $this->getAdapter()->execute($sql);
return $this->getAdapter()->execute($sql, $params);
}

/**
* @inheritDoc
*/
public function query($sql)
public function query($sql, array $params = [])
{
return $this->getAdapter()->query($sql);
return $this->getAdapter()->query($sql, $params);
}

/**
Expand Down
23 changes: 18 additions & 5 deletions src/Phinx/Db/Adapter/PdoAdapter.php
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ public function disconnect()
/**
* @inheritDoc
*/
public function execute($sql)
public function execute($sql, array $params = [])
{
$sql = rtrim($sql, "; \t\n\r\0\x0B") . ';';
$this->verboseLog($sql);
Expand All @@ -189,7 +189,14 @@ public function execute($sql)
return 0;
}

return $this->getConnection()->exec($sql);
if (empty($params)) {
return $this->getConnection()->exec($sql);
}

$stmt = $this->getConnection()->prepare($sql);
$result = $stmt->execute($params);

return $result ? $stmt->rowCount() : $result;
}

/**
Expand All @@ -212,11 +219,17 @@ public function getQueryBuilder()
* Executes a query and returns PDOStatement.
*
* @param string $sql SQL
* @return \PDOStatement
* @return \PDOStatement|false
*/
public function query($sql)
public function query($sql, array $params = [])
{
return $this->getConnection()->query($sql);
if (empty($params)) {
return $this->getConnection()->query($sql);
}
$stmt = $this->getConnection()->prepare($sql);
$result = $stmt->execute($params);

return $result ? $stmt : false;
}

/**
Expand Down
8 changes: 4 additions & 4 deletions src/Phinx/Migration/AbstractMigration.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,17 +193,17 @@ public function isMigratingUp()
/**
* @inheritDoc
*/
public function execute($sql)
public function execute($sql, array $params = [])
{
return $this->getAdapter()->execute($sql);
return $this->getAdapter()->execute($sql, $params);
}

/**
* @inheritDoc
*/
public function query($sql)
public function query($sql, array $params = [])
{
return $this->getAdapter()->query($sql);
return $this->getAdapter()->query($sql, $params);
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/Phinx/Migration/MigrationInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,10 @@ public function isMigratingUp();
* Executes a SQL statement and returns the number of affected rows.
*
* @param string $sql SQL
* @param array $params parameters to use for prepared query
* @return int
*/
public function execute($sql);
public function execute($sql, array $params = []);

/**
* Executes a SQL statement.
Expand All @@ -145,9 +146,10 @@ public function execute($sql);
* you can set the return type by the adapter in your current use.
*
* @param string $sql SQL
* @param array $params parameters to use for prepared query
* @return mixed
*/
public function query($sql);
public function query($sql, array $params = []);

/**
* Returns a new Query object that can be used to build complex SELECT, UPDATE, INSERT or DELETE
Expand Down
8 changes: 4 additions & 4 deletions src/Phinx/Seed/AbstractSeed.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,17 @@ public function getName()
/**
* @inheritDoc
*/
public function execute($sql)
public function execute($sql, array $params = [])
{
return $this->getAdapter()->execute($sql);
return $this->getAdapter()->execute($sql, $params);
}

/**
* @inheritDoc
*/
public function query($sql)
public function query($sql, array $params = [])
{
return $this->getAdapter()->query($sql);
return $this->getAdapter()->query($sql, $params);
}

/**
Expand Down
6 changes: 4 additions & 2 deletions src/Phinx/Seed/SeedInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -91,9 +91,10 @@ public function getName();
* Executes a SQL statement and returns the number of affected rows.
*
* @param string $sql SQL
* @param array $params parameters to use for prepared query
* @return int
*/
public function execute($sql);
public function execute($sql, array $params = []);

/**
* Executes a SQL statement.
Expand All @@ -104,9 +105,10 @@ public function execute($sql);
* you can set the return type by the adapter in your current use.
*
* @param string $sql SQL
* @param array $params parameters to use for prepared query
* @return mixed
*/
public function query($sql);
public function query($sql, array $params = []);

/**
* Executes a query and returns only one row as an array.
Expand Down
31 changes: 31 additions & 0 deletions tests/Phinx/Db/Adapter/MysqlAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1971,6 +1971,37 @@ public function testQueryBuilder()
$this->assertEquals(1, $stm->rowCount());
}

public function testQueryWithParams()
{
$table = new \Phinx\Db\Table('table1', [], $this->adapter);
$table->addColumn('string_col', 'string')
->addColumn('int_col', 'integer')
->save();

$this->adapter->insert($table->getTable(), [
'string_col' => 'test data',
'int_col' => 10,
]);

$this->adapter->insert($table->getTable(), [
'string_col' => null,
]);

$this->adapter->insert($table->getTable(), [
'int_col' => 23,
]);

$countQuery = $this->adapter->query('SELECT COUNT(*) AS c FROM table1 WHERE int_col > ?', [5]);
$res = $countQuery->fetchAll();
$this->assertEquals(2, $res[0]['c']);

$this->adapter->execute('UPDATE table1 SET int_col = ? WHERE int_col IS NULL', [12]);

$countQuery->execute([1]);
$res = $countQuery->fetchAll();
$this->assertEquals(3, $res[0]['c']);
}

public function testLiteralSupport()
{
$createQuery = <<<'INPUT'
Expand Down
31 changes: 31 additions & 0 deletions tests/Phinx/Db/Adapter/PostgresAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2248,6 +2248,37 @@ public function testQueryBuilder()
$this->assertEquals(1, $stm->rowCount());
}

public function testQueryWithParams()
{
$table = new \Phinx\Db\Table('table1', [], $this->adapter);
$table->addColumn('string_col', 'string')
->addColumn('int_col', 'integer')
->save();

$this->adapter->insert($table->getTable(), [
'string_col' => 'test data',
'int_col' => 10,
]);

$this->adapter->insert($table->getTable(), [
'string_col' => null,
]);

$this->adapter->insert($table->getTable(), [
'int_col' => 23,
]);

$countQuery = $this->adapter->query('SELECT COUNT(*) AS c FROM table1 WHERE int_col > ?', [5]);
$res = $countQuery->fetchAll();
$this->assertEquals(2, $res[0]['c']);

$this->adapter->execute('UPDATE table1 SET int_col = ? WHERE int_col IS NULL', [12]);

$countQuery->execute([1]);
$res = $countQuery->fetchAll();
$this->assertEquals(3, $res[0]['c']);
}

public function testRenameMixedCaseTableAndColumns()
{
$table = new \Phinx\Db\Table('OrganizationSettings', [], $this->adapter);
Expand Down
31 changes: 31 additions & 0 deletions tests/Phinx/Db/Adapter/SQLiteAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1187,6 +1187,37 @@ public function testQueryBuilder()
$this->assertEquals(1, $stm->rowCount());
}

public function testQueryWithParams()
{
$table = new \Phinx\Db\Table('table1', [], $this->adapter);
$table->addColumn('string_col', 'string')
->addColumn('int_col', 'integer')
->save();

$this->adapter->insert($table->getTable(), [
'string_col' => 'test data',
'int_col' => 10,
]);

$this->adapter->insert($table->getTable(), [
'string_col' => null,
]);

$this->adapter->insert($table->getTable(), [
'int_col' => 23,
]);

$countQuery = $this->adapter->query('SELECT COUNT(*) AS c FROM table1 WHERE int_col > ?', [5]);
$res = $countQuery->fetchAll();
$this->assertEquals(2, $res[0]['c']);

$this->adapter->execute('UPDATE table1 SET int_col = ? WHERE int_col IS NULL', [12]);

$countQuery->execute([1]);
$res = $countQuery->fetchAll();
$this->assertEquals(3, $res[0]['c']);
}

/**
* Tests adding more than one column to a table
* that already exists due to adapters having different add column instructions
Expand Down
31 changes: 31 additions & 0 deletions tests/Phinx/Db/Adapter/SqlServerAdapterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1108,6 +1108,37 @@ public function testQueryBuilder()
$stm->closeCursor();
}

public function testQueryWithParams()
{
$table = new \Phinx\Db\Table('table1', [], $this->adapter);
$table->addColumn('string_col', 'string')
->addColumn('int_col', 'integer')
->save();

$this->adapter->insert($table->getTable(), [
'string_col' => 'test data',
'int_col' => 10,
]);

$this->adapter->insert($table->getTable(), [
'string_col' => null,
]);

$this->adapter->insert($table->getTable(), [
'int_col' => 23,
]);

$countQuery = $this->adapter->query('SELECT COUNT(*) AS c FROM table1 WHERE int_col > ?', [5]);
$res = $countQuery->fetchAll();
$this->assertEquals(2, $res[0]['c']);

$this->adapter->execute('UPDATE table1 SET int_col = ? WHERE int_col IS NULL', [12]);

$countQuery->execute([1]);
$res = $countQuery->fetchAll();
$this->assertEquals(3, $res[0]['c']);
}

public function testLiteralSupport()
{
$createQuery = <<<'INPUT'
Expand Down
7 changes: 7 additions & 0 deletions tests/Phinx/Db/Mock/PdoAdapterTestPDOMockWithExecChecks.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ public function exec($sql)
$this->sql = $sql;
}

public function prepare($sql, $options = [])
{
$this->sql = $sql;

return new PdoStatementMock();
}

public function getExecutedSqlForTest()
{
return $this->sql;
Expand Down
Loading

0 comments on commit 7525393

Please sign in to comment.