Prepare to support INSERT/UPDATE/DELETE queries, too

This commit is contained in:
Kijin Sung 2020-06-27 00:04:19 +09:00
parent 6d251dfbe1
commit e3138f7278
5 changed files with 157 additions and 45 deletions

View file

@ -3,9 +3,9 @@
namespace Rhymix\Framework\Parsers\DBQuery;
/**
* Column class.
* ColumnRead class.
*/
class Column
class ColumnRead
{
public $name;
public $alias;

View file

@ -0,0 +1,18 @@
<?php
namespace Rhymix\Framework\Parsers\DBQuery;
/**
* ColumnWrite class.
*/
class ColumnWrite extends VariableBase
{
public $name;
public $operation = 'equal';
public $var;
public $default;
public $not_null;
public $filter;
public $minlength = 0;
public $maxlength = 0;
}

View file

@ -13,6 +13,8 @@ class Query extends VariableBase
public $operation;
public $column;
public $pipe;
public $join_type;
public $join_conditions = array();
public $tables = array();
public $columns = array();
public $conditions = array();
@ -50,6 +52,15 @@ class Query extends VariableBase
case 'SELECT':
$result = $this->_getSelectQueryString($count_only);
break;
case 'INSERT':
$result = $this->_getInsertQueryString();
break;
case 'UPDATE':
$result = $this->_getUpdateQueryString();
break;
case 'DELETE':
$result = $this->_getDeleteQueryString();
break;
default:
$result = '';
}
@ -119,38 +130,15 @@ class Query extends VariableBase
$result .= implode(', ', $columns);
}
// Compose the table list.
$tables = array();
foreach ($this->tables as $table)
// Compose the FROM clause.
if (count($this->tables))
{
if ($table instanceof self)
$tables = $this->_arrangeTables($this->tables);
if ($tables !== '')
{
$subquery = $table->getQueryString($this->_prefix, $this->_args);
foreach ($table->getQueryParams() as $param)
{
$this->_params[] = $param;
}
$tables[] = (count($tables) ? ', ' : '') . sprintf('(%s) AS `%s`', $subquery, $table->alias);
}
else
{
$tabledef = self::quoteName($table->name) . ($table->alias ? (' AS `' . $table->alias . '`') : '');
if ($table->join_type)
{
$join_where = $this->_arrangeConditions($table->join_conditions);
if ($join_where !== '')
{
$tabledef = $tabledef . ' ON ' . $join_where;
}
$tables[] = ' ' . $table->join_type . ' ' . $tabledef;
}
else
{
$tables[] = (count($tables) ? ', ' : '') . $tabledef;
}
$result .= ' FROM ' . $tables;
}
}
$result .= ' FROM ' . implode('', $tables);
// Compose the WHERE clause.
if (count($this->conditions))
@ -245,6 +233,86 @@ class Query extends VariableBase
return $result;
}
/**
* Generate a INSERT query string.
*
* @return string
*/
protected function _getInsertQueryString(): string
{
return '';
}
/**
* Generate a UPDATE query string.
*
* @return string
*/
protected function _getUpdateQueryString(): string
{
return '';
}
/**
* Generate a DELETE query string.
*
* @return string
*/
protected function _getDeleteQueryString(): string
{
return '';
}
/**
* Generate a FROM clause from a list of tables.
*
* @param array $tables
* @return string
*/
protected function _arrangeTables(array $tables): string
{
// Initialize the result.
$result = array();
// Process each table definition.
foreach ($tables as $table)
{
// Subquery
if ($table instanceof self)
{
$tabledef = sprintf('(%s) AS `%s`', $table->getQueryString($this->_prefix, $this->_args), $table->alias);
foreach ($table->getQueryParams() as $param)
{
$this->_params[] = $param;
}
}
// Simple table
else
{
$tabledef = self::quoteName($table->name) . ($table->alias ? (' AS `' . $table->alias . '`') : '');
}
// Add join conditions
if ($table->join_type)
{
$join_where = $this->_arrangeConditions($table->join_conditions);
if ($join_where !== '')
{
$tabledef = $tabledef . ' ON ' . $join_where;
}
$result[] = ' ' . $table->join_type . ' ' . $tabledef;
}
else
{
$result[] = (count($result) ? ', ' : '') . $tabledef;
}
}
// Combine the result and return as a string.
return implode('', $result);
}
/**
* Generate a WHERE clause from a list of conditions.
*

View file

@ -214,6 +214,18 @@ class VariableBase
$conditions = implode(' AND ', $conditions);
$where = count($keywords) === 1 ? $conditions : "($conditions)";
break;
case 'plus':
$where = sprintf('%s = %s + %s', $column, $column, $is_expression ? $value : '?');
if (!$is_expression) $params[] = $value;
break;
case 'minus':
$where = sprintf('%s = %s - %s', $column, $column, $is_expression ? $value : '?');
if (!$is_expression) $params[] = $value;
break;
case 'multiply':
$where = sprintf('%s = %s * %s', $column, $column, $is_expression ? $value : '?');
if (!$is_expression) $params[] = $value;
break;
default:
$where = sprintf('%s = ?', $column);
$params[] = $value;

View file

@ -57,25 +57,26 @@ class DBQueryParser
{
if (trim($tag['query']) === 'true')
{
$subquery = self::_parseQuery($tag);
$query->tables[$subquery->alias] = $subquery;
$table = self::_parseQuery($tag);
$query->tables[$table->alias] = $table;
}
else
{
$table = new DBQuery\Table;
$table->name = trim($tag['name']);
$table->alias = trim($tag['alias']) ?: $table->name;
$table_type = trim($tag['type']);
if (stripos($table_type, 'join') !== false)
{
$table->join_type = strtoupper($table_type);
if ($tag->conditions)
{
$table->join_conditions = self::_parseConditions($tag->conditions);
}
}
$query->tables[$table->alias] = $table;
}
$table_type = trim($tag['type']);
if (stripos($table_type, 'join') !== false)
{
$table->join_type = strtoupper($table_type);
if ($tag->conditions)
{
$table->join_conditions = self::_parseConditions($tag->conditions);
}
}
$query->tables[$table->alias] = $table;
}
// Load columns.
@ -86,9 +87,9 @@ class DBQueryParser
$subquery = self::_parseQuery($tag, trim($tag['id']));
$query->columns[] = $subquery;
}
else
elseif ($query->type === 'SELECT')
{
$column = new DBQuery\Column;
$column = new DBQuery\ColumnRead;
$column->name = trim($tag['name']);
$column->alias = trim($tag['alias']) ?: null;
if ($column->name === '*' || preg_match('/\.\*$/', $column->name))
@ -101,6 +102,19 @@ class DBQueryParser
}
$query->columns[] = $column;
}
else
{
$column = new DBQuery\ColumnWrite;
$column->name = trim($tag['name']);
$column->name = trim($tag['operation']) ?: 'equal';
$column->var = trim($tag['var']) ?: null;
$column->default = trim($tag['default']) ?: null;
$column->not_null = trim($tag['notnull'] ?: $tag['not-null']) !== '' ? true : false;
$column->filter = trim($tag['filter']) ?: null;
$column->minlength = intval(trim($tag['minlength']), 10);
$column->maxlength = intval(trim($tag['maxlength']), 10);
$query->columns[] = $column;
}
}
// Load conditions.
@ -153,7 +167,7 @@ class DBQueryParser
// If a SELECT query has no columns, use * by default.
if ($query->type === 'SELECT' && !count($query->columns))
{
$column = new DBQuery\Column;
$column = new DBQuery\ColumnRead;
$column->name = '*';
$column->is_wildcard = true;
$column->is_expression = true;