数据库调试 记录当前SQL及分析性能
@access protected
@param boolean $start 调试开始标记 true 开始 false 结束
@param string  $sql 执行的SQL语句 留空自动获取
@return void
422297
protected function debug($start, $sql = '')
    {
        if (!empty($this->config['debug'])) {
            // 开启数据库调试模式
            if ($start) {
                $this->queryStartTime = microtime(true);
            } else {
                $runtime = number_format((microtime(true) - $this->queryStartTime), 6);

                $sql = $sql ?: $this->queryStr;

                // SQL监听
                $this->triggerSql($sql, $runtime, $this->options);
            }
        }
    }
23144
protected function query_start($sql, array $params = null, $type, $extrainfo = null) {
        parent::query_start($sql, $params, $type, $extrainfo);
    }
654307
public function query($sql)
    {
        if (true == Config::get('sql_log')) {
            wlog('SQL-Log', $sql);
        }

        // Prepare one MySQL client connect
        $isFromPool = $this->prepareDB();

        try {
            $rs = $this->db->query($sql);
        } catch (\Exception $e) {
            // echo 'error:'. $e->getCode() . $e->getMessage();
            // 如果发生了mysqli::query(): MySQL server has gone away，直接抛出异常，
            // 需要捕获后，重新reconnect
        }

        if ( !empty($rs) ) {
            $GLOBALS['__$DB_QUERY_COUNT']++;
        } else if($this->db->errno == 2006 || $this->db->errno == 2013) {
            // Catch database pool long running
            // 2013 Lost connection to MySQL server during query
            // 2006 MySQL server has gone away
            try {
                $this->reconnect();
            } catch (\Exception $e) {
                DBPool::init($this->db_config)->cap--;
                DBPool::init($this->db_config)->activeCount--;
                \throw_error('DB_ERROR: ' . $this->db->error . "\nRAW_SQL: " . $sql, $this->db->errno);
            }

            $GLOBALS['__$DB_QUERY_COUNT']++;
            $rs = $this->db->query($sql);
        } else {
            DBPool::init($this->db_config)->cap--;
            DBPool::init($this->db_config)->activeCount--;
            \throw_error('DB_ERROR: ' . $this->db->error . "\nRAW_SQL: " . $sql, $this->db->errno);
        }

        // Put db connction to pool
        // If it is new client, queue in, else put pool client back
        if ($isFromPool) {
            DBPool::init($this->db_config)->back($this->db);
        } else {
            DBPool::init($this->db_config)->in($this->db);
        }

        // echo 'db_config='. $this->db_config;
        // echo 'activeCount='. (DBPool::init($this->db_config)->activeCount);
        // echo ',cap='. (DBPool::init($this->db_config)->cap);
        // var_dump(DBPool::init($this->db_config)->queue);

        return $rs;
    }
601765
public function startQuery($sql, array $params = null, array $types = null)
    {
        // this is a safeguard for when no logger might be available...
        if ($this->logger !== null) {
            $this->logger->log($sql, LOG_DEBUG, ['params' => $params, 'types' => $types]);
        }
    }
1123932
public function sqlBefore(string $name, string $sql): void
    {
        //查看是否存在SQL日志配置
        $file = configDefault(false, 'log', 'sql', $name);
        $file ? $this->log($file, $name . "\t" . intval($this->logRequestId) . "\t" . '<SQL>' . $sql . '</SQL>') : null;
    }
216856
protected function query ( $sql )
	{
		list($sql, $args) = $this->sql_args(func_get_args());
		any_db_query($sql, $args);
	}
945431
public function execute(string $sql, $bind = [])
    {
        $sql = trim($sql);

        // 执行前置钩子
        $ret = $this->before('Execute', $sql, $bind);

        //如果被前置钩子阻止
        if ($ret === self::INTERRUPT) {
            return null;
        }

        //前置钩子修正参数
        list($sql, $bind) = $ret;

        //准备语句
        $this->statement->execute($sql, $bind);

        //要记录日志的数据
        $data = ['sql' => $sql, 'bind' => $bind];

        // 如果允许多表访问,直接通过
        if ($this->enableMulti()) {
            // 执行具体删除操作
            $result = self::log('execute', $data, '*', '', false, false);

            // 获取执行结果,执行后置钩子
            return $this->after('Execute', $result);
        }

        // 识别语句中的表名
        $tables = $this->statement->getTable();

        // 未能识别出表名,直接通过,这有可能是Desc/commit/rollback/begin
        if (!$tables or count($tables) == 0) {
            // 执行具体删除操作
            $result = self::log('execute', $data, '*', '', false, false);
            // 获取执行结果,执行后置钩子
            return $this->after('Execute', $result);
        }

        // 如果识别出多个表名
        if (count($tables) > 1) {
            trigger_error('执行语句中不允许同时指定多个表名', E_USER_ERROR);
        }

        // 取表名
        $table = $tables[0];

        // 如果语句中的表名与初始化时不同,则错误
        if ($table != $this->tableName) {
            trigger_error('表名不匹配:' . $this->tableName . ':' . $sql, E_USER_ERROR);
        }

        // 执行具体删除操作
        $result = self::log('execute', $data, '*', '', false, false);

        // 获取执行结果,执行后置钩子
        return $this->after('Execute', $result);
    }
355867
public function mid($column, int $start = 1, int $length = 0): self
    {
        return $this->addFunction('sqlFunction', 'MID', $column, ['start' => $start, 'length' => $length]);
    }
1340374
public function startQuery($sql, array $params = null, array $types = null)
    {
        if (class_exists('Tideways\Profiler')) {
            $this->span = \Tideways\Profiler::createSpan('sql');
            $this->span->startTimer();
            $this->span->annotate(['title' => $sql]);

            return;
        }

        if (class_exists('QafooLabs\Profiler') and method_exists('QafooLabs\Profiler', 'startCustomTimer')) {
            $this->id = \QafooLabs\Profiler::startCustomTimer('sql', $sql);
        }
    }
8118
public function query($sql)
    {
        if (true == Config::get('sql_log')) {
            wlog('SQL-Log', $sql);
        }

        $_key = strtolower(substr($sql, 0, 6));
        if ($_key == 'select') {
            $qt = 'query';
        } else {
            $qt = 'exec';
        }

        if (true == ($rs = $this->db->$qt($sql))) {
            $GLOBALS['__$DB_QUERY_COUNT']++;
            return $rs;
        } else {
            \show_error('DB_ERROR: ' . $this->db->lastErrorMsg() . "\nRAW_SQL: " . $sql);
        }
        //return false;
    }
664819
protected function execSQL($sql)
    {
        // Check and ignore empty statements
        if (trim($sql) == "") {
            return;
        }

        try {
            $this->totalSql++;

            if (!$this->autocommit) {
                $this->conn->beginTransaction();
            }

            $stmt = $this->conn->prepare($sql);
            $this->log(sprintf('    Executing statement "%s"', $sql), Project::MSG_VERBOSE);
            $stmt->execute();
            $this->log(sprintf('    %d rows affected', $stmt->rowCount()), Project::MSG_VERBOSE);

            if (!$this->autocommit) {
                $this->conn->commit();
            }

            $this->goodSql++;
        } catch (PDOException $e) {
            $this->log("Failed to execute: " . $sql, Project::MSG_ERR);
            if ($this->onError != "continue") {
                throw $e;
            }
            $this->log($e->getMessage(), Project::MSG_ERR);
        }
    }
678124
public function load($sql)
    {
        $query = '';
        $delimiter = ';';
        $delimiterLength = 1;

        $dollarsOpen = false;
        foreach ($sql as $sqlLine) {
            if (preg_match('/DELIMITER ([\;\$\|\\\\]+)/i', $sqlLine, $match)) {
                $delimiter = $match[1];
                $delimiterLength = strlen($delimiter);
                continue;
            }

            $parsed = trim($query) == '' && $this->sqlLine($sqlLine);
            if ($parsed) {
                continue;
            }

            // Ignore $$ inside SQL standard string syntax such as in INSERT statements.
            if (!preg_match('/\'.*\$\$.*\'/', $sqlLine)) {
                $pos = strpos($sqlLine, '$$');
                if (($pos !== false) && ($pos >= 0)) {
                    $dollarsOpen = !$dollarsOpen;
                }
            }

            if (preg_match('/SET search_path = .*/i', $sqlLine, $match)) {
                $this->searchPath = $match[0];
            }

            $query .= "\n" . rtrim($sqlLine);

            if (!$dollarsOpen && substr($query, -1 * $delimiterLength, $delimiterLength) == $delimiter) {
                $this->sqlQuery(substr($query, 0, -1 * $delimiterLength));
                $query = '';
            }
        }

        if ($query !== '') {
            $this->sqlQuery($query);
        }
    }
1131911
public static function deleteBySql($sql)
    {
        if (is_array($sql)) {
            $bind = $sql;
            unset($bind[0]);
            $sql = $sql[0];
        } else {
            $bind = [];
        }

        $model = new static;

        $table = $model->getSource($bind);
        return $model->getConnection($bind)->deleteBySql('DELETE' . " FROM [$table] WHERE " . $sql, $bind);
    }
111148
public function start()
    {
        $metaData = array("columns"=>array());

        if ($this->countTotal) {
            $totalQuery = $this->bindParams($this->totalQuery, $this->sqlParams);
            $totalResult = pg_query($this->connection, $totalQuery);
            if (!$totalResult) {
                echo pg_last_error($this->connection);
                exit;
            }
            $row = pg_fetch_array($totalResult);
            $total = $row[0];
            $metaData['totalRecords'] = $total;
        }

        if ($this->countFilter) {
            $filterQuery = $this->bindParams($this->filterQuery, $this->sqlParams);
            $filterResult = pg_query($this->connection, $filterQuery);
            if (!$filterResult) {
                echo pg_last_error($this->connection);
                exit;
            }
            $row = pg_fetch_array($filterResult);
            $total = $row[0];
            $metaData['filterRecords'] = $total;
        }

        $query = $this->bindParams($this->query, $this->sqlParams);
        $result = pg_query($this->connection, $query);
        if (! $result) {
            echo pg_last_error($this->connection);
            exit;
        }

        $num_fields = pg_num_fields($result);

        for ($i=0; $i<$num_fields; $i++) {
            $name = pg_field_name($result, $i);
            $type = pg_field_type($result, $i);
            $type = $this->mapFieldTypeToBindType($type);
            $metaData["columns"][$name] = array(
                "type"=>$type,
            );
            switch($type)
            {
            case "datetime":
                $metaData["columns"][$name]["format"] = "Y-m-d H:i:s";
                break;
            case "date":
                $metaData["columns"][$name]["format"] = "Y-m-d";
                break;
            }
        }
                
        $this->sendMeta($metaData, $this);
    
        $this->startInput(null);
        
        while ($row = pg_fetch_assoc($result)) {
            $this->next($row, $this);
        }

        $this->endInput(null);
    }
689555
function exec($sql)
    {
        if ($this->trace_count){
            Trace::groups('DB')->group('count')->set(Trace::groups('DB')->group('count')->get()+1);
        }
        if ($this->trace_sql){
            Benchmark::start('sql');
            $sql = $this->addPrefixes($sql);
            $result = parent::exec($sql);
            $bm = Benchmark::stop('sql', true);
            if ($bm['time'] >= $this->slow_query){
                Trace::groups('DB')->group('query')->group()->set(array(
                    'sql' => $sql,
                    'benchmark' => $bm
                    )
                );
                Trace::groups('DB')->group('sql_time')->set(Trace::groups('DB')->group('sql_time')->get()+$bm['time']);
                Trace::groups('DB')->group('slow_count')->set(Trace::groups('DB')->group('slow_count')->get()+1);
            }
            return $result;
        }
        return parent::exec($this->addPrefixes($sql));
    }
698912
public function writeSQL($sql)
    {
        $this->sql = $sql;
        $this->PDO = $this->PDO->prepare($this->sql);
    }
1112690
public function query($sql = null)
    {
        if (!$sql) {
            $sqlWhere = '';
            if (!empty($this->getWhere())) {
                $sqlWhere = $this->getWhere();
            }

            $sqlLimit = '';
            if (!empty($this->getLimit())) {
                $sqlLimit = $this->getLimit();
            }

            $sqlOrder = '';
            $orderBy = $this->getOrderBy();
            if (!empty($orderBy)) {
                $sqlOrder = $orderBy;
            }

            $sqlSelect = "SELECT " . $this->getSelect();
            $sqlFrom = " FROM " . $this->getTable();

            $sql = $sqlSelect . $sqlFrom . $sqlWhere . $sqlOrder . $sqlLimit;
        }
        $this->setLastQuery($sql);

        try {
            $stmt = $this->db->prepare($sql);
            $this->setLastQuery($stmt->queryString, $this->getParameters());
            $stmt->execute($this->getParameters());
        } catch (\PDOException $e) {
            throw new DatabaseException($e->getMessage() . '<br>' . $this->getLastQuery()[0]);
        }

        $this->setResult($stmt);
        $this->clearQuery();

        return $this;
    }