Format the fields values structure depending on the type of query.

@param \Titon\Db\Query $query
@return string
352191
public function formatValues(Query $query) {
        $fields = $query->getData();

        switch ($query->getType()) {
            case Query::INSERT:
                return sprintf($this->getClause(self::GROUP), implode(', ', array_fill(0, count($fields), '?')));
            break;
            case Query::MULTI_INSERT:
                $value = sprintf($this->getClause(self::GROUP), implode(', ', array_fill(0, count($fields[0]), '?')));

                return implode(', ', array_fill(0, count($fields), $value));
            break;
        }

        return '';
    }
1102465
private function filterQuery(string $query): string
    {
        if (trim($query) == '') {
            return '';
        }

        if ($query[0] == '?') {
            $query = substr($query, 1);
        }

        $parts = explode('&', $query);
        foreach ($parts as $index => $part) {
            $data = explode('=', $part);
            $key = array_shift($data);

            if (count($data) == 0) {
                $parts[$index] = $this->encodeQuery($key);
                continue;
            }

            $value = implode('=', $data);
            $parts[$index] = $this->encodeQuery($key).'='.$this->encodeQuery($value);
        }

        return implode('&', $parts);
    }
959084
protected function parseTerm($query)
    {
        $query = $this->escape($query);

        $match = preg_match("/([^>=|<=|!=|>|<|=|\*=)]*)(>=|<=|!=|>|<|=|\*=)(.*)/", $query, $matches);

        if ($match) {
            $term = array();
            $term['property'] = trim($matches[1]);
            $term['operator'] = trim($matches[2]);
            $term['value'] = $this->decode(trim(($matches[3])));

            return $term;
        }

        return false;
    }
1233065
public function quote(Query $query)
    {
        $binder = $query->getValueBinder();
        $query->setValueBinder(false);

        if ($query->type() === 'insert') {
            $this->_quoteInsert($query);
        } elseif ($query->type() === 'update') {
            $this->_quoteUpdate($query);
        } else {
            $this->_quoteParts($query);
        }

        $query->traverseExpressions([$this, 'quoteExpression']);
        $query->setValueBinder($binder);

        return $query;
    }
646594
public function delete(Query $query)
    {
        $options = $query->getOptions();

        return str_replace(
            ['%TABLE%', '%USING%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'],
            [
                $this->parseTable($query, $options['table']),
                !empty($options['using']) ? ' USING ' . $this->parseTable($query, $options['using']) . ' ' : '',
                $this->parseJoin($query, $options['join']),
                $this->parseWhere($query, $options['where']),
                $this->parseOrder($query, $options['order']),
                $this->parseLimit($query, $options['limit']),
                $this->parseLock($query, $options['lock']),
                $this->parseComment($query, $options['comment']),
            ],
            $this->deleteSql);
    }
562853
public function buildDelete(Query $query) {
        return $this->renderStatement(Query::DELETE, [
            'table' => $this->formatTable($query->getTable(), $query->getAlias()),
            'joins' => $this->formatJoins($query->getJoins()),
            'where' => $this->formatWhere($query->getWhere()),
            'orderBy' => $this->formatOrderBy($query->getOrderBy()),
            'limit' => $this->formatLimit($query->getLimit()),
        ] + $this->formatAttributes($query->getAttributes()));
    }
727989
public function override($query)
    {
        foreach ($this->data as $key => $value) {
            $query = str_replace(
                sprintf('{%s}', $key),
                $value,
                $query
            );
        }

        return $query;
    }
580764
public function formatSubQuery(SubQuery $query) {

        // Reset the alias since statement would have double aliasing
        $alias = $query->getAlias();
        $query->asAlias(null);

        // @codeCoverageIgnoreStart
        if (method_exists($this, 'buildSelect')) {
            $output = sprintf($this->getClause(self::SUB_QUERY), trim($this->buildSelect($query), ';'));
        } else {
            throw new UnsupportedQueryStatementException('Sub-query building requires a buildSelect() method');
        }
        // @codeCoverageIgnoreEnd

        if ($alias) {
            $output = sprintf($this->getClause(self::AS_ALIAS), $output, $this->quote($alias));
        }

        if ($filter = $query->getFilter()) {
            $output = $this->getKeyword($filter) . ' ' . $output;
        }

        return $output;
    }
687
public function update(Query $query)
    {
        $options = $query->getOptions();

        $table = $this->parseTable($query, $options['table']);
        $data  = $this->parseData($query, $options['data']);

        if (empty($data)) {
            return '';
        }

        foreach ($data as $key => $val) {
            $set[] = $key . ' = ' . $val;
        }

        return str_replace(
            ['%TABLE%', '%SET%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'],
            [
                $this->parseTable($query, $options['table']),
                implode(' , ', $set),
                $this->parseJoin($query, $options['join']),
                $this->parseWhere($query, $options['where']),
                $this->parseOrder($query, $options['order']),
                $this->parseLimit($query, $options['limit']),
                $this->parseLock($query, $options['lock']),
                $this->parseComment($query, $options['comment']),
            ],
            $this->updateSql);
    }
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;
    }
641973
public function getSelectedFields(String $query) : Array
	{
		$columns = [];

		if (Type::getStatementType($query) == 1) {
			if (preg_match("/(SELECT|select|Select)(.*?)FROM|from|From([^ ]+)/s", $query, $matches)) {
				$columns = explode(',', $matches[2]);
				$columns = array_map(function($field) {
					return trim(ltrim($field));
				}, $columns);
			}
		}

		return $columns;
	}
777862
protected function getQueryInfos($query)
    {
        $type = strtolower(substr($query, 0, 6));

        switch ($type) {
            case 'select':
                $pattern = '/SELECT\s((.|\n)*)\sFROM\s(?P<table>[a-zA-Z_]*)($|(.*)$)/i';
                break;

            case 'insert':
                $pattern = '/INSERT(\s+)INTO(\s+)(?P<table>[a-zA-Z_]*)(\s*)(.*)/i';
                break;

            case 'update':
                $pattern = '/UPDATE(\s+)(?P<table>[a-zA-Z_]*)(\s*)(.*)/i';
                break;

            case 'delete':
                $pattern = '/DELETE(\s+)FROM(\s+)(?P<table>[a-zA-Z_]*)(\s*)(.*)/i';
                break;

            default:
                $type = 'other';
                $pattern = false;
        }

        if ($pattern && preg_match($pattern, $query, $matches)) {
            return array($type, $matches['table']);
        }

        return array($type, '__unknown');
    }
1300307
public function extractPrefixesFromQuery($query)
    {
        preg_match_all('/PREFIX\s+([a-z0-9]+)\:\s*\<([a-z0-9\:\/\.\#\-]+)\>/', $query, $matches);

        $prefixes = [];

        foreach ($matches[1] as $index => $key) {
            $prefixes[$key] = $matches[2][$index];
        }

        return $prefixes;
    }
560248
protected function _schema($query, $fields = null) {
		$model = $query->model();
		$paths = $query->paths($this);
		$models = $query->models($this);
		$alias = $query->alias();
		$result = [];

		if (!$model) {
			foreach ($fields as $field => $value) {
				if (is_array($value)) {
					$result[$field] = array_keys($value);
				} else {
					$result[''][] = $field;
				}
			}
			return $result;
		}
		if (!$fields) {
			foreach ($paths as $alias => $relation) {
				$model = $models[$alias];
				$result[$relation] = $model::schema()->names();
			}
			return $result;
		}

		$unalias = function ($value) {
			if (is_object($value) && isset($value->scalar)) {
				$value = $value->scalar;
			}
			$aliasing = preg_split("/\s+as\s+/i", $value);
			return isset($aliasing[1]) ? $aliasing[1] : $value;
		};

		if (isset($fields[0])) {
			$raw = array_map($unalias, $fields[0]);
			unset($fields[0]);
		}

		$fields = isset($fields[$alias]) ? [$alias => $fields[$alias]] + $fields : $fields;

		foreach ($fields as $field => $value) {
			if (is_array($value)) {
				if (isset($value['*'])) {
					$relModel = $models[$field];
					$result[$paths[$field]] = $relModel::schema()->names();
				} else {
					$result[$paths[$field]] = array_map($unalias, array_keys($value));
				}
			}
		}

		if (isset($raw)) {
			$result[''] = isset($result['']) ? array_merge($raw, $result['']) : $raw;
		}
		return $result;
	}
518886
private function sanitizeQuery($query)
    {
        $parts = parse_url($query);
        $path  = $parts['path'];

        if (!isset($parts['query'])) {
            return $query;
        }

        $vars = explode('&', $parts['query']);

        $final = [];

        if (!empty($vars)) {
            foreach ($vars as $var) {
                $parts = explode('=', $var);

                $key = $parts[0];
                $val = $parts[1];

                if (!array_key_exists($key, $final) && !empty($val)) {
                    $final[$key] = $val;
                }
            }
        }

        return $path . '?' . http_build_query($final);
    }
849566
private function prepareQueryFiler($query)
    {
        $result = [];
        foreach ($query as $key => $value) {
            if (is_array($value)) {
                $result[$key] = $this->prepareQueryFiler($value);
            } elseif (is_string($value) && preg_match('#^(MongoDB\\\\BSON\\\\[A-Za-z]+)\\((.*)\\)$#s', $value, $matches)) {
                $class = $matches[1];
                $objectValue = $matches[1];

                try {
                    $result[$key] = new $class($objectValue);
                } catch (\Exception $e) {
                    $result[$key] = $value;
                }
            } else {
                $result[$key] = $value;
            }
        }
        return $result;
    }
405102
private function buildQueryUrlParameter($query)
    {
        switch ($query) {
            case is_array($query) && isset($query['lat']) && isset($query['lon']) && is_numeric($query['lat']) && is_numeric($query['lon']):
                return "lat={$query['lat']}&lon={$query['lon']}";
            case is_array($query) && is_numeric($query[0]):
                return 'id='.implode(',', $query);
            case is_numeric($query):
                return "id=$query";
            case is_string($query) && strpos($query, 'zip:') === 0:
                $subQuery = str_replace('zip:', '', $query);
                return 'zip='.urlencode($subQuery);
            case is_string($query):
                return 'q='.urlencode($query);
            default:
                throw new \InvalidArgumentException('Error: $query has the wrong format. See the documentation of OpenWeatherMap::getWeather() to read about valid formats.');
        }
    }