Set consistent code style
This commit is contained in:
parent
94d1cbb09b
commit
cf2255ce87
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query;
|
namespace Query;
|
||||||
|
|
||||||
use DomainException;
|
use DomainException;
|
||||||
@ -22,8 +23,8 @@ use stdClass;
|
|||||||
* Connection manager class to manage connections for the
|
* Connection manager class to manage connections for the
|
||||||
* Query method
|
* Query method
|
||||||
*/
|
*/
|
||||||
final class ConnectionManager {
|
final class ConnectionManager
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Map of named database connections
|
* Map of named database connections
|
||||||
*/
|
*/
|
||||||
@ -91,7 +92,6 @@ final class ConnectionManager {
|
|||||||
/**
|
/**
|
||||||
* Returns the connection specified by the name given
|
* Returns the connection specified by the name given
|
||||||
*
|
*
|
||||||
* @param string $name
|
|
||||||
* @throws Exception\NonExistentConnectionException
|
* @throws Exception\NonExistentConnectionException
|
||||||
*/
|
*/
|
||||||
public function getConnection(string $name = ''): QueryBuilderInterface
|
public function getConnection(string $name = ''): QueryBuilderInterface
|
||||||
@ -113,9 +113,6 @@ final class ConnectionManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse the passed parameters and return a connection
|
* Parse the passed parameters and return a connection
|
||||||
*
|
|
||||||
* @param array|object $params
|
|
||||||
* @return QueryBuilderInterface
|
|
||||||
*/
|
*/
|
||||||
public function connect(array|object $params): QueryBuilderInterface
|
public function connect(array|object $params): QueryBuilderInterface
|
||||||
{
|
{
|
||||||
@ -138,7 +135,6 @@ final class ConnectionManager {
|
|||||||
// Create Query Builder object
|
// Create Query Builder object
|
||||||
$conn = new QueryBuilder($db, new QueryParser($db));
|
$conn = new QueryBuilder($db, new QueryParser($db));
|
||||||
|
|
||||||
|
|
||||||
// Save it for later
|
// Save it for later
|
||||||
if (isset($params->alias))
|
if (isset($params->alias))
|
||||||
{
|
{
|
||||||
@ -155,9 +151,7 @@ final class ConnectionManager {
|
|||||||
/**
|
/**
|
||||||
* Parses params into a dsn and option array
|
* Parses params into a dsn and option array
|
||||||
*
|
*
|
||||||
* @param array|object $rawParams
|
|
||||||
* @throws Exception\BadDBDriverException
|
* @throws Exception\BadDBDriverException
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
public function parseParams(array|object $rawParams): array
|
public function parseParams(array|object $rawParams): array
|
||||||
{
|
{
|
||||||
@ -183,7 +177,6 @@ final class ConnectionManager {
|
|||||||
// Create the dsn for the database to connect to
|
// Create the dsn for the database to connect to
|
||||||
$dsn = strtolower($dbType) === 'sqlite' ? $params->file : $this->createDsn($dbType, $params);
|
$dsn = strtolower($dbType) === 'sqlite' ? $params->file : $this->createDsn($dbType, $params);
|
||||||
|
|
||||||
|
|
||||||
return [$dsn, $dbType, $params, $options];
|
return [$dsn, $dbType, $params, $options];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -209,7 +202,7 @@ final class ConnectionManager {
|
|||||||
'prefix' => 'prefix',
|
'prefix' => 'prefix',
|
||||||
'options' => 'options',
|
'options' => 'options',
|
||||||
'database' => 'database',
|
'database' => 'database',
|
||||||
'alias' => 'alias'
|
'alias' => 'alias',
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($params as $key => $val)
|
foreach ($params as $key => $val)
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers;
|
namespace Query\Drivers;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
@ -29,10 +30,8 @@ use function is_string;
|
|||||||
*
|
*
|
||||||
* Extends PDO to simplify cross-database issues
|
* Extends PDO to simplify cross-database issues
|
||||||
*/
|
*/
|
||||||
abstract class AbstractDriver
|
abstract class AbstractDriver extends PDO implements DriverInterface
|
||||||
extends PDO
|
{
|
||||||
implements DriverInterface {
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to the last executed query
|
* Reference to the last executed query
|
||||||
*/
|
*/
|
||||||
@ -76,7 +75,7 @@ abstract class AbstractDriver
|
|||||||
/**
|
/**
|
||||||
* PDO constructor wrapper
|
* PDO constructor wrapper
|
||||||
*/
|
*/
|
||||||
public function __construct(string $dsn, string $username=NULL, string $password=NULL, array $driverOptions=[])
|
public function __construct(string $dsn, ?string $username=NULL, ?string $password=NULL, array $driverOptions=[])
|
||||||
{
|
{
|
||||||
// Set PDO to display errors as exceptions, and apply driver options
|
// Set PDO to display errors as exceptions, and apply driver options
|
||||||
$driverOptions[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
|
$driverOptions[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
|
||||||
@ -85,23 +84,6 @@ abstract class AbstractDriver
|
|||||||
$this->_loadSubClasses();
|
$this->_loadSubClasses();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Loads the subclasses for the driver
|
|
||||||
*/
|
|
||||||
protected function _loadSubClasses(): void
|
|
||||||
{
|
|
||||||
// Load the sql and util class for the driver
|
|
||||||
$thisClass = $this::class;
|
|
||||||
$nsArray = explode("\\", $thisClass);
|
|
||||||
array_pop($nsArray);
|
|
||||||
$driver = array_pop($nsArray);
|
|
||||||
$sqlClass = __NAMESPACE__ . "\\{$driver}\\SQL";
|
|
||||||
$utilClass = __NAMESPACE__ . "\\{$driver}\\Util";
|
|
||||||
|
|
||||||
$this->driverSQL = new $sqlClass();
|
|
||||||
$this->util = new $utilClass($this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allow invoke to work on table object
|
* Allow invoke to work on table object
|
||||||
*
|
*
|
||||||
@ -114,14 +96,30 @@ abstract class AbstractDriver
|
|||||||
isset($this->$name)
|
isset($this->$name)
|
||||||
&& is_object($this->$name)
|
&& is_object($this->$name)
|
||||||
&& method_exists($this->$name, '__invoke')
|
&& method_exists($this->$name, '__invoke')
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
return call_user_func_array([$this->$name, '__invoke'], $args);
|
return call_user_func_array([$this->$name, '__invoke'], $args);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the subclasses for the driver
|
||||||
|
*/
|
||||||
|
protected function _loadSubClasses(): void
|
||||||
|
{
|
||||||
|
// Load the sql and util class for the driver
|
||||||
|
$thisClass = $this::class;
|
||||||
|
$nsArray = explode('\\', $thisClass);
|
||||||
|
array_pop($nsArray);
|
||||||
|
$driver = array_pop($nsArray);
|
||||||
|
$sqlClass = __NAMESPACE__ . "\\{$driver}\\SQL";
|
||||||
|
$utilClass = __NAMESPACE__ . "\\{$driver}\\Util";
|
||||||
|
|
||||||
|
$this->driverSQL = new $sqlClass();
|
||||||
|
$this->util = new $utilClass($this);
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// ! Accessors / Mutators
|
// ! Accessors / Mutators
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -282,6 +280,7 @@ abstract class AbstractDriver
|
|||||||
// Fix functions
|
// Fix functions
|
||||||
$funcs = [];
|
$funcs = [];
|
||||||
preg_match_all("#{$this->escapeCharOpen}([a-zA-Z0-9_]+(\((.*?)\))){$this->escapeCharClose}#iu", $raw, $funcs, PREG_SET_ORDER);
|
preg_match_all("#{$this->escapeCharOpen}([a-zA-Z0-9_]+(\((.*?)\))){$this->escapeCharClose}#iu", $raw, $funcs, PREG_SET_ORDER);
|
||||||
|
|
||||||
foreach ($funcs as $f)
|
foreach ($funcs as $f)
|
||||||
{
|
{
|
||||||
// Unquote the function
|
// Unquote the function
|
||||||
@ -308,6 +307,7 @@ abstract class AbstractDriver
|
|||||||
{
|
{
|
||||||
$tables = $this->driverQuery('tableList');
|
$tables = $this->driverQuery('tableList');
|
||||||
natsort($tables);
|
natsort($tables);
|
||||||
|
|
||||||
return $tables;
|
return $tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,6 +326,7 @@ abstract class AbstractDriver
|
|||||||
{
|
{
|
||||||
$views = $this->driverQuery('viewList');
|
$views = $this->driverQuery('viewList');
|
||||||
sort($views);
|
sort($views);
|
||||||
|
|
||||||
return $views;
|
return $views;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,6 +457,7 @@ abstract class AbstractDriver
|
|||||||
if (preg_match($regex, $this->lastQuery, $output) > 0)
|
if (preg_match($regex, $this->lastQuery, $output) > 0)
|
||||||
{
|
{
|
||||||
$stmt = $this->query("SELECT COUNT(*) FROM {$output[1]}");
|
$stmt = $this->query("SELECT COUNT(*) FROM {$output[1]}");
|
||||||
|
|
||||||
return (int) $stmt->fetchColumn();
|
return (int) $stmt->fetchColumn();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,6 +474,7 @@ abstract class AbstractDriver
|
|||||||
|
|
||||||
// Values for insertion
|
// Values for insertion
|
||||||
$vals = [];
|
$vals = [];
|
||||||
|
|
||||||
foreach ($data as $group)
|
foreach ($data as $group)
|
||||||
{
|
{
|
||||||
$vals = [...$vals, ...array_values($group)];
|
$vals = [...$vals, ...array_values($group)];
|
||||||
@ -533,6 +536,7 @@ abstract class AbstractDriver
|
|||||||
$line = $this->quoteIdent($field) . " = CASE\n";
|
$line = $this->quoteIdent($field) . " = CASE\n";
|
||||||
|
|
||||||
$cases = [];
|
$cases = [];
|
||||||
|
|
||||||
foreach ($data as $case)
|
foreach ($data as $case)
|
||||||
{
|
{
|
||||||
if (array_key_exists($field, $case))
|
if (array_key_exists($field, $case))
|
||||||
@ -553,6 +557,7 @@ abstract class AbstractDriver
|
|||||||
$sql .= implode(",\n", $fieldLines) . "\n";
|
$sql .= implode(",\n", $fieldLines) . "\n";
|
||||||
|
|
||||||
$whereValues = array_column($data, $where);
|
$whereValues = array_column($data, $where);
|
||||||
|
|
||||||
foreach ($whereValues as $value)
|
foreach ($whereValues as $value)
|
||||||
{
|
{
|
||||||
$insertData[] = $value;
|
$insertData[] = $value;
|
||||||
@ -579,6 +584,7 @@ abstract class AbstractDriver
|
|||||||
$sql .= $this->quoteTable($table);
|
$sql .= $this->quoteTable($table);
|
||||||
|
|
||||||
$this->statement = $this->query($sql);
|
$this->statement = $this->query($sql);
|
||||||
|
|
||||||
return $this->statement;
|
return $this->statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -592,9 +598,6 @@ abstract class AbstractDriver
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method for quote_ident
|
* Helper method for quote_ident
|
||||||
*
|
|
||||||
* @param mixed $str
|
|
||||||
* @return mixed
|
|
||||||
*/
|
*/
|
||||||
public function _quote(mixed $str): mixed
|
public function _quote(mixed $str): mixed
|
||||||
{
|
{
|
||||||
@ -608,7 +611,6 @@ abstract class AbstractDriver
|
|||||||
)
|
)
|
||||||
? "{$this->escapeCharOpen}{$str}{$this->escapeCharClose}"
|
? "{$this->escapeCharOpen}{$str}{$this->escapeCharClose}"
|
||||||
: $str;
|
: $str;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,13 +13,14 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers;
|
namespace Query\Drivers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parent for database-specific syntax subclasses
|
* Parent for database-specific syntax subclasses
|
||||||
*/
|
*/
|
||||||
abstract class AbstractSQL implements SQLInterface {
|
abstract class AbstractSQL implements SQLInterface
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Limit clause
|
* Limit clause
|
||||||
*/
|
*/
|
||||||
|
@ -13,13 +13,16 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers;
|
namespace Query\Drivers;
|
||||||
|
|
||||||
|
use function arrayZipper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract class defining database / table creation methods
|
* Abstract class defining database / table creation methods
|
||||||
*/
|
*/
|
||||||
abstract class AbstractUtil {
|
abstract class AbstractUtil
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Save a reference to the connection object for later use
|
* Save a reference to the connection object for later use
|
||||||
*/
|
*/
|
||||||
@ -48,13 +51,14 @@ abstract class AbstractUtil {
|
|||||||
// 'constraint' => ...,
|
// 'constraint' => ...,
|
||||||
// 'index' => ...,
|
// 'index' => ...,
|
||||||
// ]
|
// ]
|
||||||
$columnArray = \arrayZipper([
|
$columnArray = arrayZipper([
|
||||||
'type' => $fields,
|
'type' => $fields,
|
||||||
'constraint' => $constraints
|
'constraint' => $constraints,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Join column definitions together
|
// Join column definitions together
|
||||||
$columns = [];
|
$columns = [];
|
||||||
|
|
||||||
foreach ($columnArray as $n => $props)
|
foreach ($columnArray as $n => $props)
|
||||||
{
|
{
|
||||||
$str = $this->getDriver()->quoteIdent($n);
|
$str = $this->getDriver()->quoteIdent($n);
|
||||||
@ -85,16 +89,11 @@ abstract class AbstractUtil {
|
|||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Return an SQL file with the database table structure
|
* Return an SQL file with the database table structure
|
||||||
*
|
|
||||||
* @abstract
|
|
||||||
*/
|
*/
|
||||||
abstract public function backupStructure(): string;
|
abstract public function backupStructure(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an SQL file with the database data as insert statements
|
* Return an SQL file with the database data as insert statements
|
||||||
*
|
|
||||||
* @abstract
|
|
||||||
*/
|
*/
|
||||||
abstract public function backupData(): string;
|
abstract public function backupData(): string;
|
||||||
|
|
||||||
}
|
}
|
@ -13,9 +13,9 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers;
|
namespace Query\Drivers;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
|
||||||
use PDO;
|
use PDO;
|
||||||
use PDOStatement;
|
use PDOStatement;
|
||||||
|
|
||||||
@ -36,12 +36,12 @@ use PDOStatement;
|
|||||||
* @method rollback(): bool
|
* @method rollback(): bool
|
||||||
* @method setAttribute(int $attribute, $value): bool
|
* @method setAttribute(int $attribute, $value): bool
|
||||||
*/
|
*/
|
||||||
interface DriverInterface /* extends the interface of PDO */ {
|
interface DriverInterface // extends the interface of PDO
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Constructor/Connection method
|
* Constructor/Connection method
|
||||||
*/
|
*/
|
||||||
public function __construct(string $dsn, string $username=NULL, string $password=NULL, array $driverOptions = []);
|
public function __construct(string $dsn, ?string $username=NULL, ?string $password=NULL, array $driverOptions = []);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simplifies prepared statements for database queries
|
* Simplifies prepared statements for database queries
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers\Mysql;
|
namespace Query\Drivers\Mysql;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
@ -22,8 +23,8 @@ use function defined;
|
|||||||
/**
|
/**
|
||||||
* MySQL specific class
|
* MySQL specific class
|
||||||
*/
|
*/
|
||||||
class Driver extends AbstractDriver {
|
class Driver extends AbstractDriver
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Set the backtick as the MySQL escape character
|
* Set the backtick as the MySQL escape character
|
||||||
*/
|
*/
|
||||||
@ -39,7 +40,7 @@ class Driver extends AbstractDriver {
|
|||||||
*
|
*
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public function __construct(string $dsn, string $username=NULL, string $password=NULL, array $options=[])
|
public function __construct(string $dsn, ?string $username=NULL, ?string $password=NULL, array $options=[])
|
||||||
{
|
{
|
||||||
// Set the charset to UTF-8
|
// Set the charset to UTF-8
|
||||||
if (defined('\\PDO::MYSQL_ATTR_INIT_COMMAND'))
|
if (defined('\\PDO::MYSQL_ATTR_INIT_COMMAND'))
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers\Mysql;
|
namespace Query\Drivers\Mysql;
|
||||||
|
|
||||||
use Query\Drivers\AbstractSQL;
|
use Query\Drivers\AbstractSQL;
|
||||||
@ -20,8 +21,8 @@ use Query\Drivers\AbstractSQL;
|
|||||||
/**
|
/**
|
||||||
* MySQL specific SQL
|
* MySQL specific SQL
|
||||||
*/
|
*/
|
||||||
class SQL extends AbstractSQL {
|
class SQL extends AbstractSQL
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Limit clause
|
* Limit clause
|
||||||
*/
|
*/
|
||||||
@ -56,10 +57,9 @@ class SQL extends AbstractSQL {
|
|||||||
*/
|
*/
|
||||||
public function dbList(): string
|
public function dbList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SHOW DATABASES WHERE `Database` NOT IN ('information_schema','mysql')
|
SHOW DATABASES WHERE `Database` NOT IN ('information_schema','mysql')
|
||||||
SQL;
|
SQL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -82,7 +82,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function systemTableList(): string
|
public function systemTableList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT `TABLE_NAME` FROM `information_schema`.`TABLES`
|
SELECT `TABLE_NAME` FROM `information_schema`.`TABLES`
|
||||||
WHERE `TABLE_SCHEMA`='information_schema'
|
WHERE `TABLE_SCHEMA`='information_schema'
|
||||||
SQL;
|
SQL;
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers\Mysql;
|
namespace Query\Drivers\Mysql;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
@ -21,8 +22,8 @@ use Query\Drivers\AbstractUtil;
|
|||||||
/**
|
/**
|
||||||
* MySQL-specific backup, import and creation methods
|
* MySQL-specific backup, import and creation methods
|
||||||
*/
|
*/
|
||||||
class Util extends AbstractUtil {
|
class Util extends AbstractUtil
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Create an SQL backup file for the current database's structure
|
* Create an SQL backup file for the current database's structure
|
||||||
*/
|
*/
|
||||||
@ -57,7 +58,6 @@ class Util extends AbstractUtil {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
$string[] = $row['Create Table'];
|
$string[] = $row['Create Table'];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,7 +105,7 @@ class Util extends AbstractUtil {
|
|||||||
$row = array_values($row);
|
$row = array_values($row);
|
||||||
|
|
||||||
// Quote strings
|
// Quote strings
|
||||||
$row = array_map(fn ($r) => is_string($r) ? $driver->quote($r) : $r, $row);
|
$row = array_map(static fn ($r) => is_string($r) ? $driver->quote($r) : $r, $row);
|
||||||
$row = array_map('trim', $row);
|
$row = array_map('trim', $row);
|
||||||
|
|
||||||
$rowString = 'INSERT INTO `' . trim($t) . '` (`' . implode('`,`', $columns) . '`) VALUES (' . implode(',', $row) . ');';
|
$rowString = 'INSERT INTO `' . trim($t) . '` (`' . implode('`,`', $columns) . '`) VALUES (' . implode(',', $row) . ');';
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers\Pgsql;
|
namespace Query\Drivers\Pgsql;
|
||||||
|
|
||||||
use Query\Drivers\AbstractDriver;
|
use Query\Drivers\AbstractDriver;
|
||||||
@ -20,14 +21,14 @@ use Query\Drivers\AbstractDriver;
|
|||||||
/**
|
/**
|
||||||
* PostgreSQL specific class
|
* PostgreSQL specific class
|
||||||
*/
|
*/
|
||||||
class Driver extends AbstractDriver {
|
class Driver extends AbstractDriver
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Connect to a PosgreSQL database
|
* Connect to a PosgreSQL database
|
||||||
*
|
*
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
*/
|
*/
|
||||||
public function __construct(string $dsn, string $username=NULL, string $password=NULL, array $options=[])
|
public function __construct(string $dsn, ?string $username=NULL, ?string $password=NULL, array $options=[])
|
||||||
{
|
{
|
||||||
if ( ! str_contains($dsn, 'pgsql'))
|
if ( ! str_contains($dsn, 'pgsql'))
|
||||||
{
|
{
|
||||||
@ -65,7 +66,7 @@ SQL;
|
|||||||
|
|
||||||
foreach ($keys as &$key)
|
foreach ($keys as &$key)
|
||||||
{
|
{
|
||||||
foreach(['update', 'delete'] AS $type)
|
foreach (['update', 'delete'] as $type)
|
||||||
{
|
{
|
||||||
if ( ! isset($valueMap[$key[$type]]))
|
if ( ! isset($valueMap[$key[$type]]))
|
||||||
{
|
{
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers\Pgsql;
|
namespace Query\Drivers\Pgsql;
|
||||||
|
|
||||||
use Query\Drivers\AbstractSQL;
|
use Query\Drivers\AbstractSQL;
|
||||||
@ -20,8 +21,8 @@ use Query\Drivers\AbstractSQL;
|
|||||||
/**
|
/**
|
||||||
* PostgreSQL specific SQL
|
* PostgreSQL specific SQL
|
||||||
*/
|
*/
|
||||||
class SQL extends AbstractSQL {
|
class SQL extends AbstractSQL
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Get the query plan for the sql query
|
* Get the query plan for the sql query
|
||||||
*/
|
*/
|
||||||
@ -43,7 +44,7 @@ class SQL extends AbstractSQL {
|
|||||||
*/
|
*/
|
||||||
public function dbList(): string
|
public function dbList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT "datname" FROM "pg_database"
|
SELECT "datname" FROM "pg_database"
|
||||||
WHERE "datname" NOT IN ('template0','template1')
|
WHERE "datname" NOT IN ('template0','template1')
|
||||||
ORDER BY "datname" ASC
|
ORDER BY "datname" ASC
|
||||||
@ -55,7 +56,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function tableList(): string
|
public function tableList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT "table_name"
|
SELECT "table_name"
|
||||||
FROM "information_schema"."tables"
|
FROM "information_schema"."tables"
|
||||||
WHERE "table_type" = 'BASE TABLE'
|
WHERE "table_type" = 'BASE TABLE'
|
||||||
@ -69,7 +70,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function systemTableList(): string
|
public function systemTableList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT "table_name"
|
SELECT "table_name"
|
||||||
FROM "information_schema"."tables"
|
FROM "information_schema"."tables"
|
||||||
WHERE "table_type" = 'BASE TABLE'
|
WHERE "table_type" = 'BASE TABLE'
|
||||||
@ -83,7 +84,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function viewList(): string
|
public function viewList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT "viewname" FROM "pg_views"
|
SELECT "viewname" FROM "pg_views"
|
||||||
WHERE "schemaname" NOT IN
|
WHERE "schemaname" NOT IN
|
||||||
('pg_catalog', 'information_schema')
|
('pg_catalog', 'information_schema')
|
||||||
@ -97,7 +98,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function triggerList(): string
|
public function triggerList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT *
|
SELECT *
|
||||||
FROM "information_schema"."triggers"
|
FROM "information_schema"."triggers"
|
||||||
WHERE "trigger_schema" NOT IN
|
WHERE "trigger_schema" NOT IN
|
||||||
@ -118,7 +119,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function procedureList(): string
|
public function procedureList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT "routine_name"
|
SELECT "routine_name"
|
||||||
FROM "information_schema"."routines"
|
FROM "information_schema"."routines"
|
||||||
WHERE "specific_schema" NOT IN
|
WHERE "specific_schema" NOT IN
|
||||||
@ -132,7 +133,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function sequenceList(): string
|
public function sequenceList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT "c"."relname"
|
SELECT "c"."relname"
|
||||||
FROM "pg_class" "c"
|
FROM "pg_class" "c"
|
||||||
WHERE "c"."relkind" = 'S'
|
WHERE "c"."relkind" = 'S'
|
||||||
@ -164,7 +165,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function typeList(): string
|
public function typeList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT "typname" FROM "pg_catalog"."pg_type"
|
SELECT "typname" FROM "pg_catalog"."pg_type"
|
||||||
WHERE "typname" !~ '^pg_|_'
|
WHERE "typname" !~ '^pg_|_'
|
||||||
AND "typtype" = 'b'
|
AND "typtype" = 'b'
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers\Pgsql;
|
namespace Query\Drivers\Pgsql;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
@ -21,8 +22,8 @@ use Query\Drivers\AbstractUtil;
|
|||||||
/**
|
/**
|
||||||
* Postgres-specific backup, import and creation methods
|
* Postgres-specific backup, import and creation methods
|
||||||
*/
|
*/
|
||||||
class Util extends AbstractUtil {
|
class Util extends AbstractUtil
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Create an SQL backup file for the current database's structure
|
* Create an SQL backup file for the current database's structure
|
||||||
*/
|
*/
|
||||||
@ -76,7 +77,6 @@ class Util extends AbstractUtil {
|
|||||||
$row = array_map([$this->getDriver(), 'quote'], $row);
|
$row = array_map([$this->getDriver(), 'quote'], $row);
|
||||||
$row = array_map('trim', $row);
|
$row = array_map('trim', $row);
|
||||||
|
|
||||||
|
|
||||||
$rowString = 'INSERT INTO "' . trim($t) . '" ("' . implode('","', $columns) . '") VALUES (' . implode(',', $row) . ');';
|
$rowString = 'INSERT INTO "' . trim($t) . '" ("' . implode('","', $columns) . '") VALUES (' . implode(',', $row) . ');';
|
||||||
|
|
||||||
$row = NULL;
|
$row = NULL;
|
||||||
|
@ -13,13 +13,14 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers;
|
namespace Query\Drivers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for database-specific syntax subclasses
|
* Interface for database-specific syntax subclasses
|
||||||
*/
|
*/
|
||||||
interface SQLInterface {
|
interface SQLInterface
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Get database specific sql for limit clause
|
* Get database specific sql for limit clause
|
||||||
*/
|
*/
|
||||||
|
@ -13,18 +13,20 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers\Sqlite;
|
namespace Query\Drivers\Sqlite;
|
||||||
|
|
||||||
use function is_array;
|
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
use Query\Drivers\AbstractDriver;
|
use Query\Drivers\AbstractDriver;
|
||||||
|
use function is_array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* SQLite specific class
|
* SQLite specific class
|
||||||
*/
|
*/
|
||||||
class Driver extends AbstractDriver {
|
class Driver extends AbstractDriver
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* SQLite has a truncate optimization,
|
* SQLite has a truncate optimization,
|
||||||
* but no support for the actual keyword
|
* but no support for the actual keyword
|
||||||
@ -34,7 +36,7 @@ class Driver extends AbstractDriver {
|
|||||||
/**
|
/**
|
||||||
* Open SQLite Database
|
* Open SQLite Database
|
||||||
*/
|
*/
|
||||||
public function __construct(string $dsn, string $user=NULL, string $pass=NULL, array $driverOptions=[])
|
public function __construct(string $dsn, ?string $user=NULL, ?string $pass=NULL, array $driverOptions=[])
|
||||||
{
|
{
|
||||||
if ( ! str_contains($dsn, 'sqlite:'))
|
if ( ! str_contains($dsn, 'sqlite:'))
|
||||||
{
|
{
|
||||||
@ -59,6 +61,7 @@ class Driver extends AbstractDriver {
|
|||||||
{
|
{
|
||||||
$sql = $this->getSql()->tableList();
|
$sql = $this->getSql()->tableList();
|
||||||
$res = $this->query($sql);
|
$res = $this->query($sql);
|
||||||
|
|
||||||
return dbFilter($res->fetchAll(PDO::FETCH_ASSOC), 'name');
|
return dbFilter($res->fetchAll(PDO::FETCH_ASSOC), 'name');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +79,7 @@ class Driver extends AbstractDriver {
|
|||||||
'parent_table' => $row['table'],
|
'parent_table' => $row['table'],
|
||||||
'parent_column' => $row['to'],
|
'parent_column' => $row['to'],
|
||||||
'update' => $row['on_update'],
|
'update' => $row['on_update'],
|
||||||
'delete' => $row['on_delete']
|
'delete' => $row['on_delete'],
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +90,7 @@ class Driver extends AbstractDriver {
|
|||||||
* Create sql for batch insert
|
* Create sql for batch insert
|
||||||
*
|
*
|
||||||
* @codeCoverageIgnore
|
* @codeCoverageIgnore
|
||||||
* @return array[]|string[]|null[]
|
* @return array[]|null[]|string[]
|
||||||
*/
|
*/
|
||||||
public function insertBatch(string $table, array $data=[]): array
|
public function insertBatch(string $table, array $data=[]): array
|
||||||
{
|
{
|
||||||
@ -115,6 +118,7 @@ class Driver extends AbstractDriver {
|
|||||||
// Create a key-value mapping for each field
|
// Create a key-value mapping for each field
|
||||||
$first = array_shift($data);
|
$first = array_shift($data);
|
||||||
$cols = [];
|
$cols = [];
|
||||||
|
|
||||||
foreach ($first as $colName => $datum)
|
foreach ($first as $colName => $datum)
|
||||||
{
|
{
|
||||||
$cols[] = $this->_quote($datum) . ' AS ' . $this->quoteIdent($colName);
|
$cols[] = $this->_quote($datum) . ' AS ' . $this->quoteIdent($colName);
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers\Sqlite;
|
namespace Query\Drivers\Sqlite;
|
||||||
|
|
||||||
use Query\Drivers\AbstractSQL;
|
use Query\Drivers\AbstractSQL;
|
||||||
@ -21,8 +22,8 @@ use Query\Exception\NotImplementedException;
|
|||||||
/**
|
/**
|
||||||
* SQLite Specific SQL
|
* SQLite Specific SQL
|
||||||
*/
|
*/
|
||||||
class SQL extends AbstractSQL {
|
class SQL extends AbstractSQL
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Get the query plan for the sql query
|
* Get the query plan for the sql query
|
||||||
*/
|
*/
|
||||||
@ -53,7 +54,7 @@ class SQL extends AbstractSQL {
|
|||||||
*/
|
*/
|
||||||
public function tableList(): string
|
public function tableList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT "name" FROM (
|
SELECT "name" FROM (
|
||||||
SELECT * FROM "sqlite_master" UNION ALL
|
SELECT * FROM "sqlite_master" UNION ALL
|
||||||
SELECT * FROM "sqlite_temp_master"
|
SELECT * FROM "sqlite_temp_master"
|
||||||
@ -74,7 +75,7 @@ SQL;
|
|||||||
return [
|
return [
|
||||||
'sqlite_master',
|
'sqlite_master',
|
||||||
'sqlite_temp_master',
|
'sqlite_temp_master',
|
||||||
'sqlite_sequence'
|
'sqlite_sequence',
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +84,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function viewList(): string
|
public function viewList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT "name" FROM "sqlite_master" WHERE "type" = 'view'
|
SELECT "name" FROM "sqlite_master" WHERE "type" = 'view'
|
||||||
SQL;
|
SQL;
|
||||||
}
|
}
|
||||||
@ -93,7 +94,7 @@ SQL;
|
|||||||
*/
|
*/
|
||||||
public function triggerList(): string
|
public function triggerList(): string
|
||||||
{
|
{
|
||||||
return <<<SQL
|
return <<<'SQL'
|
||||||
SELECT "name" FROM "sqlite_master" WHERE "type"='trigger'
|
SELECT "name" FROM "sqlite_master" WHERE "type"='trigger'
|
||||||
SQL;
|
SQL;
|
||||||
}
|
}
|
||||||
@ -157,7 +158,6 @@ SQL;
|
|||||||
SQL;
|
SQL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the list of indexes for the current table
|
* Get the list of indexes for the current table
|
||||||
*/
|
*/
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Drivers\Sqlite;
|
namespace Query\Drivers\Sqlite;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
@ -21,8 +22,8 @@ use Query\Drivers\AbstractUtil;
|
|||||||
/**
|
/**
|
||||||
* SQLite-specific backup, import and creation methods
|
* SQLite-specific backup, import and creation methods
|
||||||
*/
|
*/
|
||||||
class Util extends AbstractUtil {
|
class Util extends AbstractUtil
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Create an SQL backup file for the current database's data
|
* Create an SQL backup file for the current database's data
|
||||||
*/
|
*/
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Exception;
|
namespace Query\Exception;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
@ -20,5 +21,6 @@ use InvalidArgumentException;
|
|||||||
/**
|
/**
|
||||||
* Generic exception for bad drivers
|
* Generic exception for bad drivers
|
||||||
*/
|
*/
|
||||||
class BadDBDriverException extends InvalidArgumentException {
|
class BadDBDriverException extends InvalidArgumentException
|
||||||
|
{
|
||||||
}
|
}
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Exception;
|
namespace Query\Exception;
|
||||||
|
|
||||||
use InvalidArgumentException;
|
use InvalidArgumentException;
|
||||||
@ -20,5 +21,6 @@ use InvalidArgumentException;
|
|||||||
/**
|
/**
|
||||||
* Exception for missing database connection
|
* Exception for missing database connection
|
||||||
*/
|
*/
|
||||||
class NonExistentConnectionException extends InvalidArgumentException {
|
class NonExistentConnectionException extends InvalidArgumentException
|
||||||
|
{
|
||||||
}
|
}
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query\Exception;
|
namespace Query\Exception;
|
||||||
|
|
||||||
use BadMethodCallException;
|
use BadMethodCallException;
|
||||||
@ -20,5 +21,6 @@ use BadMethodCallException;
|
|||||||
/**
|
/**
|
||||||
* Exception for non-implemented method
|
* Exception for non-implemented method
|
||||||
*/
|
*/
|
||||||
class NotImplementedException extends BadMethodCallException{
|
class NotImplementedException extends BadMethodCallException
|
||||||
|
{
|
||||||
}
|
}
|
@ -13,12 +13,14 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query;
|
namespace Query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum of join types
|
* Enum of join types
|
||||||
*/
|
*/
|
||||||
enum JoinType: string {
|
enum JoinType: string
|
||||||
|
{
|
||||||
case CROSS = 'cross';
|
case CROSS = 'cross';
|
||||||
case INNER = 'inner';
|
case INNER = 'inner';
|
||||||
case OUTER = 'outer';
|
case OUTER = 'outer';
|
||||||
@ -35,4 +37,3 @@ enum JoinType: string {
|
|||||||
return self::from($val);
|
return self::from($val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,12 +13,14 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query;
|
namespace Query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 'Enum' of join types
|
* 'Enum' of join types
|
||||||
*/
|
*/
|
||||||
enum LikeType: string {
|
enum LikeType: string
|
||||||
|
{
|
||||||
case BEFORE = 'before';
|
case BEFORE = 'before';
|
||||||
case AFTER = 'after';
|
case AFTER = 'after';
|
||||||
case BOTH = 'both';
|
case BOTH = 'both';
|
||||||
|
@ -13,12 +13,14 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query;
|
namespace Query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum of query map types
|
* Enum of query map types
|
||||||
*/
|
*/
|
||||||
enum MapType: string {
|
enum MapType: string
|
||||||
|
{
|
||||||
case GROUP_END = 'group_end';
|
case GROUP_END = 'group_end';
|
||||||
case GROUP_START = 'group_start';
|
case GROUP_START = 'group_start';
|
||||||
case JOIN = 'join';
|
case JOIN = 'join';
|
||||||
|
@ -13,18 +13,20 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query;
|
namespace Query;
|
||||||
|
|
||||||
|
use PDOStatement;
|
||||||
use function is_array;
|
use function is_array;
|
||||||
use function is_int;
|
use function is_int;
|
||||||
use function mb_trim;
|
|
||||||
|
|
||||||
use PDOStatement;
|
use function mb_trim;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience class for creating sql queries
|
* Convenience class for creating sql queries
|
||||||
*/
|
*/
|
||||||
class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface {
|
class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface
|
||||||
|
{
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// ! Select Queries
|
// ! Select Queries
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -69,48 +71,52 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface {
|
|||||||
/**
|
/**
|
||||||
* Selects the maximum value of a field from a query
|
* Selects the maximum value of a field from a query
|
||||||
*
|
*
|
||||||
* @param string|bool $as
|
* @param bool|string $as
|
||||||
*/
|
*/
|
||||||
public function selectMax(string $field, $as=FALSE): self
|
public function selectMax(string $field, $as=FALSE): self
|
||||||
{
|
{
|
||||||
// Create the select string
|
// Create the select string
|
||||||
$this->state->appendSelectString(' MAX' . $this->_select($field, $as));
|
$this->state->appendSelectString(' MAX' . $this->_select($field, $as));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the minimum value of a field from a query
|
* Selects the minimum value of a field from a query
|
||||||
*
|
*
|
||||||
* @param string|bool $as
|
* @param bool|string $as
|
||||||
*/
|
*/
|
||||||
public function selectMin(string $field, $as=FALSE): self
|
public function selectMin(string $field, $as=FALSE): self
|
||||||
{
|
{
|
||||||
// Create the select string
|
// Create the select string
|
||||||
$this->state->appendSelectString(' MIN' . $this->_select($field, $as));
|
$this->state->appendSelectString(' MIN' . $this->_select($field, $as));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the average value of a field from a query
|
* Selects the average value of a field from a query
|
||||||
*
|
*
|
||||||
* @param string|bool $as
|
* @param bool|string $as
|
||||||
*/
|
*/
|
||||||
public function selectAvg(string $field, $as=FALSE): self
|
public function selectAvg(string $field, $as=FALSE): self
|
||||||
{
|
{
|
||||||
// Create the select string
|
// Create the select string
|
||||||
$this->state->appendSelectString(' AVG' . $this->_select($field, $as));
|
$this->state->appendSelectString(' AVG' . $this->_select($field, $as));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the sum of a field from a query
|
* Selects the sum of a field from a query
|
||||||
*
|
*
|
||||||
* @param string|bool $as
|
* @param bool|string $as
|
||||||
*/
|
*/
|
||||||
public function selectSum(string $field, $as=FALSE): self
|
public function selectSum(string $field, $as=FALSE): self
|
||||||
{
|
{
|
||||||
// Create the select string
|
// Create the select string
|
||||||
$this->state->appendSelectString(' SUM' . $this->_select($field, $as));
|
$this->state->appendSelectString(' SUM' . $this->_select($field, $as));
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,6 +145,7 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface {
|
|||||||
{
|
{
|
||||||
// Prepend the keyword to the select string
|
// Prepend the keyword to the select string
|
||||||
$this->state->setSelectString(' DISTINCT' . $this->state->getSelectString());
|
$this->state->setSelectString(' DISTINCT' . $this->state->getSelectString());
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -148,6 +155,7 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface {
|
|||||||
public function explain(): self
|
public function explain(): self
|
||||||
{
|
{
|
||||||
$this->explain = TRUE;
|
$this->explain = TRUE;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,8 +163,6 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface {
|
|||||||
* Specify the database table to select from
|
* Specify the database table to select from
|
||||||
*
|
*
|
||||||
* Alias of `from` method to better match CodeIgniter 4
|
* Alias of `from` method to better match CodeIgniter 4
|
||||||
*
|
|
||||||
* @param string $tableName
|
|
||||||
*/
|
*/
|
||||||
public function table(string $tableName): self
|
public function table(string $tableName): self
|
||||||
{
|
{
|
||||||
@ -514,6 +520,7 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface {
|
|||||||
{
|
{
|
||||||
$sql = 'SELECT * FROM ' . $this->driver->quoteTable($table);
|
$sql = 'SELECT * FROM ' . $this->driver->quoteTable($table);
|
||||||
$res = $this->driver->query($sql);
|
$res = $this->driver->query($sql);
|
||||||
|
|
||||||
return (int) (is_countable($res->fetchAll()) ? count($res->fetchAll()) : 0);
|
return (int) (is_countable($res->fetchAll()) ? count($res->fetchAll()) : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -589,6 +596,7 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface {
|
|||||||
[$sql, $data, $affectedRows] = $this->driver->updateBatch($table, $data, $where);
|
[$sql, $data, $affectedRows] = $this->driver->updateBatch($table, $data, $where);
|
||||||
|
|
||||||
$this->_run(QueryType::UPDATE_BATCH, $table, $sql, $data);
|
$this->_run(QueryType::UPDATE_BATCH, $table, $sql, $data);
|
||||||
|
|
||||||
return $affectedRows;
|
return $affectedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,14 +13,16 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query;
|
namespace Query;
|
||||||
|
|
||||||
use function regexInArray;
|
|
||||||
|
|
||||||
use BadMethodCallException;
|
use BadMethodCallException;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
use PDOStatement;
|
use PDOStatement;
|
||||||
use Query\Drivers\DriverInterface;
|
use Query\Drivers\DriverInterface;
|
||||||
|
use function is_string;
|
||||||
|
use function regexInArray;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method affectedRows(): int
|
* @method affectedRows(): int
|
||||||
@ -56,8 +58,8 @@ use Query\Drivers\DriverInterface;
|
|||||||
* @method setTablePrefix(string $prefix): void
|
* @method setTablePrefix(string $prefix): void
|
||||||
* @method truncate(string $table): PDOStatement
|
* @method truncate(string $table): PDOStatement
|
||||||
*/
|
*/
|
||||||
class QueryBuilderBase {
|
class QueryBuilderBase
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Convenience property for connection management
|
* Convenience property for connection management
|
||||||
*/
|
*/
|
||||||
@ -67,7 +69,7 @@ class QueryBuilderBase {
|
|||||||
* List of queries executed
|
* List of queries executed
|
||||||
*/
|
*/
|
||||||
public array $queries = [
|
public array $queries = [
|
||||||
'total_time' => 0
|
'total_time' => 0,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -110,8 +112,8 @@ class QueryBuilderBase {
|
|||||||
* Calls a function further down the inheritance chain.
|
* Calls a function further down the inheritance chain.
|
||||||
* 'Implements' methods on the driver object
|
* 'Implements' methods on the driver object
|
||||||
*
|
*
|
||||||
* @return mixed
|
|
||||||
* @throws BadMethodCallException
|
* @throws BadMethodCallException
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function __call(string $name, array $params)
|
public function __call(string $name, array $params)
|
||||||
{
|
{
|
||||||
@ -141,7 +143,7 @@ class QueryBuilderBase {
|
|||||||
// Escape the identifiers
|
// Escape the identifiers
|
||||||
$field = $this->driver->quoteIdent($field);
|
$field = $this->driver->quoteIdent($field);
|
||||||
|
|
||||||
if ( ! \is_string($as))
|
if ( ! is_string($as))
|
||||||
{
|
{
|
||||||
// @codeCoverageIgnoreStart
|
// @codeCoverageIgnoreStart
|
||||||
return $field;
|
return $field;
|
||||||
@ -149,6 +151,7 @@ class QueryBuilderBase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$as = $this->driver->quoteIdent($as);
|
$as = $this->driver->quoteIdent($as);
|
||||||
|
|
||||||
return "({$field}) AS {$as} ";
|
return "({$field}) AS {$as} ";
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -224,7 +227,7 @@ class QueryBuilderBase {
|
|||||||
'conjunction' => empty($this->state->getHavingMap())
|
'conjunction' => empty($this->state->getHavingMap())
|
||||||
? ' HAVING '
|
? ' HAVING '
|
||||||
: " {$conj} ",
|
: " {$conj} ",
|
||||||
'string' => $item
|
'string' => $item,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +245,8 @@ class QueryBuilderBase {
|
|||||||
if (is_scalar($key))
|
if (is_scalar($key))
|
||||||
{
|
{
|
||||||
$pairs[$key] = $val;
|
$pairs[$key] = $val;
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
$pairs = $key;
|
$pairs = $key;
|
||||||
}
|
}
|
||||||
@ -300,8 +304,6 @@ class QueryBuilderBase {
|
|||||||
/**
|
/**
|
||||||
* Simplify where_in methods
|
* Simplify where_in methods
|
||||||
*
|
*
|
||||||
* @param mixed $key
|
|
||||||
* @param mixed $val
|
|
||||||
* @param string $in - The (not) in fragment
|
* @param string $in - The (not) in fragment
|
||||||
* @param string $conj - The where in conjunction
|
* @param string $conj - The where in conjunction
|
||||||
*/
|
*/
|
||||||
@ -321,10 +323,8 @@ class QueryBuilderBase {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes the compiled query
|
* Executes the compiled query
|
||||||
*
|
|
||||||
* @param array|null $vals
|
|
||||||
*/
|
*/
|
||||||
protected function _run(QueryType $type, string $table, string $sql = NULL, array $vals = NULL, bool $reset = TRUE): PDOStatement
|
protected function _run(QueryType $type, string $table, ?string $sql = NULL, ?array $vals = NULL, bool $reset = TRUE): PDOStatement
|
||||||
{
|
{
|
||||||
if ($sql === NULL)
|
if ($sql === NULL)
|
||||||
{
|
{
|
||||||
@ -381,7 +381,7 @@ class QueryBuilderBase {
|
|||||||
// Add the interpreted query to the list of executed queries
|
// Add the interpreted query to the list of executed queries
|
||||||
$this->queries[] = [
|
$this->queries[] = [
|
||||||
'time' => $totalTime,
|
'time' => $totalTime,
|
||||||
'sql' => sprintf(...$evals)
|
'sql' => sprintf(...$evals),
|
||||||
];
|
];
|
||||||
|
|
||||||
$this->queries['total_time'] += $totalTime;
|
$this->queries['total_time'] += $totalTime;
|
||||||
@ -398,6 +398,7 @@ class QueryBuilderBase {
|
|||||||
protected function _compileType(QueryType $type = QueryType::SELECT, string $table = ''): string
|
protected function _compileType(QueryType $type = QueryType::SELECT, string $table = ''): string
|
||||||
{
|
{
|
||||||
$setArrayKeys = $this->state->getSetArrayKeys();
|
$setArrayKeys = $this->state->getSetArrayKeys();
|
||||||
|
|
||||||
switch ($type)
|
switch ($type)
|
||||||
{
|
{
|
||||||
case QueryType::INSERT:
|
case QueryType::INSERT:
|
||||||
@ -454,7 +455,7 @@ class QueryBuilderBase {
|
|||||||
// Set each type of subclause
|
// Set each type of subclause
|
||||||
foreach ($clauses as $clause)
|
foreach ($clauses as $clause)
|
||||||
{
|
{
|
||||||
$func = 'get' . ucFirst($clause);
|
$func = 'get' . ucfirst($clause);
|
||||||
$param = $this->state->$func();
|
$param = $this->state->$func();
|
||||||
if (is_array($param))
|
if (is_array($param))
|
||||||
{
|
{
|
||||||
@ -462,7 +463,8 @@ class QueryBuilderBase {
|
|||||||
{
|
{
|
||||||
$sql .= $q['conjunction'] . $q['string'];
|
$sql .= $q['conjunction'] . $q['string'];
|
||||||
}
|
}
|
||||||
} else
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
$sql .= $param;
|
$sql .= $param;
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query;
|
namespace Query;
|
||||||
|
|
||||||
use PDO;
|
use PDO;
|
||||||
@ -57,8 +58,8 @@ use PDOStatement;
|
|||||||
* @method setTablePrefix(string $prefix): void
|
* @method setTablePrefix(string $prefix): void
|
||||||
* @method truncate(string $table): PDOStatement
|
* @method truncate(string $table): PDOStatement
|
||||||
*/
|
*/
|
||||||
interface QueryBuilderInterface {
|
interface QueryBuilderInterface
|
||||||
|
{
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// ! Select Queries
|
// ! Select Queries
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -70,28 +71,28 @@ interface QueryBuilderInterface {
|
|||||||
/**
|
/**
|
||||||
* Selects the maximum value of a field from a query
|
* Selects the maximum value of a field from a query
|
||||||
*
|
*
|
||||||
* @param string|bool $as
|
* @param bool|string $as
|
||||||
*/
|
*/
|
||||||
public function selectMax(string $field, $as=FALSE): self;
|
public function selectMax(string $field, $as=FALSE): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the minimum value of a field from a query
|
* Selects the minimum value of a field from a query
|
||||||
*
|
*
|
||||||
* @param string|bool $as
|
* @param bool|string $as
|
||||||
*/
|
*/
|
||||||
public function selectMin(string $field, $as=FALSE): self;
|
public function selectMin(string $field, $as=FALSE): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the average value of a field from a query
|
* Selects the average value of a field from a query
|
||||||
*
|
*
|
||||||
* @param string|bool $as
|
* @param bool|string $as
|
||||||
*/
|
*/
|
||||||
public function selectAvg(string $field, $as=FALSE): self;
|
public function selectAvg(string $field, $as=FALSE): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Selects the sum of a field from a query
|
* Selects the sum of a field from a query
|
||||||
*
|
*
|
||||||
* @param string|bool $as
|
* @param bool|string $as
|
||||||
*/
|
*/
|
||||||
public function selectSum(string $field, $as=FALSE): self;
|
public function selectSum(string $field, $as=FALSE): self;
|
||||||
|
|
||||||
@ -109,8 +110,6 @@ interface QueryBuilderInterface {
|
|||||||
* Specify the database table to select from
|
* Specify the database table to select from
|
||||||
*
|
*
|
||||||
* Alias of `from` method to better match CodeIgniter 4
|
* Alias of `from` method to better match CodeIgniter 4
|
||||||
*
|
|
||||||
* @param string $tableName
|
|
||||||
*/
|
*/
|
||||||
public function table(string $tableName): self;
|
public function table(string $tableName): self;
|
||||||
|
|
||||||
@ -124,29 +123,21 @@ interface QueryBuilderInterface {
|
|||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Creates a Like clause in the sql statement
|
* Creates a Like clause in the sql statement
|
||||||
*
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function like(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self;
|
public function like(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates an OR Like clause
|
* Generates an OR Like clause
|
||||||
*
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function orLike(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self;
|
public function orLike(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a NOT LIKE clause
|
* Generates a NOT LIKE clause
|
||||||
*
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function notLike(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self;
|
public function notLike(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a OR NOT LIKE clause
|
* Generates a OR NOT LIKE clause
|
||||||
*
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function orNotLike(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self;
|
public function orNotLike(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self;
|
||||||
|
|
||||||
@ -155,17 +146,11 @@ interface QueryBuilderInterface {
|
|||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* Generates a 'Having' clause
|
* Generates a 'Having' clause
|
||||||
*
|
|
||||||
* @param mixed $key
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function having(mixed $key, mixed $values=[]): self;
|
public function having(mixed $key, mixed $values=[]): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a 'Having' clause prefixed with 'OR'
|
* Generates a 'Having' clause prefixed with 'OR'
|
||||||
*
|
|
||||||
* @param mixed $key
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function orHaving(mixed $key, mixed $values=[]): self;
|
public function orHaving(mixed $key, mixed $values=[]): self;
|
||||||
|
|
||||||
@ -176,9 +161,6 @@ interface QueryBuilderInterface {
|
|||||||
* Specify condition(s) in the where clause of a query
|
* Specify condition(s) in the where clause of a query
|
||||||
* Note: this function works with key / value, or a
|
* Note: this function works with key / value, or a
|
||||||
* passed array with key / value pairs
|
* passed array with key / value pairs
|
||||||
*
|
|
||||||
* @param mixed $key
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function where(mixed $key, mixed $values=[]): self;
|
public function where(mixed $key, mixed $values=[]): self;
|
||||||
|
|
||||||
@ -186,39 +168,26 @@ interface QueryBuilderInterface {
|
|||||||
* Where clause prefixed with "OR"
|
* Where clause prefixed with "OR"
|
||||||
*
|
*
|
||||||
* @param string $key
|
* @param string $key
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function orWhere(mixed $key, mixed $values=[]): self;
|
public function orWhere(mixed $key, mixed $values=[]): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Where clause with 'IN' statement
|
* Where clause with 'IN' statement
|
||||||
*
|
|
||||||
* @param string $field
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function whereIn(string $field, mixed $values=[]): self;
|
public function whereIn(string $field, mixed $values=[]): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Where in statement prefixed with "or"
|
* Where in statement prefixed with "or"
|
||||||
*
|
|
||||||
* @param string $field
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function orWhereIn(string $field, mixed $values=[]): self;
|
public function orWhereIn(string $field, mixed $values=[]): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* WHERE NOT IN (FOO) clause
|
* WHERE NOT IN (FOO) clause
|
||||||
*
|
|
||||||
* @param string $field
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function whereNotIn(string $field, mixed $values=[]): self;
|
public function whereNotIn(string $field, mixed $values=[]): self;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* OR WHERE NOT IN (FOO) clause
|
* OR WHERE NOT IN (FOO) clause
|
||||||
*
|
|
||||||
* @param string $field
|
|
||||||
* @param mixed $values
|
|
||||||
*/
|
*/
|
||||||
public function orWhereNotIn(string $field, mixed $values=[]): self;
|
public function orWhereNotIn(string $field, mixed $values=[]): self;
|
||||||
|
|
||||||
@ -228,7 +197,6 @@ interface QueryBuilderInterface {
|
|||||||
/**
|
/**
|
||||||
* Sets values for inserts / updates / deletes
|
* Sets values for inserts / updates / deletes
|
||||||
*
|
*
|
||||||
* @param mixed $key
|
|
||||||
* @param mixed $values
|
* @param mixed $values
|
||||||
*/
|
*/
|
||||||
public function set(mixed $key, mixed $values = NULL): self;
|
public function set(mixed $key, mixed $values = NULL): self;
|
||||||
@ -240,8 +208,6 @@ interface QueryBuilderInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Group the results by the selected field(s)
|
* Group the results by the selected field(s)
|
||||||
*
|
|
||||||
* @param mixed $field
|
|
||||||
*/
|
*/
|
||||||
public function groupBy(mixed $field): self;
|
public function groupBy(mixed $field): self;
|
||||||
|
|
||||||
@ -297,8 +263,6 @@ interface QueryBuilderInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method for get() with a where clause
|
* Convenience method for get() with a where clause
|
||||||
*
|
|
||||||
* @param array $where
|
|
||||||
*/
|
*/
|
||||||
public function getWhere(string $table, array $where=[], ?int $limit=NULL, ?int $offset=NULL): PDOStatement;
|
public function getWhere(string $table, array $where=[], ?int $limit=NULL, ?int $offset=NULL): PDOStatement;
|
||||||
|
|
||||||
@ -317,8 +281,6 @@ interface QueryBuilderInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an insert clause, and executes it
|
* Creates an insert clause, and executes it
|
||||||
*
|
|
||||||
* @param mixed $data
|
|
||||||
*/
|
*/
|
||||||
public function insert(string $table, mixed $data=[]): PDOStatement;
|
public function insert(string $table, mixed $data=[]): PDOStatement;
|
||||||
|
|
||||||
@ -331,8 +293,6 @@ interface QueryBuilderInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an update clause, and executes it
|
* Creates an update clause, and executes it
|
||||||
*
|
|
||||||
* @param mixed $data
|
|
||||||
*/
|
*/
|
||||||
public function update(string $table, mixed $data=[]): PDOStatement;
|
public function update(string $table, mixed $data=[]): PDOStatement;
|
||||||
|
|
||||||
@ -348,8 +308,6 @@ interface QueryBuilderInterface {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Deletes data from a table
|
* Deletes data from a table
|
||||||
*
|
|
||||||
* @param mixed $where
|
|
||||||
*/
|
*/
|
||||||
public function delete(string $table, mixed $where=''): PDOStatement;
|
public function delete(string $table, mixed $where=''): PDOStatement;
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query;
|
namespace Query;
|
||||||
|
|
||||||
use Query\Drivers\DriverInterface;
|
use Query\Drivers\DriverInterface;
|
||||||
@ -20,17 +21,8 @@ use Query\Drivers\DriverInterface;
|
|||||||
/**
|
/**
|
||||||
* Utility Class to parse sql clauses for properly escaping identifiers
|
* Utility Class to parse sql clauses for properly escaping identifiers
|
||||||
*/
|
*/
|
||||||
class QueryParser {
|
class QueryParser
|
||||||
|
{
|
||||||
/**
|
|
||||||
* Regex patterns for various syntax components
|
|
||||||
*/
|
|
||||||
private array $matchPatterns = [
|
|
||||||
'function' => '([a-zA-Z0-9_]+\((.*?)\))',
|
|
||||||
'identifier' => '([a-zA-Z0-9_-]+\.?)+',
|
|
||||||
'operator' => '=|AND|&&?|~|\|\|?|\^|/|>=?|<=?|-|%|OR|\+|NOT|\!=?|<>|XOR'
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Regex matches
|
* Regex matches
|
||||||
*/
|
*/
|
||||||
@ -41,6 +33,15 @@ class QueryParser {
|
|||||||
'combined' => [],
|
'combined' => [],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regex patterns for various syntax components
|
||||||
|
*/
|
||||||
|
private array $matchPatterns = [
|
||||||
|
'function' => '([a-zA-Z0-9_]+\((.*?)\))',
|
||||||
|
'identifier' => '([a-zA-Z0-9_-]+\.?)+',
|
||||||
|
'operator' => '=|AND|&&?|~|\|\|?|\^|/|>=?|<=?|-|%|OR|\+|NOT|\!=?|<>|XOR',
|
||||||
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor/entry point into parser
|
* Constructor/entry point into parser
|
||||||
*/
|
*/
|
||||||
@ -81,7 +82,7 @@ class QueryParser {
|
|||||||
// Go through and quote the identifiers
|
// Go through and quote the identifiers
|
||||||
for ($i=0; $i <= $count; $i++)
|
for ($i=0; $i <= $count; $i++)
|
||||||
{
|
{
|
||||||
if (in_array($parts['combined'][$i], $parts['identifiers']) && ! is_numeric($parts['combined'][$i]))
|
if (in_array($parts['combined'][$i], $parts['identifiers'], TRUE) && ! is_numeric($parts['combined'][$i]))
|
||||||
{
|
{
|
||||||
$parts['combined'][$i] = $this->db->quoteIdent($parts['combined'][$i]);
|
$parts['combined'][$i] = $this->db->quoteIdent($parts['combined'][$i]);
|
||||||
}
|
}
|
||||||
@ -92,8 +93,6 @@ class QueryParser {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a more useful match array
|
* Returns a more useful match array
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
*/
|
||||||
protected function filterArray(array $array): array
|
protected function filterArray(array $array): array
|
||||||
{
|
{
|
||||||
|
@ -13,12 +13,14 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query;
|
namespace Query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enum of query types
|
* Enum of query types
|
||||||
*/
|
*/
|
||||||
enum QueryType: string {
|
enum QueryType: string
|
||||||
|
{
|
||||||
case SELECT = 'select';
|
case SELECT = 'select';
|
||||||
case INSERT = 'insert';
|
case INSERT = 'insert';
|
||||||
case INSERT_BATCH = 'insert_batch';
|
case INSERT_BATCH = 'insert_batch';
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
* @link https://git.timshomepage.net/aviat/Query
|
* @link https://git.timshomepage.net/aviat/Query
|
||||||
* @version 4.0.0
|
* @version 4.0.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Query;
|
namespace Query;
|
||||||
|
|
||||||
use function is_array;
|
use function is_array;
|
||||||
@ -20,32 +21,33 @@ use function is_array;
|
|||||||
/**
|
/**
|
||||||
* Query builder state
|
* Query builder state
|
||||||
*
|
*
|
||||||
* @method getSelectString(): string
|
|
||||||
* @method getFromString(): string
|
* @method getFromString(): string
|
||||||
* @method getSetString(): string
|
|
||||||
* @method getOrderString(): string
|
|
||||||
* @method getGroupString(): string
|
|
||||||
* @method getSetArrayKeys(): array
|
|
||||||
* @method getOrderArray(): array
|
|
||||||
* @method getGroupArray(): array
|
* @method getGroupArray(): array
|
||||||
* @method getValues(): array
|
* @method getGroupString(): string
|
||||||
* @method getWhereValues(): array
|
* @method getHavingMap(): array
|
||||||
* @method getLimit(): int|null
|
* @method getLimit(): int|null
|
||||||
* @method getOffset()
|
* @method getOffset()
|
||||||
|
* @method getOrderArray(): array
|
||||||
|
* @method getOrderString(): string
|
||||||
* @method getQueryMap(): array
|
* @method getQueryMap(): array
|
||||||
* @method getHavingMap(): array
|
* @method getSelectString(): string
|
||||||
|
* @method getSetArrayKeys(): array
|
||||||
|
* @method getSetString(): string
|
||||||
|
* @method getValues(): array
|
||||||
|
* @method getWhereValues(): array
|
||||||
*
|
*
|
||||||
* @method setSelectString(string $selectString): self
|
|
||||||
* @method setFromString(string $fromString): self
|
* @method setFromString(string $fromString): self
|
||||||
* @method setSetString(string $setString): self
|
|
||||||
* @method setOrderString(string $orderString): self
|
|
||||||
* @method setGroupString(string $groupString): self
|
|
||||||
* @method setSetArrayKeys(array $arrayKeys): self
|
|
||||||
* @method setGroupArray(array $array): self
|
* @method setGroupArray(array $array): self
|
||||||
|
* @method setGroupString(string $groupString): self
|
||||||
* @method setLimit(int $limit): self
|
* @method setLimit(int $limit): self
|
||||||
* @method setOffset(?int $offset): self
|
* @method setOffset(?int $offset): self
|
||||||
|
* @method setOrderString(string $orderString): self
|
||||||
|
* @method setSelectString(string $selectString): self
|
||||||
|
* @method setSetArrayKeys(array $arrayKeys): self
|
||||||
|
* @method setSetString(string $setString): self
|
||||||
*/
|
*/
|
||||||
class State {
|
class State
|
||||||
|
{
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// ! SQL Clause Strings
|
// ! SQL Clause Strings
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
@ -150,6 +152,7 @@ class State {
|
|||||||
if (isset($this->$maybeProp))
|
if (isset($this->$maybeProp))
|
||||||
{
|
{
|
||||||
$this->$maybeProp = $arguments[0];
|
$this->$maybeProp = $arguments[0];
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,30 +163,35 @@ class State {
|
|||||||
public function appendSelectString(string $str): self
|
public function appendSelectString(string $str): self
|
||||||
{
|
{
|
||||||
$this->selectString .= $str;
|
$this->selectString .= $str;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function appendSetArrayKeys(array $setArrayKeys): self
|
public function appendSetArrayKeys(array $setArrayKeys): self
|
||||||
{
|
{
|
||||||
$this->setArrayKeys = array_merge($this->setArrayKeys, $setArrayKeys);
|
$this->setArrayKeys = array_merge($this->setArrayKeys, $setArrayKeys);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setOrderArray(string $key, mixed $orderArray): self
|
public function setOrderArray(string $key, mixed $orderArray): self
|
||||||
{
|
{
|
||||||
$this->orderArray[$key] = $orderArray;
|
$this->orderArray[$key] = $orderArray;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function appendGroupArray(string $groupArray): self
|
public function appendGroupArray(string $groupArray): self
|
||||||
{
|
{
|
||||||
$this->groupArray[] = $groupArray;
|
$this->groupArray[] = $groupArray;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function appendValues(array $values): self
|
public function appendValues(array $values): self
|
||||||
{
|
{
|
||||||
$this->values = array_merge($this->values, $values);
|
$this->values = array_merge($this->values, $values);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -200,6 +208,7 @@ class State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->whereValues[] = $val;
|
$this->whereValues[] = $val;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,14 +220,16 @@ class State {
|
|||||||
$this->queryMap[] = [
|
$this->queryMap[] = [
|
||||||
'type' => $type,
|
'type' => $type,
|
||||||
'conjunction' => $conjunction,
|
'conjunction' => $conjunction,
|
||||||
'string' => $string
|
'string' => $string,
|
||||||
];
|
];
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function appendHavingMap(array $item): self
|
public function appendHavingMap(array $item): self
|
||||||
{
|
{
|
||||||
$this->havingMap[] = $item;
|
$this->havingMap[] = $item;
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user