diff --git a/common/framework/db.php b/common/framework/db.php index cc02dad91..b3f3cc42d 100644 --- a/common/framework/db.php +++ b/common/framework/db.php @@ -37,8 +37,9 @@ class DB protected $_total_time = 0; /** - * Error codes. + * Current query ID and error information. */ + protected $_query_id = ''; protected $_errno = 0; protected $_errstr = ''; @@ -270,10 +271,12 @@ class DB $last_index = 0; if ($query->requiresPagination()) { + $this->_query_id = $query_id . ' (count)'; $output = $this->_executeCountQuery($query_id, $query, $args, $last_index); if (!$output->toBool()) { $output->page_navigation = new \PageHandler(0, 0, 0); + $this->_query_id = ''; $this->_total_time += (microtime(true) - $start_time); return $output; } @@ -284,6 +287,7 @@ class DB $output->add('_query', $query_string); $output->add('_elapsed_time', '0.00000'); $output->page_navigation = new \PageHandler(0, 0, 0); + $this->_query_id = ''; $this->_total_time += (microtime(true) - $start_time); return $output; } @@ -296,6 +300,7 @@ class DB // Prepare and execute the main query. try { + $this->_query_id = $query_id; if (count($query_params)) { $this->_last_stmt = $this->_handle->prepare($query_string); @@ -312,6 +317,7 @@ class DB $output->add('_query', $query_string); $output->add('_elapsed_time', '0.00000'); $output->page_navigation = new \PageHandler(0, 0, 0); + $this->_query_id = ''; $this->_total_time += (microtime(true) - $start_time); return $output; } @@ -322,14 +328,17 @@ class DB } catch (Exceptions\DBError $e) { + $output = $this->setError(-1, $e->getMessage()); $output->add('_query', $query_string); $output->add('_elapsed_time', '0.00000'); $output->page_navigation = new \PageHandler(0, 0, 0); + $this->_query_id = ''; $this->_total_time += (microtime(true) - $start_time); return $output; } // Fill query information and result data in the output object. + $this->_query_id = ''; $this->_total_time += ($elapsed_time = microtime(true) - $start_time); $output->add('_query', $query_string); $output->add('_elapsed_time', sprintf('%0.5f', $elapsed_time)); @@ -476,7 +485,7 @@ class DB { $this->setError(-1, $e->getMessage()); } - Debug::addQuery($this->getQueryLog('START TRANSACTION', '', 0)); + Debug::addQuery($this->getQueryLog('START TRANSACTION', 0)); } $this->_transaction_level++; return $this->_transaction_level; @@ -500,7 +509,7 @@ class DB { $this->setError(-1, $e->getMessage()); } - Debug::addQuery($this->getQueryLog('ROLLBACK', '', 0)); + Debug::addQuery($this->getQueryLog('ROLLBACK', 0)); } $this->_transaction_level--; return $this->_transaction_level; @@ -524,7 +533,7 @@ class DB { $this->setError(-1, $e->getMessage()); } - Debug::addQuery($this->getQueryLog('COMMIT', '', 0)); + Debug::addQuery($this->getQueryLog('COMMIT', 0)); } $this->_transaction_level--; return $this->_transaction_level; @@ -986,11 +995,10 @@ class DB * Generate a query log entry. * * @param string $query - * @param string $query_id * @param float $elapsed_time * @return array */ - public function getQueryLog(string $query, string $query_id, float $elapsed_time): array + public function getQueryLog(string $query, float $elapsed_time): array { // Cache the debug status to improve performance. static $debug_enabled = null; @@ -1007,7 +1015,7 @@ class DB // Compose the basic structure of the log entry. $result = array( 'query' => $query, - 'query_id' => $query_id, + 'query_id' => $this->_query_id, 'connection' => $this->_type, 'elapsed_time' => sprintf('%0.5f', $elapsed_time), 'result' => 'success', @@ -1029,6 +1037,7 @@ class DB { $result['called_file'] = $backtrace[$no]['file']; $result['called_line'] = $backtrace[$no]['line']; + $no++; $result['called_method'] = $backtrace[$no]['class'] . $backtrace[$no]['type'] . $backtrace[$no]['function']; $result['backtrace'] = array_slice($backtrace, $no, 1); break; diff --git a/common/framework/debug.php b/common/framework/debug.php index 37b2646a2..e31f7a218 100644 --- a/common/framework/debug.php +++ b/common/framework/debug.php @@ -355,7 +355,7 @@ class Debug 'query_id' => $query['query_id'], 'query_connection' => $query['connection'], 'query_string' => $query['query'], - 'query_time' => $query['elapsed_time'], + 'query_time' => floatval($query['elapsed_time']), 'file' => $query['called_file'], 'line' => $query['called_line'], 'method' => $query['called_method'], diff --git a/common/framework/helpers/dbhelper.php b/common/framework/helpers/dbhelper.php index aea3e6edd..72c26702f 100644 --- a/common/framework/helpers/dbhelper.php +++ b/common/framework/helpers/dbhelper.php @@ -33,6 +33,9 @@ class DBHelper extends \PDO */ public function prepare($statement, $driver_options = null) { + $start_time = microtime(true); + $db_class = DB::getInstance($this->_type); + try { if ($driver_options) @@ -48,6 +51,10 @@ class DBHelper extends \PDO } catch (\PDOException $e) { + $elapsed_time = microtime(true) - $start_time; + $db_class->addElapsedTime($elapsed_time); + $db_class->setError(-1, $e->getMessage()); + Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time)); throw new DBError($e->getMessage(), 0, $e); } @@ -81,7 +88,7 @@ class DBHelper extends \PDO $elapsed_time = microtime(true) - $start_time; $db_class->addElapsedTime($elapsed_time); - Debug::addQuery($db_class->getQueryLog($statement, '', $elapsed_time)); + Debug::addQuery($db_class->getQueryLog($statement, $elapsed_time)); return $stmt; } @@ -109,7 +116,7 @@ class DBHelper extends \PDO $elapsed_time = microtime(true) - $start_time; $db_class->addElapsedTime($elapsed_time); - Debug::addQuery($db_class->getQueryLog($query, '', $elapsed_time)); + Debug::addQuery($db_class->getQueryLog($query, $elapsed_time)); return $result; } diff --git a/common/framework/helpers/dbstmthelper.php b/common/framework/helpers/dbstmthelper.php index 3f6a8e79d..7496e8cb2 100644 --- a/common/framework/helpers/dbstmthelper.php +++ b/common/framework/helpers/dbstmthelper.php @@ -42,7 +42,7 @@ class DBStmtHelper extends \PDOStatement $elapsed_time = microtime(true) - $start_time; $db_class->addElapsedTime($elapsed_time); - Debug::addQuery($db_class->getQueryLog($this->queryString, '', $elapsed_time)); + Debug::addQuery($db_class->getQueryLog($this->queryString, $elapsed_time)); } catch (\PDOException $e) { @@ -50,7 +50,7 @@ class DBStmtHelper extends \PDOStatement $elapsed_time = microtime(true) - $start_time; $db_class->addElapsedTime($elapsed_time); - Debug::addQuery($db_class->getQueryLog($this->queryString, '', $elapsed_time)); + Debug::addQuery($db_class->getQueryLog($this->queryString, $elapsed_time)); throw new DBError($e->getMessage(), 0, $e); } diff --git a/common/framework/parsers/dbquery/query.php b/common/framework/parsers/dbquery/query.php index 8d7a17d09..9f7e53135 100644 --- a/common/framework/parsers/dbquery/query.php +++ b/common/framework/parsers/dbquery/query.php @@ -130,7 +130,7 @@ class Query extends VariableBase elseif ($this->_column_list) { $result .= implode(', ', array_map(function($str) { - return '`' . $str . '`'; + return self::quoteName($str); }, $this->_column_list)); } else @@ -233,7 +233,7 @@ class Query extends VariableBase // Compose the INTO clause. if (count($this->tables)) { - $tables = $this->_arrangeTables($this->tables); + $tables = $this->_arrangeTables($this->tables, false); if ($tables !== '') { $result .= ' INTO ' . $tables; @@ -280,7 +280,7 @@ class Query extends VariableBase // Compose the INTO clause. if (count($this->tables)) { - $tables = $this->_arrangeTables($this->tables); + $tables = $this->_arrangeTables($this->tables, false); if ($tables !== '') { $result .= $tables; @@ -326,7 +326,7 @@ class Query extends VariableBase // Compose the FROM clause. if (count($this->tables)) { - $tables = $this->_arrangeTables($this->tables); + $tables = $this->_arrangeTables($this->tables, false); if ($tables !== '') { $result .= ' FROM ' . $tables; @@ -363,9 +363,10 @@ class Query extends VariableBase * Generate a FROM clause from a list of tables. * * @param array $tables + * @param bool $use_aliases * @return string */ - protected function _arrangeTables(array $tables): string + protected function _arrangeTables(array $tables, bool $use_aliases = true): string { // Initialize the result. $result = array(); @@ -376,7 +377,11 @@ class Query extends VariableBase // Subquery if ($table instanceof self) { - $tabledef = sprintf('(%s) AS `%s`', $table->getQueryString($this->_prefix, $this->_args), $table->alias); + $tabledef = '(' . $table->getQueryString($this->_prefix, $this->_args) . ')'; + if ($table->alias) + { + $tabledef .= ' AS `' . $table->alias . '`'; + } foreach ($table->getQueryParams() as $param) { $this->_params[] = $param; @@ -386,7 +391,11 @@ class Query extends VariableBase // Regular table else { - $tabledef = self::quoteName($this->_prefix . $table->name) . ($table->alias ? (' AS `' . $table->alias . '`') : ''); + $tabledef = self::quoteName($this->_prefix . $table->name); + if ($use_aliases && $table->alias && $table->alias !== ($this->_prefix . $table->name)) + { + $tabledef .= ' AS `' . $table->alias . '`'; + } } // Add join conditions @@ -485,7 +494,11 @@ class Query extends VariableBase } // Get the ordering (ASC or DESC). - if (isset($this->_args[$orderby->order_var])) + if (preg_match('/^(ASC|DESC)$/i', $orderby->order_var, $matches)) + { + $column_order = strtoupper($matches[1]); + } + elseif (isset($this->_args[$orderby->order_var])) { $column_order = preg_replace('/[^A-Z]/', '', strtoupper($this->_args[$orderby->order_var])); } diff --git a/common/framework/parsers/dbquery/variablebase.php b/common/framework/parsers/dbquery/variablebase.php index a80f0dd56..b8e534b42 100644 --- a/common/framework/parsers/dbquery/variablebase.php +++ b/common/framework/parsers/dbquery/variablebase.php @@ -282,7 +282,7 @@ class VariableBase { return [true, Query::quoteName($this->default)]; } - elseif (isset($this->column) && preg_match('/_srl$/', $this->column) && !ctype_digit($this->default)) + elseif (isset($this->column) && preg_match('/_srl$/', $this->column) && !is_numeric($this->default)) { return [true, Query::quoteName($this->default)]; } diff --git a/common/framework/parsers/dbqueryparser.php b/common/framework/parsers/dbqueryparser.php index e30332f5b..2c488c9a2 100644 --- a/common/framework/parsers/dbqueryparser.php +++ b/common/framework/parsers/dbqueryparser.php @@ -105,15 +105,16 @@ class DBQueryParser extends BaseParser } else { + $attribs = self::_getAttributes($tag); $column = new DBQuery\ColumnWrite; - $column->name = trim($tag['name']); - $column->operation = trim($tag['operation']) ?: 'equal'; - $column->var = trim($tag['var']) ?: null; - $column->default = trim($tag['default']) ?: null; - $column->not_null = self::_getAttributes($tag)['notnull'] ? true : false; - $column->filter = trim($tag['filter']) ?: null; - $column->minlength = intval(trim($tag['minlength']), 10); - $column->maxlength = intval(trim($tag['maxlength']), 10); + $column->name = $attribs['name']; + $column->operation = $attribs['operation'] ?: 'equal'; + $column->var = $attribs['var'] ?? null; + $column->default = $attribs['default'] ?? null; + $column->not_null = $attribs['notnull'] ? true : false; + $column->filter = $attribs['filter'] ?? null; + $column->minlength = intval($attribs['minlength'], 10); + $column->maxlength = intval($attribs['maxlength'], 10); $query->columns[] = $column; } } @@ -215,8 +216,15 @@ class DBQueryParser extends BaseParser $cond = new DBQuery\Condition; $cond->operation = $attribs['operation']; $cond->column = $attribs['column']; - $cond->var = $attribs['var'] ?? null; - $cond->default = $attribs['default'] ?? null; + if (isset($attribs['var']) && !isset($attribs['default']) && preg_match('/^\w+\.\w+$/', $attribs['var'])) + { + $cond->default = $attribs['var']; + } + else + { + $cond->var = $attribs['var'] ?? null; + $cond->default = $attribs['default'] ?? null; + } $cond->not_null = $attribs['notnull'] ? true : false; $cond->filter = $attribs['filter'] ?? null; $cond->minlength = intval($attribs['minlength'], 10);