Intereting Posts

Оператор вопросительной метки в запросе

В моем приложении laravel 5 я использую тип данных jsonb для PostgreSQL, и он имеет ? оператор.

Но я не могу заставить его работать в моей модели, потому что laravel использует вопросительные знаки как привязки.

В частности, в методе whereRaw ():

 $query->whereRaw("jsonb_column ? 'a_key'") 

Как я могу использовать знак вопроса в своих запросах?

В основном у вас есть 2 варианта:

  1. Причиняя вашу руку грязным, расширив текущий способ, whereRaw Query Builder Laravel реализует whereRaw , иначе заявлял, что это трудно .
  2. Отправьте запрос функции команде Laravel (т. Е. Попросите продлить все компоненты Query Builder, касающиеся большего количества спецификаций PostgresQL), и скрестите пальцы, они будут обращаться к нему, если вы достаточно терпеливы .

Вот мои пожелания для опции [1.]:

Пространство имен «Illuminate \ Database \ Query» подходит для вас:

Вам особенно необходимо вникать в следующие исходные коды Laravel 5.0:

  • Builder.php
  • Grammar.php
  • PostgresGrammar.php

Кодовые фрагменты, представляющие интерес:

whereRaw in Builder.php (выдержка):

 /** * Add a raw where clause to the query. * * @param string $sql * @param array $bindings * @param string $boolean * @return $this */ public function whereRaw($sql, array $bindings = array(), $boolean = 'and') { $type = 'raw'; $this->wheres[] = compact('type', 'sql', 'boolean'); $this->addBinding($bindings, 'where'); return $this; } 

compileWheres в Grammar.php (выдержка):

 /** * Compile the "where" portions of the query. * * @param \Illuminate\Database\Query\Builder $query * @return string */ protected function compileWheres(Builder $query) { $sql = array(); if (is_null($query->wheres)) return ''; // Each type of where clauses has its own compiler function which is responsible // for actually creating the where clauses SQL. This helps keep the code nice // and maintainable since each clause has a very small method that it uses. foreach ($query->wheres as $where) { $method = "where{$where['type']}"; $sql[] = $where['boolean'].' '.$this->$method($query, $where); } // If we actually have some where clauses, we will strip off the first boolean // operator, which is added by the query builders for convenience so we can // avoid checking for the first clauses in each of the compilers methods. if (count($sql) > 0) { $sql = implode(' ', $sql); return 'where '.$this->removeLeadingBoolean($sql); } return ''; } 

$ операторов в PostgresGrammar.php (выдержка):

 /** * All of the available clause operators. * * @var array */ protected $operators = array( '=', '<', '>', '<=', '>=', '<>', '!=', 'like', 'not like', 'between', 'ilike', '&', '|', '#', '<<', '>>', ); 

обратите внимание на это ? недействительный оператор 😉

Специализированные защищенные PostgreSQL методы в PostgresGrammar.php (выдержка):

 /** * Compile the additional where clauses for updates with joins. * * @param \Illuminate\Database\Query\Builder $query * @return string */ protected function compileUpdateWheres(Builder $query) { $baseWhere = $this->compileWheres($query); if ( ! isset($query->joins)) return $baseWhere; // Once we compile the join constraints, we will either use them as the where // clause or append them to the existing base where clauses. If we need to // strip the leading boolean we will do so when using as the only where. $joinWhere = $this->compileUpdateJoinWheres($query); if (trim($baseWhere) == '') { return 'where '.$this->removeLeadingBoolean($joinWhere); } return $baseWhere.' '.$joinWhere; } /** * Compile the "join" clauses for an update. * * @param \Illuminate\Database\Query\Builder $query * @return string */ protected function compileUpdateJoinWheres(Builder $query) { $joinWheres = array(); // Here we will just loop through all of the join constraints and compile them // all out then implode them. This should give us "where" like syntax after // everything has been built and then we will join it to the real wheres. foreach ($query->joins as $join) { foreach ($join->clauses as $clause) { $joinWheres[] = $this->compileJoinConstraint($clause); } } return implode(' ', $joinWheres); } 

рассмотрите их как своего рода специализацию компиляций, упомянутых выше, остальные случаи, кроме двух (только 2 !!!) специфических, скомпилированы с использованием метода родительского класса (Illuminate \ Database \ Query \ Grammars \ Grammar).


Другие рекомендуемые соответствующие ресурсы

Вы можете найти ценные сообщения в этом блоге ( SOFTonSOFA ).

Я особенно рекомендую:

  • Глобальная область Laravel Query Builder – как использовать пользовательский Connection и Query Builder в Laravel 4 , но не в правильной версии, но показывает, как расширить Query Builder.
  • Laravel 5 Eloquent Global Scope how-to , в Laravel 5.0, но ортогональный вашему вопросу, но поучительный (правая версия, детали сантехники).

И последнее, но не менее важное: документация Laravel – лучшее место, где можно получить больше информации об основах архитектуры (Поставщики услуг, Сервисный контейнер, Фасады и т. Д.). Освоение позволяет использовать надежное расширение структуры .


Надеюсь, мой ввод даст вам достаточно намеков на возможную точку расширения предлагаемого конструктора запросов Laravel и может ли это послужить хорошей отправной точкой для написания расширения PostgreSQL ? оператора в whereRaw .

Пожалуйста, отдайте / поделитесь, когда закончите.

вы можете использовать вызов функции вместо оператора.

Сначала вы должны выяснить, какая функция? оператор использует следующий запрос в вашей базе данных PostgresSQL:

 SELECT oprname, oprcode FROM pg_operator WHERE oprname = '?' 

в моей базе данных разработки это функция jsonb_exists , тогда вы можете обновить свой запрос как:

 $query->whereRaw("jsonb_exists(jsonb_column, 'a_key')") 

Надеюсь, это поможет, счастливая кодировка.

Попробуйте ускользнуть, используя обратную косую черту, например

 SELECT * FROM table WHERE id = \?;