mirror of
https://github.com/Lastorder-DC/rhymix.git
synced 2026-05-10 04:24:14 +09:00
More work on the query parser
This commit is contained in:
parent
92ff69591f
commit
6eca8736c1
6 changed files with 422 additions and 76 deletions
18
common/framework/exceptions/queryerror.php
Normal file
18
common/framework/exceptions/queryerror.php
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Rhymix\Framework\Exceptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Query Error exception class.
|
||||||
|
*/
|
||||||
|
class QueryError extends \Rhymix\Framework\Exception
|
||||||
|
{
|
||||||
|
public function __construct($message = '', $code = 0, $previous = null)
|
||||||
|
{
|
||||||
|
if ($message === '')
|
||||||
|
{
|
||||||
|
$message = 'Query Error';
|
||||||
|
}
|
||||||
|
parent::__construct($message, $code, $previous);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,49 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Rhymix\Framework\Parsers\DBQuery;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Expression class.
|
|
||||||
*/
|
|
||||||
class Expression
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Instance properties.
|
|
||||||
*/
|
|
||||||
public $type;
|
|
||||||
public $value;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param string $type
|
|
||||||
* @param mixed $value
|
|
||||||
*/
|
|
||||||
public function __construct(string $type, $value = null)
|
|
||||||
{
|
|
||||||
$this->type = $type;
|
|
||||||
$this->value = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the string representation of this expression.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function __toString()
|
|
||||||
{
|
|
||||||
switch ($this->type)
|
|
||||||
{
|
|
||||||
case 'var':
|
|
||||||
return ':' . $this->value;
|
|
||||||
case 'null':
|
|
||||||
return 'NULL';
|
|
||||||
case 'string':
|
|
||||||
return;
|
|
||||||
case 'int':
|
|
||||||
return $this->value;
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -18,4 +18,215 @@ class Query
|
||||||
public $conditions = array();
|
public $conditions = array();
|
||||||
public $groupby = null;
|
public $groupby = null;
|
||||||
public $navigation = null;
|
public $navigation = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attributes for query generation.
|
||||||
|
*/
|
||||||
|
protected $_prefix = '';
|
||||||
|
protected $_args = array();
|
||||||
|
protected $_column_list = array();
|
||||||
|
protected $_params = array();
|
||||||
|
protected $_temp_num = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate the query string for this query.
|
||||||
|
*
|
||||||
|
* @param string $prefix
|
||||||
|
* @param array $args
|
||||||
|
* @param array $column_list
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getQueryString(string $prefix = '', array $args, array $column_list = []): string
|
||||||
|
{
|
||||||
|
// Save the query information.
|
||||||
|
$this->_prefix = $prefix;
|
||||||
|
$this->_args = $args;
|
||||||
|
$this->_column_list = $column_list;
|
||||||
|
$this->_temp_num = 0;
|
||||||
|
|
||||||
|
// Call different internal methods depending on the query type.
|
||||||
|
switch ($this->type)
|
||||||
|
{
|
||||||
|
case 'SELECT':
|
||||||
|
return $this->_getSelectQueryString();
|
||||||
|
default:
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the query parameters to use with the query string generated above.
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getQueryParams()
|
||||||
|
{
|
||||||
|
return $this->_params;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a SELECT query string.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function _getSelectQueryString(): string
|
||||||
|
{
|
||||||
|
// Initialize the query string.
|
||||||
|
$result = 'SELECT ';
|
||||||
|
|
||||||
|
// Compose the column list.
|
||||||
|
$columns = array();
|
||||||
|
if ($this->_column_list)
|
||||||
|
{
|
||||||
|
$result .= implode(', ', array_map(function($str) {
|
||||||
|
return '`' . $str . '`';
|
||||||
|
}, $this->_column_list));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach ($this->columns as $column)
|
||||||
|
{
|
||||||
|
if ($column instanceof self)
|
||||||
|
{
|
||||||
|
$subquery = $column->getQueryString($this->_prefix, $this->_args);
|
||||||
|
foreach ($column->getQueryParams() as $key => $val)
|
||||||
|
{
|
||||||
|
$this->_params[$key] = $val;
|
||||||
|
}
|
||||||
|
$columns[] = sprintf('(%s) AS %s', $subquery, self::quoteName($column->alias));
|
||||||
|
}
|
||||||
|
elseif ($column->is_expression && !$column->is_wildcard)
|
||||||
|
{
|
||||||
|
$columns[] = $column->name . ($column->alias ? (' AS ' . self::quoteName($column->alias)) : '');
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$columns[] = self::quoteName($column->name) . ($column->alias ? (' AS ' . self::quoteName($column->alias)) : '');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result .= implode(', ', $columns);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compose the table list.
|
||||||
|
$tables = array();
|
||||||
|
foreach ($this->tables as $table)
|
||||||
|
{
|
||||||
|
if ($table instanceof self)
|
||||||
|
{
|
||||||
|
$subquery = $table->getQueryString($this->_prefix, $this->_args);
|
||||||
|
foreach ($table->getQueryParams() as $key => $val)
|
||||||
|
{
|
||||||
|
$this->_params[$key] = $val;
|
||||||
|
}
|
||||||
|
$tables[] = sprintf('(%s) AS `%s`', $subquery, $table->alias);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$tabledef = self::quoteName($table->name) . ($table->alias ? (' AS `' . $table->alias . '`') : '');
|
||||||
|
if ($table->join_type)
|
||||||
|
{
|
||||||
|
$tabledef = $table->join_type . ' ' . $tabledef;
|
||||||
|
$join_where = $this->_arrangeConditions($table->join_conditions);
|
||||||
|
if ($join_where !== '')
|
||||||
|
{
|
||||||
|
$tabledef = $tabledef . ' ON ' . $join_where;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$tables[] = $tabledef;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$result .= ' FROM ' . implode(', ', $tables);
|
||||||
|
|
||||||
|
// Compose the conditions.
|
||||||
|
if (count($this->conditions))
|
||||||
|
{
|
||||||
|
$where = $this->_arrangeConditions($this->conditions);
|
||||||
|
if ($where !== '')
|
||||||
|
{
|
||||||
|
$result .= ' WHERE ' . $where;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compose the GROUP BY clause.
|
||||||
|
|
||||||
|
// Compose the LIMIT clause.
|
||||||
|
|
||||||
|
// Return the final query string.
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a WHERE clause from a list of conditions.
|
||||||
|
*
|
||||||
|
* @param array $conditions
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function _arrangeConditions(array $conditions): string
|
||||||
|
{
|
||||||
|
// Initialize the result.
|
||||||
|
$result = '';
|
||||||
|
|
||||||
|
// Process each condition.
|
||||||
|
foreach ($conditions as $condition)
|
||||||
|
{
|
||||||
|
// Subquery
|
||||||
|
if ($condition instanceof self)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// Condition group
|
||||||
|
elseif ($condition instanceof ConditionGroup)
|
||||||
|
{
|
||||||
|
$condition_string = $this->_arrangeConditions($condition->conditions);
|
||||||
|
if ($condition_string === '')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$result .= ($result === '' ? '' : (' ' . $condition->pipe . ' ')) . '(' . $condition_string . ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simple condition
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$condition_string = $this->_parseCondition($condition);
|
||||||
|
if ($condition_string === '')
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$result .= ($result === '' ? '' : (' ' . $condition->pipe . ' ')) . $condition_string;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the WHERE clause.
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate each condition in a WHERE clause.
|
||||||
|
*
|
||||||
|
* @param object $condition
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
protected function _parseCondition(Condition $condition): string
|
||||||
|
{
|
||||||
|
list($where, $params) = $condition->getQueryStringAndParams($this->_args);
|
||||||
|
foreach ($params as $key => $val)
|
||||||
|
{
|
||||||
|
$this->_params[$key] = $val;
|
||||||
|
}
|
||||||
|
return $where;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Quote a column name.
|
||||||
|
*/
|
||||||
|
public static function quoteName($column_name): string
|
||||||
|
{
|
||||||
|
$columns = explode('.', $column_name);
|
||||||
|
$columns = array_map(function($str) {
|
||||||
|
return $str === '*' ? $str : ('`' . $str . '`');
|
||||||
|
}, $columns);
|
||||||
|
return implode('.', $columns);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,63 +14,229 @@ class VariableBase
|
||||||
public $default;
|
public $default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the value of this variable.
|
* Convert an operator into real SQL.
|
||||||
*
|
*
|
||||||
* @return Expression
|
* @param array $args
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getValue(): Expression
|
public function getQueryStringAndParams(array $args): array
|
||||||
{
|
{
|
||||||
if ($this->var)
|
// Return if this method is called on an invalid child class.
|
||||||
|
if (!isset($this->column) || !isset($this->operation))
|
||||||
{
|
{
|
||||||
return new Expression('var', $this->var);
|
throw new \Rhymix\Framework\Exceptions\QueryError('Invalid invocation of getQueryStringAndParams()');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the variable or default value.
|
||||||
|
if ($this->var && isset($args[$this->var]) && !empty($args[$this->var]))
|
||||||
|
{
|
||||||
|
$this->filterValue($args[$this->var]);
|
||||||
|
$value = $args[$this->var];
|
||||||
|
}
|
||||||
|
elseif ($this->default !== null)
|
||||||
|
{
|
||||||
|
$value = $this->getDefaultValue();
|
||||||
|
}
|
||||||
|
elseif ($this->not_null)
|
||||||
|
{
|
||||||
|
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' is not set');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return $this->getDefaultValue();
|
return ['', []];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Quote the column name.
|
||||||
|
$column = Query::quoteName($this->column);
|
||||||
|
$where = '';
|
||||||
|
$params = array();
|
||||||
|
|
||||||
|
// Prepare the target value.
|
||||||
|
$list_ops = array('in' => true, 'notin' => true, 'not_in' => true, 'between' => true);
|
||||||
|
if (isset($list_ops[$this->operation]) && !is_array($value) && $value !== '')
|
||||||
|
{
|
||||||
|
$value = explode(',', preg_replace('/[\s\']/', '', $value));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Apply the operator.
|
||||||
|
switch ($this->operation)
|
||||||
|
{
|
||||||
|
case 'equal':
|
||||||
|
$where = sprintf('%s = ?', $column);
|
||||||
|
$params[] = $value;
|
||||||
|
break;
|
||||||
|
case 'like':
|
||||||
|
$where = sprintf('%s LIKE ?', $column);
|
||||||
|
$params[] = '%' . $value . '%';
|
||||||
|
break;
|
||||||
|
case 'like_prefix':
|
||||||
|
case 'like_head':
|
||||||
|
$where = sprintf('%s LIKE ?', $column);
|
||||||
|
$params[] = $value . '%';
|
||||||
|
break;
|
||||||
|
case 'like_suffix':
|
||||||
|
case 'like_tail':
|
||||||
|
$where = sprintf('%s LIKE ?', $column);
|
||||||
|
$params[] = '%' . $value;
|
||||||
|
break;
|
||||||
|
case 'notlike':
|
||||||
|
$where = sprintf('%s NOT LIKE ?', $column);
|
||||||
|
$params[] = '%' . $value . '%';
|
||||||
|
break;
|
||||||
|
case 'notlike_prefix':
|
||||||
|
case 'notlike_head':
|
||||||
|
$where = sprintf('%s NOT LIKE ?', $column);
|
||||||
|
$params[] = $value . '%';
|
||||||
|
break;
|
||||||
|
case 'notlike_suffix':
|
||||||
|
case 'notlike_tail':
|
||||||
|
$where = sprintf('%s NOT LIKE ?', $column);
|
||||||
|
$params[] = '%' . $value;
|
||||||
|
break;
|
||||||
|
case 'in':
|
||||||
|
$count = count($value);
|
||||||
|
$placeholders = implode(', ', array_fill(0, $count, '?'));
|
||||||
|
$where = sprintf('%s IN (%s)', $column, $placeholders);
|
||||||
|
foreach ($value as $item)
|
||||||
|
{
|
||||||
|
$params[] = $item;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'notin':
|
||||||
|
case 'not_in':
|
||||||
|
$count = count($value);
|
||||||
|
$placeholders = implode(', ', array_fill(0, $count, '?'));
|
||||||
|
$where = sprintf('%s NOT IN (%s)', $column, $placeholders);
|
||||||
|
foreach ($value as $item)
|
||||||
|
{
|
||||||
|
$params[] = $item;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'between':
|
||||||
|
$where = sprintf('%s BETWEEN ? AND ?', $column);
|
||||||
|
foreach ($value as $item)
|
||||||
|
{
|
||||||
|
$params[] = $item;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return the complete condition and parameters.
|
||||||
|
return [$where, $params];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the default value of this variable.
|
* Get the default value of this variable.
|
||||||
*
|
*
|
||||||
* @return Expression
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function getDefaultValue(): Expression
|
public function getDefaultValue()
|
||||||
{
|
{
|
||||||
// If the default value is not set, return null.
|
// If the default value is a column name, escape it.
|
||||||
$val = $this->default;
|
if (preg_match('/^[a-z0-9_]+(?:\.[a-z0-9_]+)+$/', $this->default))
|
||||||
if ($val === null)
|
|
||||||
{
|
{
|
||||||
return new Expression('null');
|
return Query::quoteName($this->default);
|
||||||
|
}
|
||||||
|
elseif (isset($this->column) && preg_match('/_srl$/', $this->column) && !ctype_digit($this->default))
|
||||||
|
{
|
||||||
|
return Query::quoteName($this->default);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the default value is a function shortcut, return an appropriate value.
|
// If the default value is a function shortcut, return an appropriate value.
|
||||||
switch ($val)
|
switch ($this->default)
|
||||||
{
|
{
|
||||||
case 'ipaddress()':
|
case 'ipaddress()':
|
||||||
return new Expression('string', \RX_CLIENT_IP);
|
return "'" . \RX_CLIENT_IP . "'";
|
||||||
case 'unixtime()':
|
case 'unixtime()':
|
||||||
return new Expression('string', time());
|
return time();
|
||||||
case 'curdate()':
|
case 'curdate()':
|
||||||
case 'date()':
|
case 'date()':
|
||||||
return new Expression('string', date('YmdHis'));
|
return "'" . date('YmdHis') . "'";
|
||||||
case 'sequence()':
|
case 'sequence()':
|
||||||
return new Expression('int', getNextSequence());
|
return getNextSequence();
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the default value is a calculation based on the current value, return a query string.
|
// If the default value is a calculation based on the current value, return a query string.
|
||||||
if (isset($this->column) && preg_match('/^(plus|minus|multiply)\(([0-9]+)\)$/', $val, $matches))
|
if (isset($this->column) && preg_match('/^(plus|minus|multiply)\(([0-9]+)\)$/', $this->default, $matches))
|
||||||
{
|
{
|
||||||
|
switch ($matches[1])
|
||||||
|
{
|
||||||
|
case 'plus':
|
||||||
|
return sprintf('%s + %d', Query::quoteName($this->column), $matches[2]);
|
||||||
|
case 'minus':
|
||||||
|
return sprintf('%s - %d', Query::quoteName($this->column), $matches[2]);
|
||||||
|
case 'multiply':
|
||||||
|
return sprintf('%s * %d', Query::quoteName($this->column), $matches[2]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the default value is a column name, return the column name.20
|
// Otherwise, just return the literal value.
|
||||||
if (\Rhymix\Framework\Parsers\DBQueryParser::isValidColumnName($val))
|
return $this->default;
|
||||||
{
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter a value.
|
||||||
|
*
|
||||||
|
* @param mixed $value
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function filterValue($value)
|
||||||
|
{
|
||||||
|
// Apply filters.
|
||||||
|
switch (isset($this->filter) ? $this->filter : '')
|
||||||
|
{
|
||||||
|
case 'email':
|
||||||
|
case 'email_address':
|
||||||
|
if (!preg_match('/^[\w-]+((?:\.|\+|\~)[\w-]+)*@[\w-]+(\.[\w-]+)+$/', $value))
|
||||||
|
{
|
||||||
|
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' must contain a valid e-mail address');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'homepage':
|
||||||
|
case 'url':
|
||||||
|
if (!preg_match('/^(http|https)+(:\/\/)+[0-9a-z_-]+\.[^ ]+$/i', $value))
|
||||||
|
{
|
||||||
|
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' must contain a valid URL');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'userid':
|
||||||
|
case 'user_id':
|
||||||
|
if (!preg_match('/^[a-zA-Z]+([_0-9a-zA-Z]+)*$/', $value))
|
||||||
|
{
|
||||||
|
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' must contain a valid user ID');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'number':
|
||||||
|
case 'numbers':
|
||||||
|
if (!preg_match('/^(-?)[0-9]+(,\-?[0-9]+)*$/', is_array($value) ? implode(',', $value) : $value))
|
||||||
|
{
|
||||||
|
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' must contain a valid number');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'alpha':
|
||||||
|
if (!ctype_alpha($value))
|
||||||
|
{
|
||||||
|
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' must contain only alphabets');
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 'alnum':
|
||||||
|
case 'alpha_number':
|
||||||
|
if (!ctype_alnum($value))
|
||||||
|
{
|
||||||
|
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' must contain only alphanumeric characters');
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise, return the literal value.
|
// Check minimum and maximum lengths.
|
||||||
return new Expression('string', $val);
|
$length = iconv_strlen($value, 'UTF-8');
|
||||||
|
if (isset($this->minlength) && $this->minlength > 0 && $length < $this->minlength)
|
||||||
|
{
|
||||||
|
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' must contain no less than ' . $this->minlength . ' characters');
|
||||||
|
}
|
||||||
|
if (isset($this->maxlength) && $this->maxlength > 0 && $length > $this->maxlength)
|
||||||
|
{
|
||||||
|
throw new \Rhymix\Framework\Exceptions\QueryError('Variable ' . $this->var . ' for column ' . $this->column . ' must contain no more than ' . $this->minlength . ' characters');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,11 +45,11 @@ class DBQueryParser
|
||||||
{
|
{
|
||||||
$query->name = $query->alias;
|
$query->name = $query->alias;
|
||||||
}
|
}
|
||||||
$query->type = strtoupper($xml['action']) ?: null;
|
$query->type = strtoupper($xml['action']) ?: 'SELECT';
|
||||||
|
|
||||||
// Load attributes that only apply to subqueries in the <conditions> block.
|
// Load attributes that only apply to subqueries in the <conditions> block.
|
||||||
$query->operation = trim($xml['operation']) ?: null;
|
$query->operation = trim($xml['operation']) ?: null;
|
||||||
$query->column = trim($xml['column']) ?: null;
|
$query->column = preg_replace('/[^a-z0-9_\.]/i', '', $xml['column']) ?: null;
|
||||||
$query->pipe = strtoupper($xml['pipe']) ?: 'AND';
|
$query->pipe = strtoupper($xml['pipe']) ?: 'AND';
|
||||||
|
|
||||||
// Load tables.
|
// Load tables.
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ class Table
|
||||||
* @param string $engine
|
* @param string $engine
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getCreateQuery(string $prefix = '', string $charset = 'utf8mb4', string $engine = 'innodb')
|
public function getCreateQuery(string $prefix = '', string $charset = 'utf8mb4', string $engine = 'innodb'): string
|
||||||
{
|
{
|
||||||
// Initialize the query.
|
// Initialize the query.
|
||||||
$result = 'CREATE TABLE `' . $prefix . $this->name . '` (';
|
$result = 'CREATE TABLE `' . $prefix . $this->name . '` (';
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue