Code style and logic cleanup

This commit is contained in:
Timothy Warren 2019-12-11 16:49:06 -05:00
parent 675e6eff66
commit 83373700d3
12 changed files with 372 additions and 221 deletions

View File

@ -105,7 +105,8 @@ final class ConnectionManager {
{ {
return $this->connections[$name]; return $this->connections[$name];
} }
else if (empty($name) && ! empty($this->connections)) // Otherwise, return the last one
if (empty($name) && ! empty($this->connections)) // Otherwise, return the last one
{ {
return end($this->connections); return end($this->connections);
} }
@ -123,10 +124,10 @@ final class ConnectionManager {
*/ */
public function connect($params): QueryBuilderInterface public function connect($params): QueryBuilderInterface
{ {
[$dsn, $dbtype, $params, $options] = $this->parseParams($params); [$dsn, $dbType, $params, $options] = $this->parseParams($params);
$dbtype = ucfirst($dbtype); $dbType = ucfirst($dbType);
$driver = "\\Query\\Drivers\\{$dbtype}\\Driver"; $driver = "\\Query\\Drivers\\{$dbType}\\Driver";
// Create the database connection // Create the database connection
$db = ! empty($params->user) $db = ! empty($params->user)
@ -159,19 +160,19 @@ final class ConnectionManager {
/** /**
* Parses params into a dsn and option array * Parses params into a dsn and option array
* *
* @param \stdClass $params * @param object | array $params
* @return object|array * @return array
* @throws Exception\BadDBDriverException * @throws Exception\BadDBDriverException
*/ */
public function parseParams($params): array public function parseParams($params): array
{ {
$params = (object) $params; $params = (object) $params;
$params->type = strtolower($params->type); $params->type = strtolower($params->type);
$dbtype = ($params->type !== 'postgresql') ? $params->type : 'pgsql'; $dbType = ($params->type !== 'postgresql') ? $params->type : 'pgsql';
$dbtype = ucfirst($dbtype); $dbType = ucfirst($dbType);
// Make sure the class exists // Make sure the class exists
if ( ! class_exists("\\Query\\Drivers\\{$dbtype}\\Driver")) if ( ! class_exists("\\Query\\Drivers\\{$dbType}\\Driver"))
{ {
throw new Exception\BadDBDriverException('Database driver does not exist, or is not supported'); throw new Exception\BadDBDriverException('Database driver does not exist, or is not supported');
} }
@ -185,28 +186,28 @@ final class ConnectionManager {
} }
// Create the dsn for the database to connect to // Create the dsn for the database to connect to
if(strtolower($dbtype) === 'sqlite') if(strtolower($dbType) === 'sqlite')
{ {
$dsn = $params->file; $dsn = $params->file;
} }
else else
{ {
$dsn = $this->createDsn($dbtype, $params); $dsn = $this->createDsn($dbType, $params);
} }
return [$dsn, $dbtype, $params, $options]; return [$dsn, $dbType, $params, $options];
} }
/** /**
* Create the dsn from the db type and params * Create the dsn from the db type and params
* *
* @codeCoverageIgnore * @codeCoverageIgnore
* @param string $dbtype * @param string $dbType
* @param array|object $params * @param array|object $params
* @return string * @return string
*/ */
private function createDsn(string $dbtype, $params): string private function createDsn(string $dbType, $params): string
{ {
$pairs = []; $pairs = [];
@ -234,6 +235,6 @@ final class ConnectionManager {
} }
} }
return strtolower($dbtype) . ':' . implode(';', $pairs); return strtolower($dbType) . ':' . implode(';', $pairs);
} }
} }

View File

@ -131,6 +131,8 @@ abstract class AbstractDriver
{ {
return \call_user_func_array([$this->$name, '__invoke'], $args); return \call_user_func_array([$this->$name, '__invoke'], $args);
} }
return NULL;
} }
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
@ -325,10 +327,8 @@ abstract class AbstractDriver
foreach($funcs as $f) foreach($funcs as $f)
{ {
// Unquote the function // Unquote the function
$raw = str_replace($f[0], $f[1], $raw);
// Quote the inside identifiers // Quote the inside identifiers
$raw = str_replace($f[3], $this->quoteIdent($f[3]), $raw); $raw = str_replace(array($f[0], $f[3]), array($f[1], $this->quoteIdent($f[3])), $raw);
} }
return $raw; return $raw;
@ -341,7 +341,8 @@ abstract class AbstractDriver
*/ */
public function getSchemas(): ?array public function getSchemas(): ?array
{ {
return NULL; // Most DBMSs conflate schemas and databases
return $this->getDbs();
} }
/** /**
@ -361,7 +362,7 @@ abstract class AbstractDriver
* *
* @return array * @return array
*/ */
public function getDbs(): array public function getDbs(): ?array
{ {
return $this->driverQuery('dbList'); return $this->driverQuery('dbList');
} }
@ -435,7 +436,7 @@ abstract class AbstractDriver
* @param string $table * @param string $table
* @return array * @return array
*/ */
public function getColumns($table): ?array public function getColumns(string $table): ?array
{ {
return $this->driverQuery($this->getSql()->columnList($this->prefixTable($table)), FALSE); return $this->driverQuery($this->getSql()->columnList($this->prefixTable($table)), FALSE);
} }
@ -446,7 +447,7 @@ abstract class AbstractDriver
* @param string $table * @param string $table
* @return array * @return array
*/ */
public function getFks($table): ?array public function getFks(string $table): ?array
{ {
return $this->driverQuery($this->getSql()->fkList($table), FALSE); return $this->driverQuery($this->getSql()->fkList($table), FALSE);
} }
@ -457,7 +458,7 @@ abstract class AbstractDriver
* @param string $table * @param string $table
* @return array * @return array
*/ */
public function getIndexes($table): ?array public function getIndexes(string $table): ?array
{ {
return $this->driverQuery($this->getSql()->indexList($this->prefixTable($table)), FALSE); return $this->driverQuery($this->getSql()->indexList($this->prefixTable($table)), FALSE);
} }

View File

@ -16,9 +16,6 @@ namespace Query\Drivers;
/** /**
* Abstract class defining database / table creation methods * Abstract class defining database / table creation methods
*
* @method string quoteIdent(string $sql)
* @method string quoteTable(string $sql)
*/ */
abstract class AbstractUtil { abstract class AbstractUtil {
@ -43,7 +40,7 @@ abstract class AbstractUtil {
* *
* @return DriverInterface * @return DriverInterface
*/ */
public function getDriver() public function getDriver(): DriverInterface
{ {
return $this->connection; return $this->connection;
} }
@ -57,7 +54,7 @@ abstract class AbstractUtil {
* @param bool $ifNotExists * @param bool $ifNotExists
* @return string * @return string
*/ */
public function createTable($name, $fields, array $constraints=[], $ifNotExists=TRUE) public function createTable($name, $fields, array $constraints=[], $ifNotExists=TRUE): string
{ {
$existsStr = $ifNotExists ? ' IF NOT EXISTS ' : ' '; $existsStr = $ifNotExists ? ' IF NOT EXISTS ' : ' ';
@ -77,8 +74,8 @@ abstract class AbstractUtil {
foreach($columnArray as $n => $props) foreach($columnArray as $n => $props)
{ {
$str = $this->getDriver()->quoteIdent($n); $str = $this->getDriver()->quoteIdent($n);
$str .= isset($props['type']) ? " {$props['type']}" : ""; $str .= isset($props['type']) ? " {$props['type']}" : '';
$str .= isset($props['constraint']) ? " {$props['constraint']}" : ""; $str .= isset($props['constraint']) ? " {$props['constraint']}" : '';
$columns[] = $str; $columns[] = $str;
} }
@ -112,7 +109,7 @@ abstract class AbstractUtil {
* @abstract * @abstract
* @return string * @return string
*/ */
abstract public function backupStructure(); 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
@ -120,6 +117,6 @@ abstract class AbstractUtil {
* @abstract * @abstract
* @return string * @return string
*/ */
abstract public function backupData(); abstract public function backupData(): string;
} }

View File

@ -15,12 +15,27 @@
namespace Query\Drivers; namespace Query\Drivers;
use InvalidArgumentException; use InvalidArgumentException;
use PDO;
use PDOStatement; use PDOStatement;
/** /**
* PDO Interface to implement for database drivers * PDO Interface to implement for database drivers
*
* @method beginTransaction(): bool
* @method commit(): bool
* @method errorCode(): string
* @method errorInfo(): array
* @method exec(string $statement): int
* @method getAttribute(int $attribute)
* @method inTransaction(): bool
* @method lastInsertId(string $name = NULL): string
* @method prepare(string $statement, array $driver_options = []): PDOStatement
* @method query(string $statement): PDOStatement
* @method quote(string $string, int $parameter_type = PDO::PARAM_STR): string
* @method rollback(): bool
* @method setAttribute(int $attribute, $value): bool
*/ */
interface DriverInterface { interface DriverInterface /* extends the interface of PDO */ {
/** /**
* Constructor/Connection method * Constructor/Connection method
@ -48,7 +63,7 @@ interface DriverInterface {
* @param string $table * @param string $table
* @return array * @return array
*/ */
public function getColumns($table): ?array; public function getColumns(string $table): ?array;
/** /**
* Retrieve list of data types for the database * Retrieve list of data types for the database
@ -63,7 +78,7 @@ interface DriverInterface {
* @param string $table * @param string $table
* @return array * @return array
*/ */
public function getIndexes($table): ?array; public function getIndexes(string $table): ?array;
/** /**
* Retrieve foreign keys for the table * Retrieve foreign keys for the table
@ -71,7 +86,7 @@ interface DriverInterface {
* @param string $table * @param string $table
* @return array * @return array
*/ */
public function getFks($table): ?array; public function getFks(string $table): ?array;
/** /**
* Return list of tables for the current database * Return list of tables for the current database
@ -88,6 +103,14 @@ interface DriverInterface {
*/ */
public function getSystemTables(): ?array; public function getSystemTables(): ?array;
/**
* Return schemas for databases that list them. Returns
* database list if schemas are databases for the current driver.
*
* @return array
*/
public function getSchemas(): ?array;
/** /**
* Return list of dbs for the current connection, if possible * Return list of dbs for the current connection, if possible
* *
@ -207,6 +230,14 @@ interface DriverInterface {
*/ */
public function updateBatch(string $table, array $data, string $where): array; public function updateBatch(string $table, array $data, string $where): array;
/**
* Empty the passed table
*
* @param string $table
* @return PDOStatement
*/
public function truncate(string $table): PDOStatement;
/** /**
* Get the SQL class for the current driver * Get the SQL class for the current driver
* *
@ -221,6 +252,13 @@ interface DriverInterface {
*/ */
public function getUtil(): AbstractUtil; public function getUtil(): AbstractUtil;
/**
* Get the last sql query executed
*
* @return string
*/
public function getLastQuery(): string;
/** /**
* Set the last query sql * Set the last query sql
* *
@ -228,4 +266,12 @@ interface DriverInterface {
* @return void * @return void
*/ */
public function setLastQuery(string $queryString): void; public function setLastQuery(string $queryString): void;
/**
* Set the common table name prefix
*
* @param string $prefix
* @return void
*/
public function setTablePrefix(string $prefix): void;
} }

View File

@ -111,6 +111,7 @@ class Util extends AbstractUtil {
{ {
$r = $this->getDriver()->quote($r); $r = $this->getDriver()->quote($r);
} }
unset($r);
$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).');';

View File

@ -75,8 +75,10 @@ SQL;
{ {
foreach(['update', 'delete'] AS $type) foreach(['update', 'delete'] AS $type)
{ {
if ( ! isset($valueMap[$key[$type]])) continue; if ( ! isset($valueMap[$key[$type]]))
{
continue;
}
$key[$type] = $valueMap[$key[$type]]; $key[$type] = $valueMap[$key[$type]];
} }

View File

@ -14,6 +14,9 @@
*/ */
namespace Query\Drivers\Sqlite; namespace Query\Drivers\Sqlite;
use function is_array;
use InvalidArgumentException;
use PDO; use PDO;
use Query\Drivers\AbstractDriver; use Query\Drivers\AbstractDriver;
@ -47,6 +50,16 @@ class Driver extends AbstractDriver {
parent::__construct($dsn, $user, $pass); parent::__construct($dsn, $user, $pass);
} }
/**
* Return list of dbs for the current connection, if possible. Meaningless for SQLite.
*
* @return array | null
*/
public function getDbs(): ?array
{
return NULL;
}
/** /**
* List tables for the current database * List tables for the current database
* *
@ -105,9 +118,9 @@ class Driver extends AbstractDriver {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Each member of the data array needs to be an array // Each member of the data array needs to be an array
if ( ! \is_array(current($data))) if ( ! is_array(current($data)))
{ {
return NULL; throw new InvalidArgumentException('$data must be an array of arrays');
} }
// Start the block of sql statements // Start the block of sql statements
@ -117,9 +130,9 @@ 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);
} }
$sql .= 'SELECT ' . implode(', ', $cols) . "\n"; $sql .= 'SELECT ' . implode(', ', $cols) . "\n";

View File

@ -44,13 +44,14 @@ class SQL extends AbstractSQL {
} }
/** /**
* Returns sql to list other databases * Returns sql to list other databases. Meaningless for SQLite, as this
* just returns the database(s) that we are currently connected to.
* *
* @return string * @return string
*/ */
public function dbList(): string public function dbList(): string
{ {
return 'PRAGMA database_list'; return '';
} }
/** /**

View File

@ -73,9 +73,11 @@ class Util extends AbstractUtil {
$row = array_values($row); $row = array_values($row);
// Quote values as needed by type // Quote values as needed by type
for($i=0, $icount=count($row); $i<$icount; $i++) foreach ($row as $i => $_)
{ {
$row[$i] = is_numeric($row[$i]) ? $row[$i] : $this->getDriver()->quote($row[$i]); $row[$i] = (is_numeric($row[$i]))
? $row[$i]
: $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).');';
@ -112,6 +114,6 @@ class Util extends AbstractUtil {
$sqlArray[] = $r['sql']; $sqlArray[] = $r['sql'];
} }
return implode(";\n", $sqlArray) . ";"; return implode(";\n", $sqlArray) . ';';
} }
} }

View File

@ -17,11 +17,47 @@ namespace Query;
use function regexInArray; use function regexInArray;
use BadMethodCallException; use BadMethodCallException;
use PDO;
use PDOStatement; use PDOStatement;
use Query\Drivers\DriverInterface; use Query\Drivers\DriverInterface;
/** /**
* Convenience class for creating sql queries * Convenience class for creating sql queries
*
* @method affectedRows(): int
* @method beginTransaction(): bool
* @method commit(): bool
* @method errorCode(): string
* @method errorInfo(): array
* @method exec(string $statement): int
* @method getAttribute(int $attribute)
* @method getColumns(string $table): array | null
* @method getDbs(): array | null
* @method getFks(string $table): array | null
* @method getFunctions(): array | null
* @method getIndexes(string $table): array | null
* @method getLastQuery(): string
* @method getProcedures(): array | null
* @method getSchemas(): array | null
* @method getSequences(): array | null
* @method getSystemTables(): array | null
* @method getTables(): array
* @method getTriggers(): array | null
* @method getTypes(): array | null
* @method getUtil(): \Query\Drivers\AbstractUtil
* @method getViews(): array | null
* @method inTransaction(): bool
* @method lastInsertId(string $name = NULL): string
* @method numRows(): int | null
* @method prepare(string $statement, array $driver_options = []): PDOStatement
* @method prepareExecute(string $sql, array $params): PDOStatement
* @method prepareQuery(string $sql, array $data): PDOStatement
* @method query(string $statement): PDOStatement
* @method quote(string $string, int $parameter_type = PDO::PARAM_STR): string
* @method rollback(): bool
* @method setAttribute(int $attribute, $value): bool
* @method setTablePrefix(string $prefix): void
* @method truncate(string $table): PDOStatement
*/ */
class QueryBuilder implements QueryBuilderInterface { class QueryBuilder implements QueryBuilderInterface {
@ -49,7 +85,7 @@ class QueryBuilder implements QueryBuilderInterface {
* The current database driver * The current database driver
* @var DriverInterface * @var DriverInterface
*/ */
public $driver; protected $driver;
/** /**
* Query parser class instance * Query parser class instance
@ -93,7 +129,8 @@ class QueryBuilder implements QueryBuilderInterface {
} }
/** /**
* Calls a function further down the inheritance chain * Calls a function further down the inheritance chain.
* 'Implements' methods on the driver object
* *
* @param string $name * @param string $name
* @param array $params * @param array $params
@ -211,6 +248,16 @@ class QueryBuilder implements QueryBuilderInterface {
return $this; return $this;
} }
/**
* @todo implement
* @param string $fields
* @return $this
*/
public function returning(string $fields = '*'): QueryBuilderInterface
{
return $this;
}
/** /**
* Adds the 'distinct' keyword to a query * Adds the 'distinct' keyword to a query
* *
@ -937,9 +984,9 @@ class QueryBuilder implements QueryBuilderInterface {
* @param string $pos * @param string $pos
* @param string $like * @param string $like
* @param string $conj * @param string $conj
* @return self * @return QueryBuilderInterface
*/ */
protected function _like(string $field, $val, string $pos, string $like='LIKE', string $conj='AND'): self protected function _like(string $field, $val, string $pos, string $like='LIKE', string $conj='AND'): QueryBuilderInterface
{ {
$field = $this->driver->quoteIdent($field); $field = $this->driver->quoteIdent($field);
@ -974,9 +1021,9 @@ class QueryBuilder implements QueryBuilderInterface {
* @param mixed $key * @param mixed $key
* @param mixed $values * @param mixed $values
* @param string $conj * @param string $conj
* @return self * @return QueryBuilderInterface
*/ */
protected function _having($key, $values=[], string $conj='AND'): self protected function _having($key, $values=[], string $conj='AND'): QueryBuilderInterface
{ {
$where = $this->_where($key, $values); $where = $this->_where($key, $values);
@ -1040,9 +1087,9 @@ class QueryBuilder implements QueryBuilderInterface {
* @param mixed $key * @param mixed $key
* @param mixed $values * @param mixed $values
* @param string $defaultConj * @param string $defaultConj
* @return self * @return QueryBuilderInterface
*/ */
protected function _whereString($key, $values=[], string $defaultConj='AND'): self protected function _whereString($key, $values=[], string $defaultConj='AND'): QueryBuilderInterface
{ {
// Create key/value placeholders // Create key/value placeholders
foreach($this->_where($key, $values) as $f => $val) foreach($this->_where($key, $values) as $f => $val)
@ -1087,9 +1134,9 @@ class QueryBuilder implements QueryBuilderInterface {
* @param mixed $val * @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
* @return self * @return QueryBuilderInterface
*/ */
protected function _whereIn($key, $val=[], string $in='IN', string $conj='AND'): self protected function _whereIn($key, $val=[], string $in='IN', string $conj='AND'): QueryBuilderInterface
{ {
$key = $this->driver->quoteIdent($key); $key = $this->driver->quoteIdent($key);
$params = array_fill(0, count($val), '?'); $params = array_fill(0, count($val), '?');
@ -1166,6 +1213,7 @@ class QueryBuilder implements QueryBuilderInterface {
? htmlentities($this->driver->quote($v), ENT_NOQUOTES, 'utf-8') ? htmlentities($this->driver->quote($v), ENT_NOQUOTES, 'utf-8')
: $v; : $v;
} }
unset($v);
// Add the query onto the array of values to pass // Add the query onto the array of values to pass
// as arguments to sprintf // as arguments to sprintf

View File

@ -14,10 +14,46 @@
*/ */
namespace Query; namespace Query;
use PDO;
use PDOStatement; use PDOStatement;
/** /**
* Interface defining the Query Builder class * Interface defining the Query Builder class
*
* @method affectedRows(): int
* @method beginTransaction(): bool
* @method commit(): bool
* @method errorCode(): string
* @method errorInfo(): array
* @method exec(string $statement): int
* @method getAttribute(int $attribute)
* @method getColumns(string $table): array | null
* @method getDbs(): array | null
* @method getFks(string $table): array | null
* @method getFunctions(): array | null
* @method getIndexes(string $table): array | null
* @method getLastQuery(): string
* @method getProcedures(): array | null
* @method getSchemas(): array | null
* @method getSequences(): array | null
* @method getSystemTables(): array | null
* @method getTables(): array
* @method getTriggers(): array | null
* @method getTypes(): array | null
* @method getUtil(): \Query\Drivers\AbstractUtil
* @method getViews(): array | null
* @method inTransaction(): bool
* @method lastInsertId(string $name = NULL): string
* @method numRows(): int | null
* @method prepare(string $statement, array $driver_options = []): PDOStatement
* @method prepareExecute(string $sql, array $params): PDOStatement
* @method prepareQuery(string $sql, array $data): PDOStatement
* @method query(string $statement): PDOStatement
* @method quote(string $string, int $parameter_type = PDO::PARAM_STR): string
* @method rollback(): bool
* @method setAttribute(int $attribute, $value): bool
* @method setTablePrefix(string $prefix): void
* @method truncate(string $table): PDOStatement
*/ */
interface QueryBuilderInterface { interface QueryBuilderInterface {
@ -29,67 +65,67 @@ interface QueryBuilderInterface {
* Specifies rows to select in a query * Specifies rows to select in a query
* *
* @param string $fields * @param string $fields
* @return QueryBuilderInterface * @return self
*/ */
public function select(string $fields): QueryBuilderInterface; public function select(string $fields): self;
/** /**
* Selects the maximum value of a field from a query * Selects the maximum value of a field from a query
* *
* @param string $field * @param string $field
* @param string|bool $as * @param string|bool $as
* @return QueryBuilderInterface * @return self
*/ */
public function selectMax(string $field, $as=FALSE): QueryBuilderInterface; 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 $field * @param string $field
* @param string|bool $as * @param string|bool $as
* @return QueryBuilderInterface * @return self
*/ */
public function selectMin(string $field, $as=FALSE): QueryBuilderInterface; 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 $field * @param string $field
* @param string|bool $as * @param string|bool $as
* @return QueryBuilderInterface * @return self
*/ */
public function selectAvg(string $field, $as=FALSE): QueryBuilderInterface; 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 $field * @param string $field
* @param string|bool $as * @param string|bool $as
* @return QueryBuilderInterface * @return self
*/ */
public function selectSum(string $field, $as=FALSE): QueryBuilderInterface; public function selectSum(string $field, $as=FALSE): self;
/** /**
* Adds the 'distinct' keyword to a query * Adds the 'distinct' keyword to a query
* *
* @return QueryBuilderInterface * @return self
*/ */
public function distinct(): QueryBuilderInterface; public function distinct(): self;
/** /**
* Shows the query plan for the query * Shows the query plan for the query
* *
* @return QueryBuilderInterface * @return self
*/ */
public function explain(): QueryBuilderInterface; public function explain(): self;
/** /**
* Specify the database table to select from * Specify the database table to select from
* *
* @param string $tblname * @param string $tblname
* @return QueryBuilderInterface * @return self
*/ */
public function from(string $tblname): QueryBuilderInterface; public function from(string $tblname): self;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// ! 'Like' methods // ! 'Like' methods
@ -101,9 +137,9 @@ interface QueryBuilderInterface {
* @param string $field * @param string $field
* @param mixed $values * @param mixed $values
* @param string $pos * @param string $pos
* @return QueryBuilderInterface * @return self
*/ */
public function like(string $field, $values, string $pos='both'): QueryBuilderInterface; public function like(string $field, $values, string $pos='both'): self;
/** /**
* Generates an OR Like clause * Generates an OR Like clause
@ -111,9 +147,9 @@ interface QueryBuilderInterface {
* @param string $field * @param string $field
* @param mixed $values * @param mixed $values
* @param string $pos * @param string $pos
* @return QueryBuilderInterface * @return self
*/ */
public function orLike(string $field, $values, string $pos='both'): QueryBuilderInterface; public function orLike(string $field, $values, string $pos='both'): self;
/** /**
* Generates a NOT LIKE clause * Generates a NOT LIKE clause
@ -121,9 +157,9 @@ interface QueryBuilderInterface {
* @param string $field * @param string $field
* @param mixed $values * @param mixed $values
* @param string $pos * @param string $pos
* @return QueryBuilderInterface * @return self
*/ */
public function notLike(string $field, $values, string $pos='both'): QueryBuilderInterface; public function notLike(string $field, $values, string $pos='both'): self;
/** /**
* Generates a OR NOT LIKE clause * Generates a OR NOT LIKE clause
@ -131,9 +167,9 @@ interface QueryBuilderInterface {
* @param string $field * @param string $field
* @param mixed $values * @param mixed $values
* @param string $pos * @param string $pos
* @return QueryBuilderInterface * @return self
*/ */
public function orNotLike(string $field, $values, string $pos='both'): QueryBuilderInterface; public function orNotLike(string $field, $values, string $pos='both'): self;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// ! Having methods // ! Having methods
@ -144,18 +180,18 @@ interface QueryBuilderInterface {
* *
* @param mixed $key * @param mixed $key
* @param mixed $values * @param mixed $values
* @return QueryBuilderInterface * @return self
*/ */
public function having($key, $values=[]): QueryBuilderInterface; public function having($key, $values=[]): self;
/** /**
* Generates a 'Having' clause prefixed with 'OR' * Generates a 'Having' clause prefixed with 'OR'
* *
* @param mixed $key * @param mixed $key
* @param mixed $values * @param mixed $values
* @return QueryBuilderInterface * @return self
*/ */
public function orHaving($key, $values=[]): QueryBuilderInterface; public function orHaving($key, $values=[]): self;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// ! 'Where' methods // ! 'Where' methods
@ -169,54 +205,54 @@ interface QueryBuilderInterface {
* @param mixed $key * @param mixed $key
* @param mixed $values * @param mixed $values
* @param bool $escape * @param bool $escape
* @return QueryBuilderInterface * @return self
*/ */
public function where($key, $values=[], $escape = NULL): QueryBuilderInterface; public function where($key, $values=[], $escape = NULL): self;
/** /**
* Where clause prefixed with "OR" * Where clause prefixed with "OR"
* *
* @param string $key * @param string $key
* @param mixed $values * @param mixed $values
* @return QueryBuilderInterface * @return self
*/ */
public function orWhere($key, $values=[]): QueryBuilderInterface; public function orWhere($key, $values=[]): self;
/** /**
* Where clause with 'IN' statement * Where clause with 'IN' statement
* *
* @param mixed $field * @param mixed $field
* @param mixed $values * @param mixed $values
* @return QueryBuilderInterface * @return self
*/ */
public function whereIn($field, $values=[]): QueryBuilderInterface; public function whereIn($field, $values=[]): self;
/** /**
* Where in statement prefixed with "or" * Where in statement prefixed with "or"
* *
* @param string $field * @param string $field
* @param mixed $values * @param mixed $values
* @return QueryBuilderInterface * @return self
*/ */
public function orWhereIn($field, $values=[]): QueryBuilderInterface; public function orWhereIn($field, $values=[]): self;
/** /**
* WHERE NOT IN (FOO) clause * WHERE NOT IN (FOO) clause
* *
* @param string $field * @param string $field
* @param mixed $values * @param mixed $values
* @return QueryBuilderInterface * @return self
*/ */
public function whereNotIn($field, $values=[]): QueryBuilderInterface; public function whereNotIn($field, $values=[]): self;
/** /**
* OR WHERE NOT IN (FOO) clause * OR WHERE NOT IN (FOO) clause
* *
* @param string $field * @param string $field
* @param mixed $values * @param mixed $values
* @return QueryBuilderInterface * @return self
*/ */
public function orWhereNotIn($field, $values=[]): QueryBuilderInterface; public function orWhereNotIn($field, $values=[]): self;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// ! Other Query Modifier methods // ! Other Query Modifier methods
@ -227,9 +263,9 @@ interface QueryBuilderInterface {
* *
* @param mixed $key * @param mixed $key
* @param mixed $values * @param mixed $values
* @return QueryBuilderInterface * @return self
*/ */
public function set($key, $values = NULL): QueryBuilderInterface; public function set($key, $values = NULL): self;
/** /**
* Creates a join phrase in a compiled query * Creates a join phrase in a compiled query
@ -237,35 +273,35 @@ interface QueryBuilderInterface {
* @param string $table * @param string $table
* @param string $condition * @param string $condition
* @param string $type * @param string $type
* @return QueryBuilderInterface * @return self
*/ */
public function join(string $table, string $condition, string $type=''): QueryBuilderInterface; public function join(string $table, string $condition, string $type=''): self;
/** /**
* Group the results by the selected field(s) * Group the results by the selected field(s)
* *
* @param mixed $field * @param mixed $field
* @return QueryBuilderInterface * @return self
*/ */
public function groupBy($field): QueryBuilderInterface; public function groupBy($field): self;
/** /**
* Order the results by the selected field(s) * Order the results by the selected field(s)
* *
* @param string $field * @param string $field
* @param string $type * @param string $type
* @return QueryBuilderInterface * @return self
*/ */
public function orderBy(string $field, string $type=''): QueryBuilderInterface; public function orderBy(string $field, string $type=''): self;
/** /**
* Set a limit on the current sql statement * Set a limit on the current sql statement
* *
* @param int $limit * @param int $limit
* @param int|bool $offset * @param int|bool $offset
* @return QueryBuilderInterface * @return self
*/ */
public function limit(int $limit, $offset=FALSE): QueryBuilderInterface; public function limit(int $limit, $offset=FALSE): self;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// ! Query Grouping Methods // ! Query Grouping Methods
@ -274,40 +310,40 @@ interface QueryBuilderInterface {
/** /**
* Adds a paren to the current query for query grouping * Adds a paren to the current query for query grouping
* *
* @return QueryBuilderInterface * @return self
*/ */
public function groupStart(): QueryBuilderInterface; public function groupStart(): self;
/** /**
* Adds a paren to the current query for query grouping, * Adds a paren to the current query for query grouping,
* prefixed with 'NOT' * prefixed with 'NOT'
* *
* @return QueryBuilderInterface * @return self
*/ */
public function notGroupStart(): QueryBuilderInterface; public function notGroupStart(): self;
/** /**
* Adds a paren to the current query for query grouping, * Adds a paren to the current query for query grouping,
* prefixed with 'OR' * prefixed with 'OR'
* *
* @return QueryBuilderInterface * @return self
*/ */
public function orGroupStart(): QueryBuilderInterface; public function orGroupStart(): self;
/** /**
* Adds a paren to the current query for query grouping, * Adds a paren to the current query for query grouping,
* prefixed with 'OR NOT' * prefixed with 'OR NOT'
* *
* @return QueryBuilderInterface * @return self
*/ */
public function orNotGroupStart(): QueryBuilderInterface; public function orNotGroupStart(): self;
/** /**
* Ends a query group * Ends a query group
* *
* @return QueryBuilderInterface * @return self
*/ */
public function groupEnd(): QueryBuilderInterface; public function groupEnd(): self;
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// ! Query execution methods // ! Query execution methods

View File

@ -13,129 +13,132 @@
* @link https://git.timshomepage.net/aviat4ion/Query * @link https://git.timshomepage.net/aviat4ion/Query
*/ */
use Query\{ namespace {
ConnectionManager,
QueryBuilderInterface
};
/** use Query\{
* Global functions that don't really fit anywhere else ConnectionManager,
*/ QueryBuilderInterface
};
/** /**
* Multibyte-safe trim function * Global functions that don't really fit anywhere else
* */
* @param string $string
* @return string
*/
function mb_trim(string $string): string
{
return preg_replace('/(^\s+)|(\s+$)/u', '', $string);
}
/** /**
* Filter out db rows into one array * Multibyte-safe trim function
* *
* @param array $array * @param string $string
* @param mixed $index * @return string
* @return array */
*/ function mb_trim(string $string): string
function dbFilter(array $array, $index): array
{
$newArray = [];
foreach($array as $a)
{ {
$newArray[] = $a[$index]; return preg_replace('/(^\s+)|(\s+$)/u', '', $string);
} }
return $newArray; /**
} * Filter out db rows into one array
*
/** * @param array $array
* Zip a set of arrays together on common keys * @param mixed $index
* * @return array
* The $zipperInput array is an array of arrays indexed by their place in the output */
* array. function dbFilter(array $array, $index): array
*
* @param array $zipperInput
* @return array
*/
function arrayZipper(array $zipperInput): array
{
$output = [];
foreach($zipperInput as $appendKey => $values)
{ {
foreach($values as $index => $value) $newArray = [];
foreach ($array as $a)
{ {
if ( ! isset($output[$index])) $newArray[] = $a[$index];
{
$output[$index] = [];
}
$output[$index][$appendKey] = $value;
} }
return $newArray;
} }
return $output; /**
} * Zip a set of arrays together on common keys
*
/** * The $zipperInput array is an array of arrays indexed by their place in the output
* Determine whether a value in the passed array matches the pattern * array.
* passed *
* * @param array $zipperInput
* @param array $array * @return array
* @param string $pattern */
* @return bool function arrayZipper(array $zipperInput): array
*/
function regexInArray(array $array, string $pattern): bool
{
if (empty($array))
{ {
$output = [];
foreach ($zipperInput as $appendKey => $values)
{
foreach ($values as $index => $value)
{
if ( ! isset($output[$index]))
{
$output[$index] = [];
}
$output[$index][$appendKey] = $value;
}
}
return $output;
}
/**
* Determine whether a value in the passed array matches the pattern
* passed
*
* @param array $array
* @param string $pattern
* @return bool
*/
function regexInArray(array $array, string $pattern): bool
{
if (empty($array))
{
return FALSE;
}
foreach ($array as $item)
{
if (is_scalar($item) && preg_match($pattern, $item))
{
return TRUE;
}
}
return FALSE; return FALSE;
} }
foreach($array as $item) /**
* Connection function
*
* Send an array or object as connection parameters to create a connection. If
* the array or object has an 'alias' parameter, passing that string to this
* function will return that connection. Passing no parameters returns the last
* connection created.
*
* @param string|object|array $params
* @return QueryBuilderInterface|null
*/
function Query($params = ''): ?QueryBuilderInterface
{ {
if (is_scalar($item) && preg_match($pattern, $item)) if ($params === NULL)
{ {
return TRUE; return NULL;
} }
$manager = ConnectionManager::getInstance();
// If you are getting a previously created connection
if (is_scalar($params))
{
return $manager->getConnection($params);
}
$paramsObject = (object)$params;
// Otherwise, return a new connection
return $manager->connect($paramsObject);
} }
return FALSE;
} }
/**
* Connection function
*
* Send an array or object as connection parameters to create a connection. If
* the array or object has an 'alias' parameter, passing that string to this
* function will return that connection. Passing no parameters returns the last
* connection created.
*
* @param string|object|array $params
* @return QueryBuilderInterface|null
*/
function Query($params = ''): ?QueryBuilderInterface
{
if ($params === NULL)
{
return NULL;
}
$manager = ConnectionManager::getInstance();
// If you are getting a previously created connection
if (is_scalar($params))
{
return $manager->getConnection($params);
}
$paramsObject = (object) $params;
// Otherwise, return a new connection
return $manager->connect($paramsObject);
}
// End of common.php // End of common.php