组装sql用于DEBUG

@return string
6296
private function buildDebugSql()
    {
        $bindParams = $this->bindParams;
        foreach ($bindParams as $key => $val) {
            $bindParams[$key] = str_replace('\\\\', '\\', addslashes($val));
        }
        return vsprintf(str_replace('%s', "'%s'", $this->currentSql), $bindParams);
    }
608623
private static function debugEnd()
    {
        // SWATDB_DEBUG is legacy, use SwatDB::setDebug() instead
        if (defined('SWATDB_DEBUG') || self::$debug) {
            self::$debug_wrapper_depth--;

            if (self::$debug_wrapper_depth === 0) {
                $count = 0;
                $depth = 0;

                foreach (self::$debug_info as $info) {
                    if ($info['depth'] < $depth) {
                        echo str_repeat(
                            '</blockquote>',
                            $depth - $info['depth']
                        );
                    } elseif ($info['depth'] > $depth) {
                        echo '<blockquote class="swat-db-debug">';
                    } elseif ($info['depth'] === 0) {
                        echo '<hr />';
                    }

                    echo "\n" . $info['message'] . "\n";

                    $locale = SwatI18NLocale::get();
                    printf(
                        "<p>Query #%s</p>\n",
                        $locale->formatNumber($info['count'])
                    );

                    if (count(self::$debug_info) > $count + 1) {
                        $time = self::$debug_info[$count + 1]['time'];
                    } else {
                        $time = microtime(true) * 1000;
                    }

                    $ms = $time - $info['time'];

                    printf(
                        "<p><strong>%s ms</strong></p>\n",
                        $locale->formatNumber($ms, 3)
                    );

                    if ($info['depth'] === 0 && count(self::$debug_info) > 1) {
                        $ms =
                            microtime(true) * 1000 -
                            self::$debug_info[0]['time'];

                        echo '<p><strong>';

                        printf(
                            Swat::_(
                                'Total time: %s ms (includes ' .
                                    'queries within the wrapper)'
                            ),
                            $locale->formatNumber($ms, 3)
                        );

                        echo '</strong></p>';
                    }

                    $count++;
                    $depth = $info['depth'];
                }

                if ($depth > 0) {
                    echo str_repeat('</blockquote>', $depth);
                }

                // reset debug info for the next query
                self::$debug_info = array();
            }
        }
    }
569364
public function get_sql() : string {
		if ( empty( $this->columns_to_select ) ) {
			// this should be the default behavior
			$this->columns_to_select = [ '*' ];
		}

		$from = ' FROM ' . implode( ', ', $this->from ) . ' ';

		if ( ! empty( $this->joins ) ) {
			$from .= $this->joins;
		}

		$from  .= 'WHERE ' . $this->where_clause;
		$select = 'SELECT ' . implode( ', ', $this->columns_to_select ) . $from;

		if ( ! empty( $this->group_by ) ) {
			$select .= 'GROUP BY ' . implode( ', ', $this->group_by ) . ' ';
		}

		if ( $this->order_by !== '' ) {
			$select .= 'ORDER BY ' . $this->order_by . ' ';
		}

		$select .= 'LIMIT ' . $this->limit;

		if ( $this->offset !== '' ) {
			$select .= ' OFFSET ' . $this->offset;
		}

		return $select;
	}
1177591
public function sql()
    {
        if ($this->active()) {
            switch ($this->mode()) {
                case self::MODE_RANDOM:
                    return $this->byRandom();

                case self::MODE_CUSTOM:
                    return $this->byCondition();

                case self::MODE_VALUES:
                    return $this->byValues();
            }

            if ($this->hasCondition()) {
                return $this->byCondition();
            }

            if ($this->hasValues()) {
                return $this->byValues();
            }

            if ($this->hasProperty()) {
                return $this->byProperty();
            }
        }

        return '';
    }
1016148
public function debug() {
        echo "filePath    = " . $this->filePath . PHP_EOL;
        echo "startMarker = " . $this->startMarker . PHP_EOL;
        echo "endMarker   = " . $this->endMarker . PHP_EOL;
        echo "startIndex  = " . $this->startIndex . PHP_EOL;
        echo "endIndex    = " . $this->endIndex . PHP_EOL;
        echo "numLines    = " . $this->numLines . PHP_EOL;
        echo "Start       = " . print_r($this->beforeLines, true);
        echo "Auto      = " . print_r($this->autoLines, true);
        echo "End         = " . print_r($this->afterLines, true);
        return $this;
    }
609377
protected function print_debug($sql, array $params=null, $obj=null) {
        if (!$this->get_debug()) {
            return;
        }
        if (CLI_SCRIPT) {
            $separator = "--------------------------------\n";
            echo $separator;
            echo "{$sql}\n";
            if (!is_null($params)) {
                echo "[" . var_export($params, true) . "]\n";
            }
            echo $separator;
        } else if (AJAX_SCRIPT) {
            $separator = "--------------------------------";
            error_log($separator);
            error_log($sql);
            if (!is_null($params)) {
                error_log("[" . var_export($params, true) . "]");
            }
            error_log($separator);
        } else {
            $separator = "<hr />\n";
            echo $separator;
            echo s($sql) . "\n";
            if (!is_null($params)) {
                echo "[" . s(var_export($params, true)) . "]\n";
            }
            echo $separator;
        }
    }
327654
protected function getSelectString(): string
    {
        $statement = '';
        $fieldSelect    = $this->builder->getSelect();
        $aggregate = $this->builder->getAggregate();
        if (empty($fieldSelect) && empty($aggregate)) {
            return $statement;
        }

        $select = $this->getAggregateStatement($fieldSelect, $aggregate);

        // 字段组拼
        foreach ($select as $column => $alias) {
            // Filter db keyword
            if (array_key_exists($column, $fieldSelect) && trim($column) != '*' && strpos($column, '.') === false) {
                // 判断是否为函数调用
                if (strpos($column, '(') || strpos($column, ')')) {
                    $column = sprintf('%s', $column);
                } else {
                    $column = sprintf('`%s`', $column);
                }
            }

            $statement .= $column;
            if ($alias !== null) {
                $statement .= sprintf(' AS `%s`', $alias);
            }
            $statement .= ', ';
        }

        //select组拼
        $statement = substr($statement, 0, -2);
        if (!empty($statement)) {
            $statement = 'SELECT ' . $statement;
        }

        return $statement;
    }
743343
private function getSql() {
        $sql = str_replace(['%TABLE%',
                            '%DISTINCT%',
                            '%FIELD%',
                            '%JOIN%',
                            '%WHERE%',
                            '%GROUP%',
                            '%HAVING%',
                            '%ORDER%',
                            '%LIMIT%',
                            '%LOCK%',
                            '%COMMENT%',
                            '%FORCE%'], [$this->table,
                                         $this->distinct,
                                         $this->parseField(),
                                         $this->parseJoin(),
                                         $this->whereSql(),
                                         $this->group,
                                         $this->having,
                                         $this->order,
                                         $this->limit,
                                         $this->lock,
                                         $this->comment,
                                         $this->force], $this->selectSql);
        return $sql;
    }
903109
private function createExecute(): string
    {
        // 已经传递了SQL,Prepare语句与SQL相同
        $this->prepare = $this->sql;

        // 查找SQL中涉及的表
        $this->tables = $this->db->getNameFromExecute($this->sql);

        return $this->sql;
    }
48014
private function getSQL()
    {
        $sql = $this->getTypeSQL()
                . $this->getWhereSQL()
                . $this->getOrderSQL()
                . $this->getLimitSQL()
                . $this->getOffsetSQL();
        return $sql;
    }
107533
public function nextQuery()
    {
        $sql = null;

        while (($line = $this->sqlReader->readLine()) !== null) {
            $delimiter = $this->parent->getDelimiter();
            $project = $this->parent->getOwningTarget()->getProject();
            $line = $project->replaceProperties(trim($line));

            if (($line != $delimiter) && (StringHelper::startsWith("//", $line)
                    || StringHelper::startsWith("--", $line)
                    || StringHelper::startsWith("#", $line))
            ) {
                continue;
            }

            $sql .= " " . $line . "\n";

            /**
             * fix issue with PDO and wrong formated multistatements
             *
             * @issue 1108
             */
            if (StringHelper::endsWith($delimiter, $line)) {
                break;
            }
        }

        return $sql;
    }
1276466
protected function buildSql()
    {
        $query = $this->getQuery();
        if (
            !isset($query['table']) || empty($query['table'])
            || !isset($query['columns']) || empty($query['columns'])
        ) {
            throw new Exception(str_cover('"{type}"查询参数不完整', [
                '{type}' => 'insert'
            ]), 101300301);
        }
        $KS = $VS = [];
        foreach ($query['columns'] as $k => $v) {
            if ($v instanceof Expression) {
                $KS[] = $this->quoteColumnName($k);
                $VS[] = $v->expression;
                continue;
            }
            $KS[] = $this->quoteColumnName($k);
            $VS[] = $bk = $this->getBindKey();
            $this->addParam($bk, $v);
        }
        $sql = 'INSERT INTO '
            . $this->quoteTableName($query['table'])
            . ' (' . implode(',', $KS) . ') VALUES (' . implode(',', $VS) . ')';
        return $sql;
    }
615335
public function dump() : string
    {
        $html  = '<p><i>You have made ' . self::$numQueries . ' database queries.</i></p><pre>';
        
        foreach (self::$queries as $key => $val) {
            $params = empty(self::$params[$key])
                ? null
                : htmlentities(print_r(self::$params[$key], 1), null, 'UTF-8') . '<br/><br/>';
            $html .= htmlentities($val, null, 'UTF-8') . '<br/><br/>' . $params;
        }
        
        return $html . '</pre>';
    }
939193
public function count() {
        $sql    = $this->getSQL();
        $values = $this->values;
        if ($sql) {
            try {
                $statement = $this->dialect->prepare($sql);
                foreach ($values as $value) {
                    list ($name, $val, $type) = $value;
                    if (!$statement->bindValue($name, $val, $type)) {
                        $this->errorSQL    = $sql;
                        $this->errorValues = $values->__toString();
                        $this->error       = 'can not bind the value ' . $val . '[' . $type . '] to the argument:' . $name;

                        return false;
                    }
                }
                $rst = $statement->execute();
                $cnt = false;
                if ($rst) {
                    $cnt = $statement->rowCount();
                } else {
                    $this->dumpSQL($statement);
                }
                if ($statement) {
                    $statement->closeCursor();
                    $statement = null;
                }
                QueryBuilder::addSqlCount();

                return $cnt;
            } catch (\PDOException $e) {
                $this->exception   = $e;
                $this->error       = $e->getMessage();
                $this->errorSQL    = $sql;
                $this->errorValues = $values->__toString();

                return false;
            }
        } else {
            $this->error       = 'Can not generate the delete SQL';
            $this->errorSQL    = '';
            $this->errorValues = $values->__toString();
        }

        return false;
    }
857448
public function debugBacktrace()
    {
        $skipFunc[] = 'handle_exception';
        $skipFunc[] = 'handle_error';
        $skipFunc[] = 'ErrorFunc::systemError';
        $skipFunc[] = 'ErrorFunc::debugBacktrace';
        $debugBacktrace = debug_backtrace();
        ksort($debugBacktrace);
        $phpMsg = [];
        foreach ($debugBacktrace as $error) {
            if (!isset($error['file'])) {
                // 利用反射API来获取方法/函数所在的文件和行数
                try {
                    if (isset($error['class'])) {
                        $reflection = new \ReflectionMethod($error['class'], $error['function']);
                    } else {
                        $reflection = new \ReflectionFunction($error['function']);
                    }
                    $error['file'] = $reflection->getFileName();
                    $error['line'] = $reflection->getStartLine();
                } catch (\ReflectionException $e) {
                    //$e->getCode();
                    continue;
                }
            }
            $func = isset($error['class']) ? $error['class'] : '';
            $func .= isset($error['type']) ? $error['type'] : '';
            $func .= isset($error['function']) ? $error['function'] : '';

            if (in_array($func, $skipFunc)) {
                continue;
            }
            $error['line'] = sprintf('%04d', $error['line']);
            $phpMsg[] = ['file' => $error['file'], 'line' => $error['line'], 'function' => $func];
        }
        return $phpMsg;
    }
1104051
public function getQuery(): string
    {
        $sql = $this->getSql();

        $sql = str_replace(['%', '?'], ['%%', '"%s"'], $sql);

        // replace mask by data
        return vsprintf($sql, $this->getParams());
    }
277495
public function getPdo()
    {
        // 分析查询表达式
        $options = $this->parseExpress();
        // 生成查询SQL
        $sql = $this->builder->select($options);
        // 获取参数绑定
        $bind = $this->getBind();
        if ($options['fetch_sql']) {
            // 获取实际执行的SQL语句
            return $this->connection->getRealSql($sql, $bind);
        }
        // 执行查询操作
        return $this->query($sql, $bind, $options['master'], true);
    }