Prepares query for logging.

@param  string $query  SQL query
@param  array  $params Query paramaters
@return string
964349
protected function prepareQueryForLog(string $query, array $params): string
	{
		return preg_replace_callback('/\?/', function() use (&$params)
		{
			$param = array_shift($params);

			if(is_int($param) || is_float($param))
			{
				return $param;
			}
			elseif(is_bool(($param)))
			{
				return $param ? 'TRUE' : 'FALSE';
			}
			elseif(is_object($param))
			{
				return get_class($param);
			}
			elseif(is_null($param))
			{
				return 'NULL';
			}
			elseif(is_resource($param))
			{
				return 'resource';
			}
			else
			{
				return $this->pdo->quote($param);
			}
		}, $query);
	}
1038047
protected function namedParams(&$query, &$params)
    {
        if (!is_array($params)) {
            return;
        }

        $pattern = "a-zA-Z0-9_";

        if (!preg_match("/\?([" . $pattern . "]+)/", $query)) {
            return;
        }

        $oldParams = $params;
        $params = [];

        reset($oldParams);
        $this->modifyQuery($query, function($part) use(&$params, &$oldParams, $pattern) {
            return preg_replace_callback("/\?([" . $pattern . "]*)([^" . $pattern . "]|$)/", function($match) use(&$params, &$oldParams) {
                if ($key = $match[1]) {
                    $params[] = $oldParams[$key];
                } else {
                    $params[] = current($oldParams);
                    next($oldParams);
                }
                return "?" . $match[2];
            }, $part);
        });
    }
44261
public function executeQuery($query, array $params = []) {
        $storage = $this->getStorage();
        $cacheKey = null;
        $cacheLength = null;

        // Determine cache key and lengths
        if ($query instanceof Query) {
            $cacheKey = $query->getCacheKey();
            $cacheLength = $query->getCacheLength();

        } else if (!is_array($query)) {
            throw new InvalidQueryException('Query must be a command array or a Titon\Db\Query instance');
        }

        // Use the storage engine first
        if ($cacheKey) {
            if ($storage && $storage->has($cacheKey)) {
                return $storage->get($cacheKey);

            // Fallback to driver cache
            // This is used to cache duplicate queries
            } else if ($this->hasCache($cacheKey)) {
                return $this->getCache($cacheKey);
            }
        }

        // Execute the query using the dialect
        $db = $this->getConnection()->selectDB($this->getDatabase());
        $dialect = $this->getDialect();
        $startTime = microtime();

        // Direct query command
        if (is_array($query)) {
            $response = $db->command($query, $params);

        // Using query object
        } else {
            if ($query->getType() === Query::CREATE_TABLE) {
                $response = $dialect->executeCreateTable($db, $query);

            } else {
                $type = $query->getType();
                $method = 'execute' . ucfirst($type);

                if (!method_exists($dialect, $method)) {
                    throw new UnsupportedQueryStatementException(sprintf('Query statement %s does not exist or has not been implemented', $type));
                }

                $response = call_user_func_array([$dialect, $method], [$db->selectCollection($query->getTable()), $query]);
            }
        }

        // Gather and log result
        if (is_array($response)) {
            $response['startTime'] = $startTime;

            if (isset($response['id'])) {
                $this->_lastID = $response['id'];
            }
        } else {
            $this->_lastID = null;
        }

        if (is_array($query)) {
            $response['command'] = $query;

            $this->_result = new MongoResultSet($response);
        } else {
            $this->_result = new MongoResultSet($response, $query);
        }

        $this->logQuery($this->_result);

        // Return and cache result
        if ($cacheKey) {
            if ($storage) {
                $storage->set($cacheKey, $this->_result, $cacheLength);
            } else {
                $this->setCache($cacheKey, $this->_result);
            }
        }

        return $this->_result;
    }
1259567
public function column(string $query, array $params = [])
	{
		$prepared = $this->prepare($query, $params);

		$this->execute($prepared);

		return $prepared['statement']->fetchColumn();
	}
1277769
public function execute($query = null, array $params = []) : object
    {
        // When using one argument and its array, assume its $params
        if (is_array($query)) {
            $params = $query;
            $query = null;
        }

        if (!$query) {
            $query = $this->getSQL();
        }

        return parent::execute($query, $params);
    }
256367
public function first(string $query, array $params = [], ...$fetchMode)
	{
		$prepared = $this->prepare($query, $params);

		$this->execute($prepared);

		if(!empty($fetchMode))
		{
			$prepared['statement']->setFetchMode(...$fetchMode);
		}

		return $prepared['statement']->fetch();
	}
911331
public static function setParams($query, array $params = []) {
        Str::assert($query, 'query');

        return array_reduce($params, function($query, $param) {
            $param = self::getStringRepresentation($param);

            return strpos($query, '?') ? substr_replace($query, $param, strpos($query, '?'), strlen('?')) : $query;
        }, $query);
    }
336123
protected function bindParams($query, $sqlParams)
    {
        if (empty($sqlParams)) {
            $sqlParams = [];
        } 
        uksort(
            $sqlParams,
            function ($k1, $k2) {
                return strlen($k1) < strlen($k2);
            }
        );
        foreach ($sqlParams as $key=>$value) {
            if (gettype($value)==="array") {
                $value = array_map(
                    function ($v) {
                        return $this->escape($v);
                    },
                    $value
                );
                $value = "(".implode(",", $value).")";
                $query = str_replace($key, $value, $query);
            } else {
                $query = str_replace($key, $this->escape($value), $query);
            }
        }
        return $query;
    }
508113
protected function prepareQuery($query)
    {
        $query = $query->with($this->withs);

        if ($this->withCounts) {
            $query = $query->withCount($this->withCounts);
        }

        if ($this->orderBy) {
            $query = $query->orderBy($this->orderBy, $this->orderByDirection);
        }

        if ( ! empty($this->has)) {
            foreach ($this->has as $has) {
                $query = $query->has($has['relation'], $has['operator'], $has['value']);
            }
        }

        if ( ! empty($this->whereHas)) {
            foreach ($this->whereHas as $has) {
                $query = $query->whereHas($has[0], isset($has[1]) ? $has[1] : null);
            }
        }

        return $query;
    }
252129
public function query(string $sql, array $params = []): Statement
    {
        $this->usedPrepare = false;
        $stmt = $this->prepare($sql, $params);
        $this->usedPrepare = true;
        $stmt->execute();
        return $stmt;
    }
343621
public static function getSqlWithParams(string $sql, array $params = []): string
    {
        if (! empty($params)) {
            $indexed = ($params === array_values($params));
            foreach ($params as $k => $v) {
                if (is_string($v)) {
                    $v = "'${v}'";
                }
                if (is_array($v)) {
                    $v = "'" . implode("','", $v) . "'";
                }
                if ($indexed) {
                    $sql = preg_replace('/\?/', $v, $sql, 1);
                } else {
                    $sql = str_replace(":${k}", $v, $sql);
                }
            }
        }

        return str_replace(PHP_EOL, '', $sql);
    }
884064
protected function prepareParams($query, $sqlParams)
    {
        if (empty($sqlParams)) {
            $sqlParams = [];
        }
        uksort(
            $sqlParams,
            function ($k1, $k2) {
                return strlen($k1) < strlen($k2);
            }
        );
        $resultQuery = $query;
        $paramNum = 0;
        foreach ($sqlParams as $paName => $paValue) {
            if (gettype($paValue)==="array") {
                $paramList = [];
                foreach ($paValue as $i=>$value) {
                    // $paramList[] = $paName . "_param$i";
                    $paramList[] = ":pdoParam$paramNum";
                    $paramNum++;
                }
                $resultQuery = str_replace($paName, implode(",", $paramList), $resultQuery);
            }
        }
        return $resultQuery;
    }
889476
public function query($query, array $params = [])
    {
        $this->queryString = $query;
        $this->queryParams = $params;

        return $this;
    }
1173039
public function query($query, array $params = [])
    {
        $this->lastStatement = $this->getPDO()->prepare($query);
        $this->lastStatement->execute($this->prepareParams($params));
        return $this->lastStatement;
    }
1332839
public function execute($query, $params = []) : object
    {
        self::$queries[] = $query;
        self::$params[]  = $params;
        self::$numQueries++;

        if ($this->options['verbose']) {
            echo "<p>Num query = "
                . self::$numQueries
                . "</p><p>Query = </p><pre>"
                . htmlentities($query)
                . "</pre>"
                . (empty($params)
                    ? null
                    : "<p>Params:</p><pre>" . htmlentities(print_r($params, 1)) . "</pre>"
                );
        }

        return parent::execute($query, $params);
    }
364378
protected function prepare(string $query, array $params): array
    {
        try {
            $statement = $this->getPDO()->prepare($query);
        } catch (PDOException $e) {
            throw new PDOException($e->getMessage() . ' [ ' . $this->replaceParams($query, $params) . ' ] ',
                (int)$e->getCode(), $e->getPrevious());
        }

        return ['query' => $query, 'params' => $params, 'statement' => $statement];
    }
1090630
final public static function getObjectByQuery($query, $params=[]) {
		
		$app	= Application::getInstance();
		$db		= Database::getInstance();
		$class	= get_called_class();
		
		// run query
		$db->setQuery($query);
		$row = $db->loadObject($params);
		
		// initialize custom binds
		$customBinds = [];
		
		if (!is_a($row, 'stdClass')) {
			return NULL;
		}
			
		$binds = $class::getBinds();
		
		// get object properties from query
		$fields  = get_object_vars($row);
		
		// search for custom field names
		foreach ($fields as $field=>$value) {
			if (!array_search($field, $binds)) {
				$customBinds[Utilities::getCamelCase($field)] = $field;
			}
		}
		
		$object = new $class($row);
		
		// populate custom properties
		foreach ($customBinds as $customProp=>$customField) {
			$object->$customProp = $row->$customField;
		}
			
		// turn on loaded-from-db flag
		$object->loadedFromDb = TRUE;
			
		$app->logEvent('Loaded a ' . $class . ' object' . (count($customBinds) ? ' with custom fields ' . implode(',', $customBinds) : ''));
		
		return $object;
		
	}