Do not speak Portuguese? Translate this site with Google or Bing Translator
Expressões de consulta do Laravel

Posted on: March 30, 2023 10:16 AM

Posted by: Renato

Views: 454

Substitua chamadas de consulta brutas por expressões de consulta do Laravel

..

Replace Raw Query Calls With Laravel Query Expressions
 

O pacote Query Expressions para Laravel substitui qualquer chamada de consulta bruta por expressões. Em vez de escrever o seguinte exemplo do leia-me :

 

// Instead of:

User::query()

->when(isPostgreSQL(), fn ($query) => $query->selectRaw('coalesce("user", "admin") AS "value"'))

->when(isMySQL(), fn ($query) => $query->selectRaw('coalesce(`user`, `admin`) AS `value`'))

.

Você poderia escrever algo como o seguinte usando este pacote:

 


 
User::select(
new Alias(new Coalesce(['user', 'admin']), 'count')
);
 
// More examples:
 
// UPDATE user_quotas SET credits = credits - 15 WHERE id = 1985
$quota->update([
'credits' => new Subtract('credits', new Number(15)),
]);
 
// SELECT id, name, (price - discount) * 0.2 AS vat FROM products
Product::select([
'id',
'name',
new Alias(new Multiply(new Subtract('price', 'discount'), Number(0.2)), 'vat')
])->get();

.

Além do código terser, por que você deseja usar algo como este pacote? O leia-me descreve como este pacote se encaixa em seus aplicativos Laravel:

A implementação do banco de dados do Laravel fornece uma boa maneira de trabalhar com vários bancos de dados enquanto abstrai seu funcionamento interno...

No entanto, quando queremos usar mais funcionalidade de banco de dados do que o Laravel fornece, devemos recorrer a expressões SQL brutas e escrever código específico do banco de dados. O pacote Query Expressions se baseia em novos recursos introduzidos no Laravel 10 para resolver esse problema.

No momento da redação, este pacote oferece suporte a várias expressões, como:

  • valores
  • Apelido
  • Operadores aritméticos
  • Operadores bit a bit
  • Comparação e operadores lógicos
  • funções agregadas
  • Condicional

----->>>>>

  • Values
  • Aliases
  • Arithmetic operators
  • Bitwise operators
  • Comparison and Logical operators
  • Aggregate functions
  • Conditional

Se você quiser saber mais sobre este pacote, confira laravel-query-expressions no GitHub. Você pode instalar este pacote em seu projeto Laravel 10 via composer:

composer require tpetry/laravel-query-expressions

.

Informações do Github

Laravel Query Expressions to replace DB::raw() calls

Supported PHP Versions Supported Laravel Versions Latest Version on Packagist GitHub Tests Action Status GitHub Static Analysis Action Status GitHub Code Style Action Status

Laravel's database implementation provides a good way of working with multiple databases while abstracting away their inner workings. You don't have to consider minor syntax differences when using a query builder or how each database handles specific operations slightly differently.

However, when we want to use more database functionality than Laravel provides, we must fall back to raw SQL expressions and write database-specific code. The Query Expressions package builds on new features introduced in Laravel 10 to solve that problem. All provided implementations abstract some SQL functionality that is automatically transformed to the correct syntax with the same behaviour for your used database engine. And if your version is still supported by Laravel but is missing a feature, it is emulated by the implementations. So you can even do things that were not possible before.

You can make your queries database independent:

// Instead of:
User::query()
    ->when(isPostgreSQL(), fn ($query) => $query->selectRaw('coalesce("user", "admin") AS "value"'))
    ->when(isMySQL(), fn ($query) => $query->selectRaw('coalesce(`user`, `admin`) AS `value`'))

// You can use:
User::select(new Alias(new Coalesce(['user', 'admin']), 'count'));

And you can also create new powerful queries:

// Aggregate multiple statistics with one query for dashboards:
Movie::select([
    new CountFilter(new Equal('released', new Number(2021))),
    new CountFilter(new Equal('released', new Number(2022))),
    new CountFilter(new Equal('genre_id', new Number(12))),
    new CountFilter(new Equal('genre_id', new Number(35))),
])->where('streamingservice', 'netflix');

Installation

You can install the package via composer:

composer require tpetry/laravel-query-expressions

Usage

This package implements a lot of expressions you can use for selecting data, do better filtering or ordering of rows. Every expression can be used exactly as stated by the documentation, but you can also combine them as shared in the example before. Whenever an expression class needs a string|Expression parameter, you can pass a column name or another (deeply nested) expression object.

Note A string passed for a string|Expression parameter is always used as a column name that will be automatically quoted.

Warning The generated SQL statements of the examples are only for explanatory purposes. The real ones will be automatically tailored to your database using proper quoting and its specific syntax.

Language

Values

As stated before, an expression is always a column name. But if you want to e.g. do an equality check, you may want to compare something to a specific value. That's where you should use the Number class.

use Tpetry\QueryExpressions\Value\Number;

new Number(44);
new Number(3.1415);

Note The Number class in isolation is not that usefull. But it will be used more in the next examples.

Alias

use Illuminate\Contracts\Database\Query\Expression;
use Tpetry\QueryExpressions\Language\Alias;
use Tpetry\QueryExpressions\Value\Number;

new Alias(string|Expression $expression, string $name)

User::select([
    new Alias('last_modified_at', 'modification_date'),
    new Alias(new Value(21), 'min_age_threshold'),
])->get();

Note The Alias class in isolation is not that usefull because Eloquent can already do this. But it will be used more in the next examples.

Operators

Arithmetic Operators

use Illuminate\Contracts\Database\Query\Expression;
use Tpetry\QueryExpressions\Operator\Arithmetic\{
    Add, Divide, Modulo, Multiply, Power, Subtract,
};
use Tpetry\QueryExpressions\Operator\Value\Number;

new Add(string|Expression $value1, string|Expression $value2);
new Divide(string|Expression $value1, string|Expression $value2);
new Modulo(string|Expression $value1, string|Expression $value2);
new Multiply(string|Expression $value1, string|Expression $value2);
new Power(string|Expression $value1, string|Expression $value2);
new Subtract(string|Expression $value1, string|Expression $value2);

// UPDATE user_quotas SET credits = credits - 15 WHERE id = 1985
$quota->update([
    'credits' => new Subtract('credits', new Number(15)),
]);

// SELECT id, name, (price - discount) * 0.2 AS vat FROM products
Product::select([
    'id',
    'name',
    new Alias(new Multiply(new Subtract('price', 'discount'), Number(0.2)), 'vat')
])->get();

Bitwise Operators

use Illuminate\Contracts\Database\Query\Expression;
use Tpetry\QueryExpressions\Operator\Bitwise\{
    BitAnd, BitNot, BitOr, BitXor, ShiftLeft, ShiftRight,
};
use Tpetry\QueryExpressions\Operator\Value\Number;

new BitAnd(string|Expression $value1, string|Expression $value2);
new BitNot(string|Expression $value);
new BitOr(string|Expression $value1, string|Expression $value2);
new BitXor(string|Expression $value1, string|Expression $value2);
new ShiftLeft(string|Expression $value, string|Expression $times);
new ShiftRight(string|Expression $value, string|Expression $times);

// SELECT * FROM users WHERE (acl & 0x8000) = 0x8000
User::where(new BitAnd('acl', 0x8000), 0x8000)
    ->get();

Comparison & Logical Operators

use Illuminate\Contracts\Database\Query\Expression;
use Tpetry\QueryExpressions\Operator\Comparison\{
    Between, DistinctFrom, Equal, GreaterThan, GreaterThanOrEqual, LessThan, LessThanOrEqual, NotDistinctFrom, NotEqual
};
use Tpetry\QueryExpressions\Operator\Logical\{
    CondAnd, CondNot, CondOr, CondXor
};
use Tpetry\QueryExpressions\Operator\Value\Number;

new Between(string|Expression $value, string|Expression $min, string|Expression $max);
new DistinctFrom(string|Expression $value1, string|Expression $value2);
new Equal(string|Expression $value1, string|Expression $value2);
new GreaterThan(string|Expression $value1, string|Expression $value2);
new GreaterThanOrEqual(string|Expression $value1, string|Expression $value2);
new LessThan(string|Expression $value1, string|Expression $value2);
new LessThanOrEqual(string|Expression $value1, string|Expression $value2);
new NotDistinctFrom(string|Expression $value1, string|Expression $value2);
new NotEqual(string|Expression $value1, string|Expression $value2);

new CondAnd(string|Expression $value1, string|Expression $value2);
new CondNot(string|Expression $value);
new CondOr(string|Expression $value1, string|Expression $value2);
new CondXor(string|Expression $value1, string|Expression $value2);

// Examples in Aggregates::countFilter()

Warning These objects can currently not be used with Laravel's where(). They are only for logical operations within aggregates or as selected columns. I am working on fixing that ;)

Functions

Aggregates

use Illuminate\Contracts\Database\Query\Expression;
use Tpetry\QueryExpressions\Function\Aggregate\{
    Avg, Count, CountFilter, Max, Min, Sum, SumFilter,
};
use Tpetry\QueryExpressions\Operator\Value\Number;

new Avg(string|Expression $value);
new Count(string|Expression $value);
new CountFilter(string|Expression $filter);
new Max(string|Expression $value);
new Min(string|Expression $value);
new Sum(string|Expression $value);
new SumFilter(string|Expression $value, string|Expression $filter);

// SELECT COUNT(*) AS visits, AVG(duration) AS duration FROM blog_visits WHERE ...
BlogVisit::select([
    new Alias(new Count('*'), 'visits'),
    new Alias(new Avg('duration'), 'duration'),
])
->whereDay('created_at', now())
->get();

// SELECT
//   COUNT(*) FILTER (WHERE (released = 2021)) AS released_2021,
//   COUNT(*) FILTER (WHERE (released = 2022)) AS released_20212,
//   COUNT(*) FILTER (WHERE (genre_id = 12)) AS genre_12,
//   COUNT(*) FILTER (WHERE (genre_id = 35)) AS genre_35
// FROM movies
// WHERE streamingservice = 'netflix'
Movie::select([
    new Alias(new CountFilter(new Equal('released', new Number(2021))), 'released_2021'),
    new Alias(new CountFilter(new Equal('released', new Number(2022))), 'released_2022'),
    new Alias(new CountFilter(new Equal('genre_id', new Number(12))), 'genre_12'),
    new Alias(new CountFilter(new Equal('genre_id', new Number(35))), 'genre_35'),
])
    ->where('streamingservice', 'netflix')
    ->get();

Conditional

use Tpetry\QueryExpressions\Function\Conditional\{
    Coalesce, Greatest, Least
};
use Tpetry\QueryExpressions\Language\Alias;

new Coalesce(array $expressions);
new Greatest(array $expressions);
new Least(array $expressions);

// SELECT GREATEST(published_at, updated_at, created_at) AS last_modification FROM blog_articles
BlogArticle::select([
    new Alias(new Greatest('published_at', 'updated_at', 'created_at'), 'last_modification')
])
->get();

 

Fontes:

- https://laravel-news.com/query-expressions-for-laravel

https://github.com/tpetry/laravel-query-expressions


3

Share

Donate to Site


About Author

Renato

Developer

Add a Comment
Comments 0 Comments

No comments yet! Be the first to comment

Blog Search


Categories

OUTROS (16) Variados (109) PHP (133) Laravel (171) Black Hat (3) front-end (29) linux (114) postgresql (39) Docker (28) rest (5) soap (1) webservice (6) October (1) CMS (2) node (7) backend (13) ubuntu (56) devops (25) nodejs (5) npm (3) nvm (1) git (8) firefox (1) react (7) reactnative (5) collections (1) javascript (7) reactjs (8) yarn (0) adb (1) Solid (2) blade (3) models (1) controllers (0) log (1) html (2) hardware (3) aws (14) Transcribe (2) transcription (1) google (4) ibm (1) nuance (1) PHP Swoole (5) mysql (31) macox (4) flutter (1) symfony (1) cor (1) colors (2) homeOffice (2) jobs (3) imagick (2) ec2 (1) sw (1) websocket (2) markdown (1) ckeditor (1) tecnologia (14) faceapp (1) eloquent (14) query (4) sql (40) ddd (3) nginx (9) apache (4) certbot (1) lets-encrypt (3) debian (12) liquid (1) magento (2) ruby (1) LETSENCRYPT (1) Fibonacci (1) wine (1) transaction (1) pendrive (1) boot (1) usb (1) prf (1) policia (2) federal (1) lucena (1) mongodb (4) paypal (1) payment (1) zend (1) vim (4) ciencia (6) js (1) nosql (1) java (1) JasperReports (1) phpjasper (1) covid19 (1) saude (1) athena (1) cinnamon (1) phpunit (2) binaural (1) mysqli (3) database (42) windows (6) vala (1) json (2) oracle (1) mariadb (4) dev (12) webdev (24) s3 (4) storage (1) kitematic (1) gnome (2) web (2) intel (3) piada (1) cron (2) dba (18) lumen (1) ffmpeg (2) android (2) aplicativo (1) fedora (2) shell (4) bash (3) script (3) lider (1) htm (1) csv (1) dropbox (1) db (3) combustivel (2) haru (1) presenter (1) gasolina (1) MeioAmbiente (1) Grunt (1) biologia (1) programming (22) performance (3) brain (1) smartphones (1) telefonia (1) privacidade (1) opensource (3) microg (1) iode (1) ssh (3) zsh (2) terminal (3) dracula (1) spaceship (1) mac (2) idiomas (1) laptop (2) developer (37) api (5) data (1) matematica (1) seguranca (2) 100DaysOfCode (9) hotfix (1) documentation (1) laravelphp (10) RabbitMQ (3) Elasticsearch (1) redis (2) Raspberry (4) Padrao de design (4) JQuery (1) angularjs (4) Dicas (43) Kubernetes (3) vscode (2) backup (1) angular (3) servers (2) pipelines (1) AppSec (1) DevSecOps (4) rust (1) RustLang (1) Mozilla (1) algoritimo (1) sqlite (1) Passport (2) jwt (5) security (2) translate (1) kube (2) iot (1) politica (2) bolsonaro (1) flow (1) podcast (1) Brasil (1) containers (3) traefik (1) networking (1) host (1) POO (2) microservices (2) bug (1) cqrs (1) arquitetura (3) Architecture (4) sail (3) militar (1) artigo (1) economia (1) forcas armadas (1) ffaa (1) autenticacao (2) autorizacao (2) authentication (4) authorization (3) NoCookies (1) wsl (4) memcached (1) macos (2) unix (2) kali-linux (1) linux-tools (5) apple (1) noticias (2) composer (1) rancher (1) k8s (1) escopos (1) orm (1) jenkins (4) github (5) gitlab (3) queue (1) Passwordless (1) sonarqube (1) phpswoole (1) laraveloctane (1) Swoole (1) Swoole (1) octane (1) Structurizr (1) Diagramas (1) c4 (1) c4-models (1) compactar (1) compression (1) messaging (1) restfull (1) eventdrive (1) services (1) http (1) Monolith (1) microservice (1) historia (1) educacao (1) cavalotroia (1) OOD (0) odd (1) chatgpt (1) openai (3) vicuna (1) llama (1) gpt (1) transformers (1) pytorch (1) tensorflow (1) akitando (1) ia (1) nvidia (1) agi (1) guard (1) multiple_authen (2) rpi (1) auth (1) auth (1) livros (2) ElonMusk (2) Oh My Zsh (1) Manjaro (1) BigLinux (2) ArchLinux (1) Migration (1) Error (1) Monitor (1) Filament (1) LaravelFilament (1) replication (1) phpfpm (1) cache (1) vpn (1) l2tp (1) zorin-os (1) optimization (1) scheduling (1) monitoring (2) linkedin (1) community (1) inteligencia-artificial (2) wsl2 (1) maps (1) API_KEY_GOOGLE_MAPS (1) repmgr (1) altadisponibilidade (1) banco (1) modelagemdedados (1) inteligenciadedados (4) governancadedados (1) bancodedados (2) Observability (1) picpay (1) ecommerce (1) Curisidades (1) Samurai (1) KubeCon (1) GitOps (1) Axios (1) Fetch (1) Deepin (1) vue (4) nuxt (1) PKCE (1) Oauth2 (2) webhook (1) TypeScript (1) tailwind (1) gource (2)

New Articles



Get Latest Updates by Email