Prepwork for 'returning' method of Query builder
This commit is contained in:
parent
78705bf796
commit
2bf8897918
30
README.md
30
README.md
@ -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
|
||||||
@ -40,7 +38,7 @@ $params = array(
|
|||||||
'database' => 'test_db',
|
'database' => 'test_db',
|
||||||
|
|
||||||
// Only required for
|
// Only required for
|
||||||
// SQLite
|
// SQLite
|
||||||
'file' => '/path/to/db/file',
|
'file' => '/path/to/db/file',
|
||||||
|
|
||||||
// Optional parameters
|
// Optional parameters
|
||||||
@ -78,12 +76,12 @@ Query('old')->query($sql);
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Running Queries
|
### Running Queries
|
||||||
Query is based on CodeIgniter's [Query Builder](http://www.codeigniter.com/user_guide/database/query_builder.html) class.
|
Query is based on CodeIgniter's [Query Builder](http://www.codeigniter.com/user_guide/database/query_builder.html) class.
|
||||||
However, it has camelCased method names, and does not implement the caching methods.
|
However, it has camelCased method names, and does not implement the caching methods.
|
||||||
For specific query builder methods, see the [class documentation](https://gitdev.timshomepage.net/Query/apiDocumentation/classes/Query_QueryBuilder.html#methods).
|
For specific query builder methods, see the [class documentation](https://gitdev.timshomepage.net/Query/apiDocumentation/classes/Query_QueryBuilder.html#methods).
|
||||||
|
|
||||||
Other database methods not directly involved in building queries, are also available from the query builder object.
|
Other database methods not directly involved in building queries, are also available from the query builder object.
|
||||||
The methods available depend on the database, but common methods are documented
|
The methods available depend on the database, but common methods are documented
|
||||||
[here](https://gitdev.timshomepage.net/Query/apiDocumentation/classes/Query_Drivers_AbstractDriver.html#methods).
|
[here](https://gitdev.timshomepage.net/Query/apiDocumentation/classes/Query_Drivers_AbstractDriver.html#methods).
|
||||||
|
|
||||||
#### You can also run queries manually.
|
#### You can also run queries manually.
|
||||||
@ -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,9 +118,9 @@ 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).
|
||||||
|
|
||||||
```php
|
```php
|
||||||
<?php
|
<?php
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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
|
||||||
*
|
*
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -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]];
|
||||||
|
@ -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
26
src/QueryType.php
Normal 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';
|
||||||
|
}
|
@ -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
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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 {
|
||||||
|
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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();
|
||||||
|
Loading…
Reference in New Issue
Block a user