diff --git a/src/ConnectionManager.php b/src/ConnectionManager.php index 6b6ffac..e1234da 100644 --- a/src/ConnectionManager.php +++ b/src/ConnectionManager.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query; use DomainException; @@ -22,8 +23,8 @@ use stdClass; * Connection manager class to manage connections for the * Query method */ -final class ConnectionManager { - +final class ConnectionManager +{ /** * Map of named database connections */ @@ -91,7 +92,6 @@ final class ConnectionManager { /** * Returns the connection specified by the name given * - * @param string $name * @throws Exception\NonExistentConnectionException */ public function getConnection(string $name = ''): QueryBuilderInterface @@ -113,9 +113,6 @@ final class ConnectionManager { /** * Parse the passed parameters and return a connection - * - * @param array|object $params - * @return QueryBuilderInterface */ public function connect(array|object $params): QueryBuilderInterface { @@ -138,7 +135,6 @@ final class ConnectionManager { // Create Query Builder object $conn = new QueryBuilder($db, new QueryParser($db)); - // Save it for later if (isset($params->alias)) { @@ -155,9 +151,7 @@ final class ConnectionManager { /** * Parses params into a dsn and option array * - * @param array|object $rawParams * @throws Exception\BadDBDriverException - * @return array */ public function parseParams(array|object $rawParams): array { @@ -183,7 +177,6 @@ final class ConnectionManager { // Create the dsn for the database to connect to $dsn = strtolower($dbType) === 'sqlite' ? $params->file : $this->createDsn($dbType, $params); - return [$dsn, $dbType, $params, $options]; } @@ -209,12 +202,12 @@ final class ConnectionManager { 'prefix' => 'prefix', 'options' => 'options', 'database' => 'database', - 'alias' => 'alias' + 'alias' => 'alias', ]; - foreach($params as $key => $val) + foreach ($params as $key => $val) { - if (( ! array_key_exists($key, $skip)) && ! empty($val)) + if (( ! array_key_exists($key, $skip)) && ! empty($val)) { $pairs[] = implode('=', [$key, $val]); } @@ -222,4 +215,4 @@ final class ConnectionManager { return strtolower($dbType) . ':' . implode(';', $pairs); } -} \ No newline at end of file +} diff --git a/src/Drivers/AbstractDriver.php b/src/Drivers/AbstractDriver.php index e4274ef..bd58197 100644 --- a/src/Drivers/AbstractDriver.php +++ b/src/Drivers/AbstractDriver.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers; use InvalidArgumentException; @@ -29,10 +30,8 @@ use function is_string; * * Extends PDO to simplify cross-database issues */ -abstract class AbstractDriver - extends PDO - implements DriverInterface { - +abstract class AbstractDriver extends PDO implements DriverInterface +{ /** * Reference to the last executed query */ @@ -76,7 +75,7 @@ abstract class AbstractDriver /** * 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 $driverOptions[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION; @@ -85,23 +84,6 @@ abstract class AbstractDriver $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 * @@ -114,14 +96,30 @@ abstract class AbstractDriver isset($this->$name) && is_object($this->$name) && method_exists($this->$name, '__invoke') - ) - { + ) { return call_user_func_array([$this->$name, '__invoke'], $args); } 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 // -------------------------------------------------------------------------- @@ -177,11 +175,11 @@ abstract class AbstractDriver $this->statement = $this->prepare($sql); // Bind the parameters - foreach($data as $k => $value) + foreach ($data as $k => $value) { // Parameters are 1-based, the data is 0-based // So, if the key is numeric, add 1 - if(is_numeric($k)) + if (is_numeric($k)) { $k++; } @@ -282,7 +280,8 @@ abstract class AbstractDriver // Fix functions $funcs = []; 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 // Quote the inside identifiers @@ -308,6 +307,7 @@ abstract class AbstractDriver { $tables = $this->driverQuery('tableList'); natsort($tables); + return $tables; } @@ -326,6 +326,7 @@ abstract class AbstractDriver { $views = $this->driverQuery('viewList'); sort($views); + return $views; } @@ -456,6 +457,7 @@ abstract class AbstractDriver if (preg_match($regex, $this->lastQuery, $output) > 0) { $stmt = $this->query("SELECT COUNT(*) FROM {$output[1]}"); + return (int) $stmt->fetchColumn(); } @@ -472,7 +474,8 @@ abstract class AbstractDriver // Values for insertion $vals = []; - foreach($data as $group) + + foreach ($data as $group) { $vals = [...$vals, ...array_values($group)]; } @@ -533,6 +536,7 @@ abstract class AbstractDriver $line = $this->quoteIdent($field) . " = CASE\n"; $cases = []; + foreach ($data as $case) { if (array_key_exists($field, $case)) @@ -553,6 +557,7 @@ abstract class AbstractDriver $sql .= implode(",\n", $fieldLines) . "\n"; $whereValues = array_column($data, $where); + foreach ($whereValues as $value) { $insertData[] = $value; @@ -579,6 +584,7 @@ abstract class AbstractDriver $sql .= $this->quoteTable($table); $this->statement = $this->query($sql); + return $this->statement; } @@ -592,9 +598,6 @@ abstract class AbstractDriver /** * Helper method for quote_ident - * - * @param mixed $str - * @return mixed */ public function _quote(mixed $str): mixed { @@ -608,7 +611,6 @@ abstract class AbstractDriver ) ? "{$this->escapeCharOpen}{$str}{$this->escapeCharClose}" : $str; - } /** diff --git a/src/Drivers/AbstractSQL.php b/src/Drivers/AbstractSQL.php index 3dcfd89..aeefa8d 100644 --- a/src/Drivers/AbstractSQL.php +++ b/src/Drivers/AbstractSQL.php @@ -13,13 +13,14 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers; /** * Parent for database-specific syntax subclasses */ -abstract class AbstractSQL implements SQLInterface { - +abstract class AbstractSQL implements SQLInterface +{ /** * Limit clause */ diff --git a/src/Drivers/AbstractUtil.php b/src/Drivers/AbstractUtil.php index b3bc5ea..fc5034b 100644 --- a/src/Drivers/AbstractUtil.php +++ b/src/Drivers/AbstractUtil.php @@ -13,13 +13,16 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers; +use function arrayZipper; + /** * Abstract class defining database / table creation methods */ -abstract class AbstractUtil { - +abstract class AbstractUtil +{ /** * Save a reference to the connection object for later use */ @@ -48,14 +51,15 @@ abstract class AbstractUtil { // 'constraint' => ..., // 'index' => ..., // ] - $columnArray = \arrayZipper([ + $columnArray = arrayZipper([ 'type' => $fields, - 'constraint' => $constraints + 'constraint' => $constraints, ]); // Join column definitions together $columns = []; - foreach($columnArray as $n => $props) + + foreach ($columnArray as $n => $props) { $str = $this->getDriver()->quoteIdent($n); $str .= isset($props['type']) ? " {$props['type']}" : ''; @@ -65,7 +69,7 @@ abstract class AbstractUtil { } // Generate the sql for the creation of the table - $sql = 'CREATE TABLE'.$existsStr.$this->getDriver()->quoteTable($name).' ('; + $sql = 'CREATE TABLE' . $existsStr . $this->getDriver()->quoteTable($name) . ' ('; $sql .= implode(', ', $columns); $sql .= ')'; @@ -77,7 +81,7 @@ abstract class AbstractUtil { */ public function deleteTable(string $name): string { - return 'DROP TABLE IF EXISTS '.$this->getDriver()->quoteTable($name); + return 'DROP TABLE IF EXISTS ' . $this->getDriver()->quoteTable($name); } // -------------------------------------------------------------------------- @@ -85,16 +89,11 @@ abstract class AbstractUtil { // -------------------------------------------------------------------------- /** * Return an SQL file with the database table structure - * - * @abstract */ abstract public function backupStructure(): string; /** * Return an SQL file with the database data as insert statements - * - * @abstract */ abstract public function backupData(): string; - -} \ No newline at end of file +} diff --git a/src/Drivers/DriverInterface.php b/src/Drivers/DriverInterface.php index d3073fd..baaa142 100644 --- a/src/Drivers/DriverInterface.php +++ b/src/Drivers/DriverInterface.php @@ -13,9 +13,9 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers; -use InvalidArgumentException; use PDO; use PDOStatement; @@ -36,12 +36,12 @@ use PDOStatement; * @method rollback(): bool * @method setAttribute(int $attribute, $value): bool */ -interface DriverInterface /* extends the interface of PDO */ { - +interface DriverInterface // extends the interface of PDO +{ /** * 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 diff --git a/src/Drivers/Mysql/Driver.php b/src/Drivers/Mysql/Driver.php index c03fc32..9cc111a 100644 --- a/src/Drivers/Mysql/Driver.php +++ b/src/Drivers/Mysql/Driver.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers\Mysql; use PDO; @@ -22,8 +23,8 @@ use function defined; /** * MySQL specific class */ -class Driver extends AbstractDriver { - +class Driver extends AbstractDriver +{ /** * Set the backtick as the MySQL escape character */ @@ -39,7 +40,7 @@ class Driver extends AbstractDriver { * * @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 if (defined('\\PDO::MYSQL_ATTR_INIT_COMMAND')) @@ -51,7 +52,7 @@ class Driver extends AbstractDriver { if ( ! str_contains($dsn, 'mysql')) { - $dsn = 'mysql:'.$dsn; + $dsn = 'mysql:' . $dsn; } parent::__construct($dsn, $username, $password, $options); @@ -67,7 +68,7 @@ class Driver extends AbstractDriver { if ( stripos($query, 'insert') !== FALSE && version_compare($this->getVersion(), '10.5.0', '>=') - ){ + ) { return parent::returning($query, $select); } @@ -75,11 +76,11 @@ class Driver extends AbstractDriver { 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; } -} \ No newline at end of file +} diff --git a/src/Drivers/Mysql/SQL.php b/src/Drivers/Mysql/SQL.php index e0e8a59..406f71d 100644 --- a/src/Drivers/Mysql/SQL.php +++ b/src/Drivers/Mysql/SQL.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers\Mysql; use Query\Drivers\AbstractSQL; @@ -20,8 +21,8 @@ use Query\Drivers\AbstractSQL; /** * MySQL specific SQL */ -class SQL extends AbstractSQL { - +class SQL extends AbstractSQL +{ /** * Limit clause */ @@ -29,10 +30,10 @@ class SQL extends AbstractSQL { { if ( ! is_numeric($offset)) { - return $sql." LIMIT {$limit}"; + return $sql . " LIMIT {$limit}"; } - return $sql." LIMIT {$offset}, {$limit}"; + return $sql . " LIMIT {$offset}, {$limit}"; } /** @@ -56,10 +57,9 @@ class SQL extends AbstractSQL { */ public function dbList(): string { - return <<getDriver(); $dbs = $driver->getDbs(); - foreach($dbs as &$d) + foreach ($dbs as &$d) { // Skip built-in dbs // @codeCoverageIgnoreStart @@ -47,7 +48,7 @@ class Util extends AbstractUtil { // Get the list of tables $tables = $driver->driverQuery("SHOW TABLES FROM `{$d}`", TRUE); - foreach($tables as $table) + foreach ($tables as $table) { $array = $driver->driverQuery("SHOW CREATE TABLE `{$d}`.`{$table}`", FALSE); $row = current($array); @@ -57,7 +58,6 @@ class Util extends AbstractUtil { continue; } - $string[] = $row['Create Table']; } } @@ -74,7 +74,7 @@ class Util extends AbstractUtil { $tables = $driver->getTables(); // Filter out the tables you don't want - if( ! empty($exclude)) + if ( ! empty($exclude)) { $tables = array_diff($tables, $exclude); } @@ -82,7 +82,7 @@ class Util extends AbstractUtil { $outputSql = ''; // Select the rows from each Table - foreach($tables as $t) + foreach ($tables as $t) { $sql = "SELECT * FROM `{$t}`"; $res = $driver->query($sql); @@ -100,24 +100,24 @@ class Util extends AbstractUtil { $insertRows = []; // Create the insert statements - foreach($rows as $row) + foreach ($rows as $row) { $row = array_values($row); // 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); - $rowString = 'INSERT INTO `'.trim($t).'` (`'.implode('`,`', $columns).'`) VALUES ('.implode(',', $row).');'; + $rowString = 'INSERT INTO `' . trim($t) . '` (`' . implode('`,`', $columns) . '`) VALUES (' . implode(',', $row) . ');'; $row = NULL; $insertRows[] = $rowString; } - $outputSql .= "\n\n".implode("\n", $insertRows)."\n"; + $outputSql .= "\n\n" . implode("\n", $insertRows) . "\n"; } return $outputSql; } -} \ No newline at end of file +} diff --git a/src/Drivers/Pgsql/Driver.php b/src/Drivers/Pgsql/Driver.php index 86e6e60..bcd0a7b 100644 --- a/src/Drivers/Pgsql/Driver.php +++ b/src/Drivers/Pgsql/Driver.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers\Pgsql; use Query\Drivers\AbstractDriver; @@ -20,18 +21,18 @@ use Query\Drivers\AbstractDriver; /** * PostgreSQL specific class */ -class Driver extends AbstractDriver { - +class Driver extends AbstractDriver +{ /** * Connect to a PosgreSQL database * * @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')) { - $dsn = 'pgsql:'.$dsn; + $dsn = 'pgsql:' . $dsn; } parent::__construct($dsn, $username, $password, $options); @@ -63,9 +64,9 @@ SQL; $keys = parent::getFks($table); - foreach($keys as &$key) + foreach ($keys as &$key) { - foreach(['update', 'delete'] AS $type) + foreach (['update', 'delete'] as $type) { if ( ! isset($valueMap[$key[$type]])) { @@ -80,4 +81,4 @@ SQL; return $keys; } -} \ No newline at end of file +} diff --git a/src/Drivers/Pgsql/SQL.php b/src/Drivers/Pgsql/SQL.php index 4fb34aa..773ef32 100644 --- a/src/Drivers/Pgsql/SQL.php +++ b/src/Drivers/Pgsql/SQL.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers\Pgsql; use Query\Drivers\AbstractSQL; @@ -20,8 +21,8 @@ use Query\Drivers\AbstractSQL; /** * PostgreSQL specific SQL */ -class SQL extends AbstractSQL { - +class SQL extends AbstractSQL +{ /** * Get the query plan for the sql query */ @@ -43,7 +44,7 @@ class SQL extends AbstractSQL { */ public function dbList(): string { - return <<getDriver()->getTables(); // Filter out the tables you don't want - if( ! empty($exclude)) + if ( ! empty($exclude)) { $tables = array_diff($tables, $exclude); } @@ -48,9 +49,9 @@ class Util extends AbstractUtil { $outputSql = ''; // Get the data for each object - foreach($tables as $t) + foreach ($tables as $t) { - $sql = 'SELECT * FROM "'.trim($t).'"'; + $sql = 'SELECT * FROM "' . trim($t) . '"'; $res = $this->getDriver()->query($sql); $objRes = $res->fetchAll(PDO::FETCH_ASSOC); @@ -68,7 +69,7 @@ class Util extends AbstractUtil { $insertRows = []; // Create the insert statements - foreach($objRes as $row) + foreach ($objRes as $row) { $row = array_values($row); @@ -76,8 +77,7 @@ class Util extends AbstractUtil { $row = array_map([$this->getDriver(), 'quote'], $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; @@ -86,9 +86,9 @@ class Util extends AbstractUtil { $objRes = NULL; - $outputSql .= "\n\n".implode("\n", $insertRows)."\n"; + $outputSql .= "\n\n" . implode("\n", $insertRows) . "\n"; } return $outputSql; } -} \ No newline at end of file +} diff --git a/src/Drivers/SQLInterface.php b/src/Drivers/SQLInterface.php index 048d463..a9f0531 100644 --- a/src/Drivers/SQLInterface.php +++ b/src/Drivers/SQLInterface.php @@ -13,13 +13,14 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers; /** * Interface for database-specific syntax subclasses */ -interface SQLInterface { - +interface SQLInterface +{ /** * Get database specific sql for limit clause */ @@ -96,4 +97,4 @@ interface SQLInterface { * Get the list of indexes for the current table */ public function indexList(string $table): string; -} \ No newline at end of file +} diff --git a/src/Drivers/Sqlite/Driver.php b/src/Drivers/Sqlite/Driver.php index 44e7d59..bccbea5 100644 --- a/src/Drivers/Sqlite/Driver.php +++ b/src/Drivers/Sqlite/Driver.php @@ -13,18 +13,20 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers\Sqlite; -use function is_array; - use InvalidArgumentException; + use PDO; use Query\Drivers\AbstractDriver; +use function is_array; /** * SQLite specific class */ -class Driver extends AbstractDriver { +class Driver extends AbstractDriver +{ /** * SQLite has a truncate optimization, * but no support for the actual keyword @@ -34,7 +36,7 @@ class Driver extends AbstractDriver { /** * 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:')) { @@ -59,6 +61,7 @@ class Driver extends AbstractDriver { { $sql = $this->getSql()->tableList(); $res = $this->query($sql); + return dbFilter($res->fetchAll(PDO::FETCH_ASSOC), 'name'); } @@ -69,14 +72,14 @@ class Driver extends AbstractDriver { { $returnRows = []; - foreach(parent::getFks($table) as $row) + foreach (parent::getFks($table) as $row) { $returnRows[] = [ 'child_column' => $row['from'], 'parent_table' => $row['table'], 'parent_column' => $row['to'], '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 * * @codeCoverageIgnore - * @return array[]|string[]|null[] + * @return array[]|null[]|string[] */ public function insertBatch(string $table, array $data=[]): array { @@ -115,13 +118,14 @@ class Driver extends AbstractDriver { // Create a key-value mapping for each field $first = array_shift($data); $cols = []; - foreach($first as $colName => $datum) + + foreach ($first as $colName => $datum) { $cols[] = $this->_quote($datum) . ' AS ' . $this->quoteIdent($colName); } $sql .= 'SELECT ' . implode(', ', $cols) . "\n"; - foreach($data as $union) + foreach ($data as $union) { $vals = array_map([$this, 'quote'], $union); $sql .= 'UNION SELECT ' . implode(',', $vals) . "\n"; @@ -138,4 +142,4 @@ class Driver extends AbstractDriver { // Return the same query, as the returning clause is not supported return $query; } -} \ No newline at end of file +} diff --git a/src/Drivers/Sqlite/SQL.php b/src/Drivers/Sqlite/SQL.php index 5b5971e..5f120bc 100644 --- a/src/Drivers/Sqlite/SQL.php +++ b/src/Drivers/Sqlite/SQL.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Drivers\Sqlite; use Query\Drivers\AbstractSQL; @@ -21,8 +22,8 @@ use Query\Exception\NotImplementedException; /** * SQLite Specific SQL */ -class SQL extends AbstractSQL { - +class SQL extends AbstractSQL +{ /** * Get the query plan for the sql query */ @@ -53,7 +54,7 @@ class SQL extends AbstractSQL { */ public function tableList(): string { - return <<getDriver()->query($sql); @@ -46,9 +47,9 @@ class Util extends AbstractUtil { $outputSql = ''; // Get the data for each object - foreach($result as $r) + foreach ($result as $r) { - $sql = 'SELECT * FROM "'.$r['name'].'"'; + $sql = 'SELECT * FROM "' . $r['name'] . '"'; $res = $this->getDriver()->query($sql); $objRes = $res->fetchAll(PDO::FETCH_ASSOC); @@ -66,7 +67,7 @@ class Util extends AbstractUtil { $insertRows = []; // Create the insert statements - foreach($objRes as $row) + foreach ($objRes as $row) { $row = array_values($row); @@ -78,7 +79,7 @@ class Util extends AbstractUtil { : $this->getDriver()->quote($row[$i]); } - $rowString = 'INSERT INTO "'.$r['name'].'" ("'.implode('","', $columns).'") VALUES ('.implode(',', $row).');'; + $rowString = 'INSERT INTO "' . $r['name'] . '" ("' . implode('","', $columns) . '") VALUES (' . implode(',', $row) . ');'; unset($row); @@ -87,7 +88,7 @@ class Util extends AbstractUtil { unset($objRes); - $outputSql .= "\n\n".implode("\n", $insertRows); + $outputSql .= "\n\n" . implode("\n", $insertRows); } return $outputSql; @@ -105,11 +106,11 @@ class Util extends AbstractUtil { $sqlArray = []; - foreach($result as $r) + foreach ($result as $r) { $sqlArray[] = $r['sql']; } return implode(";\n", $sqlArray) . ';'; } -} \ No newline at end of file +} diff --git a/src/Exception/BadDBDriverException.php b/src/Exception/BadDBDriverException.php index be0f0fa..020291a 100644 --- a/src/Exception/BadDBDriverException.php +++ b/src/Exception/BadDBDriverException.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Exception; use InvalidArgumentException; @@ -20,5 +21,6 @@ use InvalidArgumentException; /** * Generic exception for bad drivers */ -class BadDBDriverException extends InvalidArgumentException { -} \ No newline at end of file +class BadDBDriverException extends InvalidArgumentException +{ +} diff --git a/src/Exception/NonExistentConnectionException.php b/src/Exception/NonExistentConnectionException.php index 0e80797..5ab3392 100644 --- a/src/Exception/NonExistentConnectionException.php +++ b/src/Exception/NonExistentConnectionException.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Exception; use InvalidArgumentException; @@ -20,5 +21,6 @@ use InvalidArgumentException; /** * Exception for missing database connection */ -class NonExistentConnectionException extends InvalidArgumentException { -} \ No newline at end of file +class NonExistentConnectionException extends InvalidArgumentException +{ +} diff --git a/src/Exception/NotImplementedException.php b/src/Exception/NotImplementedException.php index a0510d2..e9b3353 100644 --- a/src/Exception/NotImplementedException.php +++ b/src/Exception/NotImplementedException.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query\Exception; use BadMethodCallException; @@ -20,5 +21,6 @@ use BadMethodCallException; /** * Exception for non-implemented method */ -class NotImplementedException extends BadMethodCallException{ -} \ No newline at end of file +class NotImplementedException extends BadMethodCallException +{ +} diff --git a/src/JoinType.php b/src/JoinType.php index 4aaf05c..db679a3 100644 --- a/src/JoinType.php +++ b/src/JoinType.php @@ -13,12 +13,14 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query; /** * Enum of join types */ -enum JoinType: string { +enum JoinType: string +{ case CROSS = 'cross'; case INNER = 'inner'; case OUTER = 'outer'; @@ -35,4 +37,3 @@ enum JoinType: string { return self::from($val); } } - diff --git a/src/LikeType.php b/src/LikeType.php index de93eda..77eee87 100644 --- a/src/LikeType.php +++ b/src/LikeType.php @@ -13,12 +13,14 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query; /** * 'Enum' of join types */ -enum LikeType: string { +enum LikeType: string +{ case BEFORE = 'before'; case AFTER = 'after'; case BOTH = 'both'; @@ -32,4 +34,4 @@ enum LikeType: string { return self::from($val); } -} \ No newline at end of file +} diff --git a/src/MapType.php b/src/MapType.php index d58b4e8..baaffeb 100644 --- a/src/MapType.php +++ b/src/MapType.php @@ -13,16 +13,18 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query; /** * Enum of query map types */ -enum MapType: string { +enum MapType: string +{ case GROUP_END = 'group_end'; case GROUP_START = 'group_start'; case JOIN = 'join'; case LIKE = 'like'; case WHERE = 'where'; case WHERE_IN = 'where_in'; -} \ No newline at end of file +} diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index 49fb0e5..efdbbb1 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -13,18 +13,20 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query; +use PDOStatement; use function is_array; use function is_int; -use function mb_trim; -use PDOStatement; +use function mb_trim; /** * Convenience class for creating sql queries */ -class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface { +class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface +{ // -------------------------------------------------------------------------- // ! Select Queries // -------------------------------------------------------------------------- @@ -69,48 +71,52 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface { /** * 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 { // Create the select string - $this->state->appendSelectString(' MAX'.$this->_select($field, $as)); + $this->state->appendSelectString(' MAX' . $this->_select($field, $as)); + return $this; } /** * 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 { // Create the select string - $this->state->appendSelectString(' MIN'.$this->_select($field, $as)); + $this->state->appendSelectString(' MIN' . $this->_select($field, $as)); + return $this; } /** * 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 { // Create the select string - $this->state->appendSelectString(' AVG'.$this->_select($field, $as)); + $this->state->appendSelectString(' AVG' . $this->_select($field, $as)); + return $this; } /** * 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 { // Create the select string - $this->state->appendSelectString(' SUM'.$this->_select($field, $as)); + $this->state->appendSelectString(' SUM' . $this->_select($field, $as)); + return $this; } @@ -139,6 +145,7 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface { { // Prepend the keyword to the select string $this->state->setSelectString(' DISTINCT' . $this->state->getSelectString()); + return $this; } @@ -148,6 +155,7 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface { public function explain(): self { $this->explain = TRUE; + return $this; } @@ -155,8 +163,6 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface { * Specify the database table to select from * * Alias of `from` method to better match CodeIgniter 4 - * - * @param string $tableName */ public function table(string $tableName): self { @@ -383,15 +389,15 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface { $orderClauses = []; // Flatten key/val pairs into an array of space-separated pairs - foreach($this->state->getOrderArray() as $k => $v) + foreach ($this->state->getOrderArray() as $k => $v) { $orderClauses[] = $k . ' ' . strtoupper($v); } // Set the final string $orderString = isset($rand) - ? "\nORDER BY".$rand - : "\nORDER BY ".implode(', ', $orderClauses); + ? "\nORDER BY" . $rand + : "\nORDER BY " . implode(', ', $orderClauses); $this->state->setOrderString($orderString); @@ -512,8 +518,9 @@ class QueryBuilder extends QueryBuilderBase implements QueryBuilderInterface { */ public function countAll(string $table): int { - $sql = 'SELECT * FROM '.$this->driver->quoteTable($table); + $sql = 'SELECT * FROM ' . $this->driver->quoteTable($table); $res = $this->driver->query($sql); + 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); $this->_run(QueryType::UPDATE_BATCH, $table, $sql, $data); + return $affectedRows; } diff --git a/src/QueryBuilderBase.php b/src/QueryBuilderBase.php index 570380c..c18c28b 100644 --- a/src/QueryBuilderBase.php +++ b/src/QueryBuilderBase.php @@ -13,14 +13,16 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query; -use function regexInArray; - use BadMethodCallException; + use PDO; use PDOStatement; use Query\Drivers\DriverInterface; +use function is_string; +use function regexInArray; /** * @method affectedRows(): int @@ -56,8 +58,8 @@ use Query\Drivers\DriverInterface; * @method setTablePrefix(string $prefix): void * @method truncate(string $table): PDOStatement */ -class QueryBuilderBase { - +class QueryBuilderBase +{ /** * Convenience property for connection management */ @@ -67,7 +69,7 @@ class QueryBuilderBase { * List of queries executed */ public array $queries = [ - 'total_time' => 0 + 'total_time' => 0, ]; /** @@ -110,8 +112,8 @@ class QueryBuilderBase { * Calls a function further down the inheritance chain. * 'Implements' methods on the driver object * - * @return mixed * @throws BadMethodCallException + * @return mixed */ public function __call(string $name, array $params) { @@ -141,7 +143,7 @@ class QueryBuilderBase { // Escape the identifiers $field = $this->driver->quoteIdent($field); - if ( ! \is_string($as)) + if ( ! is_string($as)) { // @codeCoverageIgnoreStart return $field; @@ -149,6 +151,7 @@ class QueryBuilderBase { } $as = $this->driver->quoteIdent($as); + return "({$field}) AS {$as} "; } @@ -224,7 +227,7 @@ class QueryBuilderBase { 'conjunction' => empty($this->state->getHavingMap()) ? ' HAVING ' : " {$conj} ", - 'string' => $item + 'string' => $item, ]); } @@ -242,7 +245,8 @@ class QueryBuilderBase { if (is_scalar($key)) { $pairs[$key] = $val; - } else + } + else { $pairs = $key; } @@ -300,8 +304,6 @@ class QueryBuilderBase { /** * Simplify where_in methods * - * @param mixed $key - * @param mixed $val * @param string $in - The (not) in fragment * @param string $conj - The where in conjunction */ @@ -321,10 +323,8 @@ class QueryBuilderBase { /** * 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) { @@ -346,7 +346,7 @@ class QueryBuilderBase { $totalTime = number_format($endTime - $startTime, 5); // Add this query to the list of executed queries - $this->_appendQuery($vals, $sql, (int)$totalTime); + $this->_appendQuery($vals, $sql, (int) $totalTime); // Reset class state for next query if ($reset) @@ -368,7 +368,7 @@ class QueryBuilderBase { // Quote string values foreach ($evals as &$v) { - $v = ( is_numeric($v)) + $v = (is_numeric($v)) ? $v : htmlentities($this->driver->quote($v), ENT_NOQUOTES, 'utf-8'); } @@ -381,7 +381,7 @@ class QueryBuilderBase { // Add the interpreted query to the list of executed queries $this->queries[] = [ 'time' => $totalTime, - 'sql' => sprintf(...$evals) + 'sql' => sprintf(...$evals), ]; $this->queries['total_time'] += $totalTime; @@ -398,6 +398,7 @@ class QueryBuilderBase { protected function _compileType(QueryType $type = QueryType::SELECT, string $table = ''): string { $setArrayKeys = $this->state->getSetArrayKeys(); + switch ($type) { case QueryType::INSERT: @@ -454,7 +455,7 @@ class QueryBuilderBase { // Set each type of subclause foreach ($clauses as $clause) { - $func = 'get' . ucFirst($clause); + $func = 'get' . ucfirst($clause); $param = $this->state->$func(); if (is_array($param)) { @@ -462,7 +463,8 @@ class QueryBuilderBase { { $sql .= $q['conjunction'] . $q['string']; } - } else + } + else { $sql .= $param; } @@ -530,4 +532,4 @@ class QueryBuilderBase { return $returningSQL; } -} \ No newline at end of file +} diff --git a/src/QueryBuilderInterface.php b/src/QueryBuilderInterface.php index 6716876..bf08dbc 100644 --- a/src/QueryBuilderInterface.php +++ b/src/QueryBuilderInterface.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query; use PDO; @@ -57,8 +58,8 @@ use PDOStatement; * @method setTablePrefix(string $prefix): void * @method truncate(string $table): PDOStatement */ -interface QueryBuilderInterface { - +interface QueryBuilderInterface +{ // -------------------------------------------------------------------------- // ! Select Queries // -------------------------------------------------------------------------- @@ -70,28 +71,28 @@ interface QueryBuilderInterface { /** * 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; /** * 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; /** * 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; /** * 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; @@ -109,8 +110,6 @@ interface QueryBuilderInterface { * Specify the database table to select from * * Alias of `from` method to better match CodeIgniter 4 - * - * @param string $tableName */ public function table(string $tableName): self; @@ -124,29 +123,21 @@ interface QueryBuilderInterface { // -------------------------------------------------------------------------- /** * Creates a Like clause in the sql statement - * - * @param mixed $values */ public function like(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self; /** * Generates an OR Like clause - * - * @param mixed $values */ public function orLike(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self; /** * Generates a NOT LIKE clause - * - * @param mixed $values */ public function notLike(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self; /** * Generates a OR NOT LIKE clause - * - * @param mixed $values */ public function orNotLike(string $field, mixed $values, LikeType|string $pos=LikeType::BOTH): self; @@ -155,17 +146,11 @@ interface QueryBuilderInterface { // -------------------------------------------------------------------------- /** * Generates a 'Having' clause - * - * @param mixed $key - * @param mixed $values */ public function having(mixed $key, mixed $values=[]): self; /** * Generates a 'Having' clause prefixed with 'OR' - * - * @param mixed $key - * @param mixed $values */ public function orHaving(mixed $key, mixed $values=[]): self; @@ -176,9 +161,6 @@ interface QueryBuilderInterface { * Specify condition(s) in the where clause of a query * Note: this function works with key / value, or a * passed array with key / value pairs - * - * @param mixed $key - * @param mixed $values */ public function where(mixed $key, mixed $values=[]): self; @@ -186,39 +168,26 @@ interface QueryBuilderInterface { * Where clause prefixed with "OR" * * @param string $key - * @param mixed $values */ public function orWhere(mixed $key, mixed $values=[]): self; /** * Where clause with 'IN' statement - * - * @param string $field - * @param mixed $values */ public function whereIn(string $field, mixed $values=[]): self; /** * Where in statement prefixed with "or" - * - * @param string $field - * @param mixed $values */ public function orWhereIn(string $field, mixed $values=[]): self; /** * WHERE NOT IN (FOO) clause - * - * @param string $field - * @param mixed $values */ public function whereNotIn(string $field, mixed $values=[]): self; /** * OR WHERE NOT IN (FOO) clause - * - * @param string $field - * @param mixed $values */ public function orWhereNotIn(string $field, mixed $values=[]): self; @@ -228,7 +197,6 @@ interface QueryBuilderInterface { /** * Sets values for inserts / updates / deletes * - * @param mixed $key * @param mixed $values */ public function set(mixed $key, mixed $values = NULL): self; @@ -240,8 +208,6 @@ interface QueryBuilderInterface { /** * Group the results by the selected field(s) - * - * @param mixed $field */ public function groupBy(mixed $field): self; @@ -297,8 +263,6 @@ interface QueryBuilderInterface { /** * 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; @@ -317,8 +281,6 @@ interface QueryBuilderInterface { /** * Creates an insert clause, and executes it - * - * @param mixed $data */ public function insert(string $table, mixed $data=[]): PDOStatement; @@ -331,8 +293,6 @@ interface QueryBuilderInterface { /** * Creates an update clause, and executes it - * - * @param mixed $data */ public function update(string $table, mixed $data=[]): PDOStatement; @@ -348,8 +308,6 @@ interface QueryBuilderInterface { /** * Deletes data from a table - * - * @param mixed $where */ public function delete(string $table, mixed $where=''): PDOStatement; diff --git a/src/QueryParser.php b/src/QueryParser.php index 2c723c9..9972da1 100644 --- a/src/QueryParser.php +++ b/src/QueryParser.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query; use Query\Drivers\DriverInterface; @@ -20,17 +21,8 @@ use Query\Drivers\DriverInterface; /** * Utility Class to parse sql clauses for properly escaping identifiers */ -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' - ]; - +class QueryParser +{ /** * Regex matches */ @@ -41,6 +33,15 @@ class QueryParser { '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 */ @@ -56,12 +57,12 @@ class QueryParser { public function parseJoin(string $sql): array { // Get sql clause components - preg_match_all('`'.$this->matchPatterns['function'].'`', $sql, $this->matches['functions'], PREG_SET_ORDER); - preg_match_all('`'.$this->matchPatterns['identifier'].'`', $sql, $this->matches['identifiers'], PREG_SET_ORDER); - preg_match_all('`'.$this->matchPatterns['operator'].'`', $sql, $this->matches['operators'], PREG_SET_ORDER); + preg_match_all('`' . $this->matchPatterns['function'] . '`', $sql, $this->matches['functions'], PREG_SET_ORDER); + preg_match_all('`' . $this->matchPatterns['identifier'] . '`', $sql, $this->matches['identifiers'], PREG_SET_ORDER); + preg_match_all('`' . $this->matchPatterns['operator'] . '`', $sql, $this->matches['operators'], PREG_SET_ORDER); // Get everything at once for ordering - $fullPattern = '`'.$this->matchPatterns['function'].'+|'.$this->matchPatterns['identifier'].'|('.$this->matchPatterns['operator'].')+`i'; + $fullPattern = '`' . $this->matchPatterns['function'] . '+|' . $this->matchPatterns['identifier'] . '|(' . $this->matchPatterns['operator'] . ')+`i'; preg_match_all($fullPattern, $sql, $this->matches['combined'], PREG_SET_ORDER); // Go through the matches, and get the most relevant matches @@ -79,9 +80,9 @@ class QueryParser { $count = is_countable($parts['identifiers']) ? count($parts['identifiers']) : 0; // 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]); } @@ -92,18 +93,16 @@ class QueryParser { /** * Returns a more useful match array - * - * @return array */ protected function filterArray(array $array): array { $newArray = []; - foreach($array as $row) + foreach ($array as $row) { $newArray[] = (is_array($row)) ? $row[0] : $row; } return $newArray; } -} \ No newline at end of file +} diff --git a/src/QueryType.php b/src/QueryType.php index 36b118d..6e6550e 100644 --- a/src/QueryType.php +++ b/src/QueryType.php @@ -13,16 +13,18 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query; /** * Enum of query types */ -enum QueryType: string { +enum QueryType: string +{ case SELECT = 'select'; case INSERT = 'insert'; case INSERT_BATCH = 'insert_batch'; case UPDATE = 'update'; case UPDATE_BATCH = 'update_batch'; case DELETE = 'delete'; -} \ No newline at end of file +} diff --git a/src/State.php b/src/State.php index 25a2df5..0ab91af 100644 --- a/src/State.php +++ b/src/State.php @@ -13,6 +13,7 @@ * @link https://git.timshomepage.net/aviat/Query * @version 4.0.0 */ + namespace Query; use function is_array; @@ -20,32 +21,33 @@ use function is_array; /** * Query builder state * - * @method getSelectString(): string * @method getFromString(): string - * @method getSetString(): string - * @method getOrderString(): string - * @method getGroupString(): string - * @method getSetArrayKeys(): array - * @method getOrderArray(): array * @method getGroupArray(): array - * @method getValues(): array - * @method getWhereValues(): array + * @method getGroupString(): string + * @method getHavingMap(): array * @method getLimit(): int|null * @method getOffset() + * @method getOrderArray(): array + * @method getOrderString(): string * @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 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 setGroupString(string $groupString): self * @method setLimit(int $limit): 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 // -------------------------------------------------------------------------- @@ -150,6 +152,7 @@ class State { if (isset($this->$maybeProp)) { $this->$maybeProp = $arguments[0]; + return $this; } } @@ -160,30 +163,35 @@ class State { public function appendSelectString(string $str): self { $this->selectString .= $str; + return $this; } public function appendSetArrayKeys(array $setArrayKeys): self { $this->setArrayKeys = array_merge($this->setArrayKeys, $setArrayKeys); + return $this; } public function setOrderArray(string $key, mixed $orderArray): self { $this->orderArray[$key] = $orderArray; + return $this; } public function appendGroupArray(string $groupArray): self { $this->groupArray[] = $groupArray; + return $this; } public function appendValues(array $values): self { $this->values = array_merge($this->values, $values); + return $this; } @@ -191,7 +199,7 @@ class State { { if (is_array($val)) { - foreach($val as $v) + foreach ($val as $v) { $this->whereValues[] = $v; } @@ -200,6 +208,7 @@ class State { } $this->whereValues[] = $val; + return $this; } @@ -211,14 +220,16 @@ class State { $this->queryMap[] = [ 'type' => $type, 'conjunction' => $conjunction, - 'string' => $string + 'string' => $string, ]; + return $this; } public function appendHavingMap(array $item): self { $this->havingMap[] = $item; + return $this; } }