Prepwork for 'returning' method of Query builder

This commit is contained in:
Timothy Warren 2019-12-13 15:11:49 -05:00
parent 78705bf796
commit 2bf8897918
13 changed files with 131 additions and 21 deletions

View File

@ -2,22 +2,20 @@
A query builder/database abstraction layer, using prepared statements for security. A query builder/database abstraction layer, using prepared statements for security.
[![Build Status](https://jenkins.timshomepage.net/buildStatus/icon?job=query)](https://jenkins.timshomepage.net/job/query/)
[![Code Coverage](https://scrutinizer-ci.com/g/aviat4ion/Query/badges/coverage.png?b=develop)](https://scrutinizer-ci.com/g/aviat4ion/Query/?branch=develop) [![Code Coverage](https://scrutinizer-ci.com/g/aviat4ion/Query/badges/coverage.png?b=develop)](https://scrutinizer-ci.com/g/aviat4ion/Query/?branch=develop)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/aviat4ion/Query/badges/quality-score.png?b=develop)](https://scrutinizer-ci.com/g/aviat4ion/Query/?branch=develop) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/aviat4ion/Query/badges/quality-score.png?b=develop)](https://scrutinizer-ci.com/g/aviat4ion/Query/?branch=develop)
[![Latest Stable Version](https://poser.pugx.org/aviat/query/v/stable.png)](https://packagist.org/packages/aviat/query) [![Latest Stable Version](https://poser.pugx.org/aviat/query/v/stable.png)](https://packagist.org/packages/aviat/query)
[![Total Downloads](https://poser.pugx.org/aviat/query/downloads.png)](https://packagist.org/packages/aviat/query) [![Total Downloads](https://poser.pugx.org/aviat/query/downloads.png)](https://packagist.org/packages/aviat/query)
[![Latest Unstable Version](https://poser.pugx.org/aviat/query/v/unstable.png)](https://packagist.org/packages/aviat/query) [![Latest Unstable Version](https://poser.pugx.org/aviat/query/v/unstable.png)](https://packagist.org/packages/aviat/query)
[![License](https://poser.pugx.org/aviat/query/license.png)](http://www.dbad-license.org/)
## Requirements ## Requirements
* PDO extensions for the databases you wish to use (unless it's Firebird, in which case, the interbase extension is required) * PDO extensions for the databases you wish to use
* PHP 7.1 or later * PHP 7.2 or later
## Databases Supported ## Databases Supported
* MySQL * MySQL 5+ / MariaDB
* PostgreSQL * PostgreSQL 8.4+
* SQLite * SQLite
## Including Query in your application ## Including Query in your application
@ -102,7 +100,7 @@ An example of a moderately complex query:
$query = $db->select('id, key as k, val') $query = $db->select('id, key as k, val')
->from('table t') ->from('table t')
->where('k >', 3) ->where('k >', 3)
->orWhere('id !=' 5) ->orWhere('id !=', 5)
->orderBy('val', 'DESC') ->orderBy('val', 'DESC')
->limit(3, 1) ->limit(3, 1)
->get(); ->get();
@ -120,7 +118,7 @@ LIMIT 3 OFFSET 1
``` ```
The query execution methods `get`, `getWhere`, `insert`, The query execution methods `get`, `getWhere`, `insert`,
`insertBatch`,`update`, and `delete` return a native [PDOStatemnt](http://php.net/manual/en/class.pdostatement.php) object. `insertBatch`,`update`, and `delete` return a native [PDOStatement](http://php.net/manual/en/class.pdostatement.php) object.
To retrieve the results of a query, use the PDOStatement method [fetch](http://php.net/manual/en/pdostatement.fetch.php) and/or To retrieve the results of a query, use the PDOStatement method [fetch](http://php.net/manual/en/pdostatement.fetch.php) and/or
[fetchAll](http://php.net/manual/en/pdostatement.fetchall.php). [fetchAll](http://php.net/manual/en/pdostatement.fetchall.php).

View File

@ -474,6 +474,16 @@ abstract class AbstractDriver
return $this->driverQuery('typeList', FALSE); return $this->driverQuery('typeList', FALSE);
} }
/**
* Get the version of the database engine
*
* @return string
*/
public function getVersion(): string
{
return $this->getAttribute(PDO::ATTR_SERVER_VERSION);
}
/** /**
* Method to simplify retrieving db results for meta-data queries * Method to simplify retrieving db results for meta-data queries
* *
@ -653,6 +663,18 @@ abstract class AbstractDriver
return $this->statement; return $this->statement;
} }
/**
* Generate the returning clause for the current database
*
* @param string $query
* @param string $select
* @return string
*/
public function returning(string $query, string $select): string
{
return "{$query} RETURNING {$select}";
}
/** /**
* Helper method for quote_ident * Helper method for quote_ident
* *

View File

@ -253,6 +253,13 @@ interface DriverInterface /* extends the interface of PDO */ {
*/ */
public function getUtil(): AbstractUtil; public function getUtil(): AbstractUtil;
/**
* Get the version of the database engine
*
* @return string
*/
public function getVersion(): string;
/** /**
* Get the last sql query executed * Get the last sql query executed
* *

View File

@ -63,4 +63,34 @@ class Driver extends AbstractDriver {
parent::__construct($dsn, $username, $password, $options); parent::__construct($dsn, $username, $password, $options);
} }
/**
* Generate the returning clause for the current database
*
* @param string $query
* @param string $select
* @return string
*/
public function returning(string $query, string $select): string
{
// @TODO add checks for MariaDB for future-proofing
// MariaDB 10.5.0+ supports the returning clause for insert
if (
stripos($query, 'insert') !== FALSE
&& version_compare($this->getVersion(), '10.5.0', '>=')
){
return parent::returning($query, $select);
}
// MariaDB 10.0.5+ supports the returning clause for delete
if (
stripos($query, 'delete') !== FALSE
&& version_compare($this->getVersion(), '10.0.5', '>=')
){
return parent::returning($query, $select);
}
// Just return the same SQL if the returning clause is not supported
return $query;
}
} }

View File

@ -78,7 +78,9 @@ SQL;
{ {
if ( ! isset($valueMap[$key[$type]])) if ( ! isset($valueMap[$key[$type]]))
{ {
// @codeCoverageIgnoreStart
continue; continue;
// @codeCoverageIgnoreEnd
} }
$key[$type] = $valueMap[$key[$type]]; $key[$type] = $valueMap[$key[$type]];

View File

@ -109,7 +109,7 @@ class Driver extends AbstractDriver {
{ {
// If greater than version 3.7.11, supports the same syntax as // If greater than version 3.7.11, supports the same syntax as
// MySQL and Postgres // MySQL and Postgres
if (version_compare($this->getAttribute(PDO::ATTR_SERVER_VERSION), '3.7.11', '>=')) if (version_compare($this->getVersion(), '3.7.11', '>='))
{ {
return parent::insertBatch($table, $data); return parent::insertBatch($table, $data);
} }
@ -145,4 +145,17 @@ class Driver extends AbstractDriver {
return [$sql, NULL]; return [$sql, NULL];
} }
/**
* Generate the returning clause for the current database
*
* @param string $query
* @param string $select
* @return string
*/
public function returning(string $query, string $select): string
{
// Return the same query, as the returning clause is not supported
return $query;
}
} }

26
src/QueryType.php Normal file
View File

@ -0,0 +1,26 @@
<?php declare(strict_types=1);
/**
* Query
*
* SQL Query Builder / Database Abstraction Layer
*
* PHP version 7.2
*
* @package Query
* @author Timothy J. Warren <tim@timshomepage.net>
* @copyright 2012 - 2019 Timothy J. Warren
* @license http://www.opensource.org/licenses/mit-license.html MIT License
* @link https://git.timshomepage.net/aviat/Query
* @version 3.0.0
*/
namespace Query;
/**
* 'Enum' of query types
*/
class QueryType {
public const SELECT = 'select';
public const INSERT = 'insert';
public const UPDATE = 'update';
public const DELETE = 'delete';
}

View File

@ -131,5 +131,12 @@ abstract class BaseDriverTest extends TestCase {
$funcs = self::$db->getFunctions(); $funcs = self::$db->getFunctions();
$this->assertTrue(\is_array($funcs)); $this->assertTrue(\is_array($funcs));
} }
public function testGetVersion(): void
{
$version = self::$db->getVersion();
$this->assertTrue(is_string($version));
$this->assertTrue(strlen($version) > 0);
}
} }
// End of db_test.php // End of db_test.php

View File

@ -24,6 +24,7 @@ class ConnectionManagerTest extends TestCase {
public static function setUpBeforeClass(): void public static function setUpBeforeClass(): void
{ {
ConnectionManager::getInstance();
self::$instance = ConnectionManager::getInstance(); self::$instance = ConnectionManager::getInstance();
} }

View File

@ -23,7 +23,6 @@ use TypeError;
/** /**
* MySQLTest class. * MySQLTest class.
* *
* @covers \Query\Drivers\Mysql\Driver
* @requires extension pdo_mysql * @requires extension pdo_mysql
*/ */
class MySQLDriverTest extends BaseDriverTest { class MySQLDriverTest extends BaseDriverTest {

View File

@ -25,7 +25,6 @@ use TypeError;
* *
* @extends DBTest * @extends DBTest
* @requires extension pdo_pgsql * @requires extension pdo_pgsql
* @covers \Query\Drivers\Pgsql\Driver
*/ */
class PgSQLDriverTest extends BaseDriverTest { class PgSQLDriverTest extends BaseDriverTest {

View File

@ -25,7 +25,6 @@ use Query\Tests\BaseDriverTest;
* *
* @extends DBTest * @extends DBTest
* @requires extension pdo_sqlite * @requires extension pdo_sqlite
* @covers \Query\Drivers\Sqlite\Driver
*/ */
class SQLiteDriverTest extends BaseDriverTest { class SQLiteDriverTest extends BaseDriverTest {
@ -253,6 +252,9 @@ SQL;
public function testGetDBs(): void public function testGetDBs(): void
{ {
$driverSQL = self::$db->getSql()->dbList();
$this->assertEqual('', $driverSQL);
$this->assertNull(self::$db->getDbs()); $this->assertNull(self::$db->getDbs());
} }

View File

@ -35,7 +35,11 @@ namespace Query\Tests {
{ {
$class = \get_class($this); $class = \get_class($this);
echo 'Ran test suite: ' . $class . '<br />'; if (PHP_SAPI !== 'cli')
{
echo 'Running test suite: ' . $class . '<br />';
flush();
}
if (method_exists($class, 'setupBeforeClass')) { if (method_exists($class, 'setupBeforeClass')) {
$class::setupBeforeClass(); $class::setupBeforeClass();