生成查询条件SQL
@access public
@param Query     $query        查询对象
@param mixed     $where
@param array     $options
@return string
188027
public function buildWhere(Query $query, $where)
    {
        if (empty($where)) {
            $where = [];
        }

        $whereStr = '';
        $binds    = $this->connection->getFieldsBind($query->getOptions('table'));

        foreach ($where as $logic => $val) {
            $str = [];

            foreach ($val as $value) {
                if ($value instanceof Expression) {
                    $str[] = ' ' . $logic . ' ( ' . $value->getValue() . ' )';
                    continue;
                }

                if (is_array($value)) {
                    if (key($value) !== 0) {
                        throw new Exception('where express error:' . var_export($value, true));
                    }
                    $field = array_shift($value);
                } elseif (!($value instanceof \Closure)) {
                    throw new Exception('where express error:' . var_export($value, true));
                }

                if ($value instanceof \Closure) {
                    // 使用闭包查询
                    $newQuery = $query->newQuery()->setConnection($this->connection);
                    $value($newQuery);
                    $whereClause = $this->buildWhere($query, $newQuery->getOptions('where'));

                    if (!empty($whereClause)) {
                        $str[] = ' ' . $logic . ' ( ' . $whereClause . ' )';
                    }
                } elseif (is_array($field)) {
                    array_unshift($value, $field);
                    $str2 = [];
                    foreach ($value as $item) {
                        $str2[] = $this->parseWhereItem($query, array_shift($item), $item, $logic, $binds);
                    }

                    $str[] = ' ' . $logic . ' ( ' . implode(' AND ', $str2) . ' )';
                } elseif (strpos($field, '|')) {
                    // 不同字段使用相同查询条件（OR）
                    $array = explode('|', $field);
                    $item  = [];

                    foreach ($array as $k) {
                        $item[] = $this->parseWhereItem($query, $k, $value, '', $binds);
                    }

                    $str[] = ' ' . $logic . ' ( ' . implode(' OR ', $item) . ' )';
                } elseif (strpos($field, '&')) {
                    // 不同字段使用相同查询条件（AND）
                    $array = explode('&', $field);
                    $item  = [];

                    foreach ($array as $k) {
                        $item[] = $this->parseWhereItem($query, $k, $value, '', $binds);
                    }

                    $str[] = ' ' . $logic . ' ( ' . implode(' AND ', $item) . ' )';
                } else {
                    // 对字段使用表达式查询
                    $field = is_string($field) ? $field : '';
                    $str[] = ' ' . $logic . ' ' . $this->parseWhereItem($query, $field, $value, $logic, $binds);
                }
            }

            $whereStr .= empty($whereStr) ? substr(implode(' ', $str), strlen($logic) + 1) : implode(' ', $str);
        }

        return $whereStr;
    }
490952
public function findWithTrashed(Query $query, array $options)
    {
        return $query->where(['OR' => [
            $query->newExpr()->isNotNull($this->getTrashField()),
            $query->newExpr()->isNull($this->getTrashField()),
        ]]);
    }
715948
public static function all($table,$where=[],$option=[])
    {
        $sql=self::parseSql($table,$where,$option);
        return $sql->fetchAll();
    }
1058953
public function compileWheres(Query $query)
	{
		$wheres = $query->wheres;

		$sql = [];

		foreach ($wheres as $where)
		{
			if ($where instanceof Expression)
			{
				switch ($where->type)
				{
					case 'raw':

						$sql[] = $this->compileRawWhere($where);

						break;

					case 'disjunct':
						
						$sql[] = $this->compileBasicWhere($where);

						break;

					case 'builder':

						$query = Query::$self->newQuery();

						call_user_func($where->clause, $query);

						$sql[] = '(' . substr($this->compileWheres($query), 6) . ')';

						break;
					
					default:
						# code...
						break;
				}
			}
			elseif (($operator = $where) instanceof Operator)
			{
				$sql[] = $operator->getType();
			}
		}

		return 'WHERE ' . implode(' ', $sql);
	}
611340
public function execute(Query $query, array $options = [])
    {
        $result = $this->_executeQuery($query, $options);

        if ($this->getDriver() === null) {
            throw new \UnexpectedValueException(__('No driver has been defined'));
        }

        // Write to the logger when one has been defined
        if ($this->getDriver()->getLogger()) {
            $this->_logQuery($query, $this->getDriver()->getLogger());
        }

        return $result;
    }
5760
public function findDistance(Query $query, array $options) {
		$options += ['tableName' => null, 'sort' => true];
		$sql = $this->distanceExpr($options['lat'], $options['lng'], null, null, $options['tableName']);

		if ($query->autoFields() === null) {
			$query->autoFields(true);
		}

		$query->select(['distance' => $query->newExpr($sql)]);
		if (isset($options['distance'])) {
			// Some SQL versions cannot reuse the select() distance field, so we better reuse the $sql snippet
			$query->where(function ($exp) use ($sql, $options) {
				return $exp->lt($sql, $options['distance']);
			});
		}

		if ($options['sort']) {
			$sort = $options['sort'] === true ? 'ASC' : $options['sort'];
			$query->order(['distance' => $sort]);
		}

		return $query;
	}
727090
public function findToken(Query $query, array $options)
    {
        $options += [
            'token' => null,
            'expired >' => new DateTime(),
            'status' => false
        ];

        return $query->where($options);
    }
204838
public function update($query, array $options = []) {
		$params = compact('query', 'options');

		return Filters::run($this, __FUNCTION__, $params, function($params) {
			$query = $params['query'];
			$options = $params['options'];
			$params = $query->export($this);

			list($_path, $conditions) = (array) $params['conditions'];
			$data = $query->data();

			foreach (['id', 'rev'] as $key) {
				$data["_{$key}"] = isset($data[$key]) ? (string) $data[$key] : null;
				unset($data[$key]);
			}
			$data = (array) $conditions + array_filter((array) $data);

			$retry = false;
			do {
				$result = $this->connection->put(
					"{$this->_config['database']}/{$_path}",
					$data,
					['type' => 'json']
				);
				$result = is_string($result) ? json_decode($result, true) : $result;
				$retry = $retry ? !$retry : $this->_autoBuild($result);
			} while ($retry);

			if (isset($result['_id']) || (isset($result['ok']) && $result['ok'] === true)) {
				$result = $this->_format($result, $options);
				$query->entity()->sync($result['id'], ['rev' => $result['rev']]);
				return true;
			}
			if (isset($result['error'])) {
				$query->entity()->errors([$result['error']]);
			}
			return false;
		});
	}
159240
public static function get($url, $query = [], $options = [])
    {
        $options['query'] = $query;
        return self::doRequest('get', $url, $options);
    }
139970
public function findForIndex(Query $query, array $options)
    {
        return $query->contain([
                $this->Categories->getAlias() => ['fields' => ['title', 'slug']],
                $this->Tags->getAlias() => function (Query $q) {
                    return $q->order(['tag' => 'ASC']);
                },
                $this->Users->getAlias() => ['fields' => ['id', 'first_name', 'last_name']],
            ])
            ->select(['id', 'title', 'preview', 'subtitle', 'slug', 'text', 'enable_comments', 'created'])
            ->order([sprintf('%s.created', $this->getAlias()) => 'DESC']);
    }
369336
public function pdo(Query $query)
    {
        // 分析查询表达式
        $options = $query->getOptions();

        // 生成查询SQL
        $sql = $this->builder->select($query);

        $bind = $query->getBind();

        if (!empty($options['fetch_sql'])) {
            // 获取实际执行的SQL语句
            return $this->getRealSql($sql, $bind);
        }

        // 执行查询操作
        return $this->query($sql, $bind, $options['master'], true);
    }
1184515
public function query(array $queryArgs, array $query = [], array $options = [])
    {
        $httpParams = [
            'query_parameters' => []
        ];
        $request = [
            'volatile' => $this->volatile
        ];

        if (array_key_exists('controller', $queryArgs)) {
            $request['controller'] = $queryArgs['controller'];
        } else {
            if (!array_key_exists('route', $queryArgs) || !array_key_exists('method', $queryArgs)) {
                throw new InvalidArgumentException('Unable to execute query: missing controller or route/method');
            }

            $request['controller'] = '';
        }

        if (array_key_exists('action', $queryArgs)) {
            $request['action'] = $queryArgs['action'];
        } else {
            if (!array_key_exists('route', $queryArgs) || !array_key_exists('method', $queryArgs)) {
                throw new InvalidArgumentException('Unable to execute query: missing action or route/method');
            }

            $request['action'] = '';
        }

        if (!empty($options)) {
            if (array_key_exists('volatile', $options)) {
                foreach ($options['volatile'] as $meta => $value) {
                    $request['volatile'][$meta] = $value;
                }
            }

            if (array_key_exists('requestId', $options)) {
                $request['requestId'] = $options['requestId'];
            }

            if (array_key_exists('httpParams', $options)) {
                foreach ($options['httpParams'] as $param => $value) {
                    $httpParams[$param] = $value;
                }
            }

            if (isset($options['query_parameters'])) {
                $httpParams['query_parameters'] = array_merge($httpParams['query_parameters'], $options['query_parameters']);
            }

            foreach (['refresh', 'from', 'size', 'scroll'] as $optionParam) {
                if (array_key_exists($optionParam, $options)) {
                    $httpParams['query_parameters'][$optionParam] = $options[$optionParam];
                }
            }
        }

        if (array_key_exists('volatile', $query)) {
            foreach ($query['volatile'] as $meta => $value) {
                $request['volatile'][$meta] = $value;
            }
        }

        foreach ($query as $attr => $value) {
            if ($attr === 'body' && empty($value)) {
                $request['body'] = (object)[];
            } else if ($attr !== 'volatile') {
                $request[$attr] = $value;
            }
        }

        $request = $this->addHeaders($request, $this->headers);

        /*
        * Do not add the token for the checkToken route, to avoid getting a token error when
        * a developer simply wish to verify his token
        */
        if ($this->jwtToken && !($request['controller'] === 'auth' && $request['action'] === 'checkToken')) {
            if (array_key_exists('headers', $request) && !is_array($request['headers'])) {
                $request['headers'] = [];
            }

            $request['headers']['authorization'] = 'Bearer ' . $this->jwtToken;
        }

        foreach (['collection', 'route', 'method', 'index'] as $queryArg) {
            if (array_key_exists($queryArg, $queryArgs)) {
                $request[$queryArg] = $queryArgs[$queryArg];
            }
        }

        if (!array_key_exists('requestId', $request)) {
            $request['requestId'] = Uuid::uuid4()->toString();
        }
         // @todo move this into RequestHandler
        return $this->emitRestRequest($this->convertRestRequest($request, $httpParams));
    }
379419
public function findEmailVerified(Query $query, array $options) {
		$query->where([
			$this->_table->aliasField($this->_field('emailVerified')) => true,
		]);

		return $query;
	}
979078
public function delete($query, array $options = []) {
		$params = compact('query', 'options');

		return Filters::run($this, __FUNCTION__, $params, function($params) {
			$query = $params['query'];
			$params = $query->export($this);
			list($_path, $conditions) = $params['conditions'];
			$data = $query->data();

			if (!empty($data['rev'])) {
				$conditions['rev'] = $data['rev'];
			}
			$result = $this->connection->delete(
				"{$this->_config['database']}/{$_path}",
				$conditions
			);
			$result = json_decode($result);
			$result = (isset($result->ok) && $result->ok === true);

			if ($query->entity()) {
				$query->entity()->sync(null, [], ['dematerialize' => true]);
			}
			return $result;
		});
	}
1206169
private static function parseWhere(IQuery $query, $where)
    {
        if(null === $where)
        {
            return $query;
        }
        if(is_callable($where))
        {
            // 回调传入条件
            call_user_func($where, $query);
        }
        else
        {
            foreach($where as $k => $v)
            {
                if(is_array($v))
                {
                    $operation = array_shift($v);
                    $query->where($k, $operation, $v[0]);
                }
                else
                {
                    $query->where($k, '=', $v);
                }
            }
        }
        return $query;
    }
1368350
public static function format($query, array $options = [])
    {
        $lexer = new Lexer($query);
        $formatter = new self($options);

        return $formatter->formatList($lexer->list);
    }
1366454
public function query(array $where, array $options = []) {
        $options += [
            'order' => $this->getDefaultOrder(),
            'limit' => $this->getDefaultLimit(),
            Db::OPTION_FETCH_MODE => $this->getFetchArgs()
        ];

        $stmt = $this->db->get($this->name, $where, $options);
        return $stmt;
    }