paulo-leo / laravel-qjs
Descrição do seu pacote
Installs: 20
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/paulo-leo/laravel-qjs
This package is auto-updated.
Last update: 2025-12-25 23:21:34 UTC
README
O Laravel QJS é um pacote PHP desenvolvido especificamente para aplicações Laravel, mas também é compatível com o Lumen. Ele oferece uma maneira eficiente e intuitiva de gerar relatórios usando uma linguagem baseada na estrutura JSON.
Introdução ao QJS: Uma Linguagem Declarativa para Geração Dinâmica de Relatórios
O QJS é uma linguagem declarativa que pode ser escrita tanto em JSON quanto em arrays associativos do PHP. Desenvolvida por Paulo Leonardo Da S. Cassimiro, sua principal finalidade é resolver o desafio recorrente de geração de relatórios. A criação de relatórios é uma tarefa altamente dinâmica, cuja complexidade varia de acordo com o cenário específico. A proposta por trás dessa linguagem é permitir o armazenamento de instruções para a renderização de relatórios em arquivos de texto ou campos de banco de dados, podendo ser chamados em tempo real.
A ideia de construir o QJS usando o formato JSON foi inspirada no uso de estados de componentes em aplicações reativas, como React, Vue, Angular, entre outras. Isso possibilita a construção de relatórios em tempo real, dependendo da implementação. As instruções da linguagem seguem as mesmas regras do SQL comum, com a diferença de que as declarações não precisam seguir uma ordem específica, sendo o único campo obrigatório o from, enquanto os demais refinam o seu relatório.
Em resumo, o QJS pode ser considerado um protocolo para a criação de relatórios baseados em estados JSON.
Uma consulta QJS pode ser interpretada da seguinte maneira:
{
"from":"categories",
"where":"created_at,between,$nowsub:30;$now"
}
Nesta consulta, especificamos que um relatório será gerado para todas as categorias (from) do sistema, onde (where) as categorias foram criadas (created_at) dentro do intervalo (between) dos últimos 30 dias até a data atual ($nowsub:30;$now). Os placeholders $nowsub e $now são métodos avançados de data que podem ser utilizados em qualquer filtro, exceto nos operadores in e !in. O prefixo $ indica o uso de um comando interno.
Recursos
-
Sintaxe Simples: A estrutura de uma consulta QJS é simples e não requer uma ordem específica para os comandos.
-
Flexibilidade: O comando "from" é o único obrigatório para gerar um relatório básico, mas é possível realizar relacionamentos entre entidades do esquema do banco de dados, executar agregações e subconsultas nas linhas e utilizar comandos avançados de datas nos filtros dos relatórios.
-
Facilidade de Uso: A estrutura do QJS pode ser facilmente salva em uma string e executada diretamente a partir de uma tabela de relatórios.
-
Simplificação de Relatórios Complexos: Uma das maiores motivações para o desenvolvimento deste recurso é a simplificação de relatórios complexos, tornando o processo mais ágil e eficiente.
-
Conversão Nativa: O QJS oferece suporte nativo para a conversão dos relatórios gerados em tabelas HTML e XLS.
Instalação via composer:
composer require paulo-leo/laravel-qjs:dev-main
Exemplo de uso
<?php namespace App\Http\Controllers; use PauloLeo\LaravelQJS\QJS; class ReportController extends Controller{ public function render(Request $request){ $qjs = new QJS; $query = $request->all(); $report = $qjs->render($query); if($report->render){ response()->json($report->data,200); }else{ response()->json($report,422); } } }
Convertendo em XLS(Excel) ou HTML
<?php namespace App\Http\Controllers; use PauloLeo\LaravelQJS\QJS; public function render(Request $request){ $qjs = new QJS; $query = $request->all(); $report = $qjs->render($query); if($request->type == 'xls' && $report->render) return $qjs->toXLS($report->data); if($request->type == 'html' && $report->render) return $qjs->toHTML($report->data); return response()->json($report); } }
O método render é o núcleo da classe, responsável por processar a consulta que pode ser especificada em formato JSON ou como um array associativo. Seu primeiro parâmetro é a própria consulta, enquanto o segundo refere-se aos filtros aplicados. Esses filtros podem ser passados como um array associativo ou como uma string em formato JSON.
O método render sempre retorna um objeto contendo a chave render, a qual pode assumir os valores true ou false. Quando true, indica que a renderização do relatório foi bem-sucedida, devolvendo, então, a chave data contendo os dados do relatório. Esses dados são organizados como um array indexado, onde cada índice contém um objeto com as informações a serem apresentadas no relatório.
Aqui está um exemplo de uso:
$query = array( "from" => "users" ); $filter = array( array("name", "!=", "Carlos") ); $qjs = new QJS; return response()->json($qjs->render($query, $filter));
Guia QJS
Listar todos os usuários do sistema:
{
"from": "users"
}
Listar todos os usuários e trazer somente os campos id e name:
{
"from": "users",
"rows": "id, name"
}
Listar todos os usuários e trazer somente os campos id e name e renomeia o campo name para cliente:
{
"from": "users",
"rows": "id, name as cliente"
}
Listar todos os usuários, trazendo apenas os campos id e name, e contar quantos existem:
{
"from": "users",
"rows": "id, name, $count(*) as total",
"group":"id,name"
}
Observação: Sempre que executar uma subconsulta, adicione o caractere $ antes do comando SQL ou da função de agregação desejada. O $ indica que você está realizando uma subconsulta ou uma função de agregação. Além disso, ao utilizar uma subconsulta com campos não agregados, é importante incluir o comando group e passar os campos não agregados nele para garantir que o resultado seja agrupado corretamente. No entanto, no exemplo abaixo, não é necessário usar o comando group, pois as regras do SQL se aplicam aqui:
{
"from": "users",
"rows": "$count(*) as total"
}
Você pode usar a declaração where para aplicar filtros ao seu relatórios:
{
"from": "users",
"rows": "id, name",
"where":"id,10"
}
O comando acima busca o usuário ao qual o id é igual a "10", quando é omitido o operador, query considera como igual "=". Se você quiser passar um operador, você deverá escrever da seguinte maneira:
{
"from": "users",
"rows": "id, name",
"where":"id,!=,10"
}
Para passar mais de um filtro, você pode escrever da seguinte forma:
{
"from": "users",
"rows": "id, name",
"where":[
["id",">","1"],
["name","like","a%"]
]
}
Para passar mais de um filtro, você pode escrever da seguinte forma:
{
"from": "users",
"rows": "id, name",
"where":[
["id", ">", "1"],
["name", "like", "a%"]
]
}
O mesmo código pode ser escrito assim:
{
"from": "users",
"rows": "id, name",
"where":["id,>,1","name,like,a%"]
}
Se desejar passar um operador OR após o primeiro filtro, basta adicionar um quarto valor no filtro, um booleano true indicando que será aplicado o operador OR:
{
"from": "users",
"rows": "id, name",
"where":[
["id",">","1"],
["name","like","a%",true]]
}
Além disso, você pode usar os seguintes operadores para lidar com intervalos, valores nulos e listagem: Para intervalos entre dois valores, utilize o operador between:
{
"from": "users",
"rows": "id, name",
"where":[
["id","between","1|10"]
]
}
Para valores nulos:
{
"from": "users",
"rows": "id, name",
"where":[
["id","null"]
]
}
Para uma lista de valores:
{
"from": "users",
"rows": "id, name",
"where":[
["id","in",[1,2,3]]
]
}
Se desejar negar a busca utilizando esses operadores, basta adicionar o caractere ! na frente do operador between, null e in:
{
"from": "users",
"rows": "id, name",
"where":[
["id","!null"],
["id","!in",[1,2,3]],
["id","!between","1|10"]
]
}
Agora, se você declarou um método de agregação na row e deseja filtrar a agregação, pode usar a declaração having da seguinte forma:
{
"from": "users",
"rows": "id, name, $count(*) as total",
"group": "id, name",
"having": [
["total", ">", "10"]
]
}
Você também pode ordenar o seu relatório utilizando a declaração order. Aqui estão dois exemplos de como fazer isso: Ordenar por uma coluna em ordem descendente:
{
"from": "users",
"order": "id,desc"
}
Ordenar por múltiplas colunas, onde a primeira é ordenada em ordem descendente e a segunda em ordem ascendente:
{
"from": "users",
"order": ["id,desc","name"]
}
A funcionalidade de junção de entidades no QJS assemelha-se aos JOINS do SQL, utilizando três métodos fundamentais. Com base na teoria dos conjuntos, é possível empregar os métodos "join" para uma junção total, quando há referência entre as duas entidades; "left", quando a prioridade é dada à tabela à esquerda; e "right", quando a prioridade é atribuída à tabela à direita.
{
"from": "users",
"rows":"users.id,users.name,categories.name as category",
"join":"categories,categories.id,users.category_id"
}
Para realizar múltiplas junções, segue-se a seguinte sintaxe:
{
"from": "users",
"rows": "users.id, users.name, categories.name as category",
"left": [
"categories, categories.id, users.category_id",
"drivers, drivers.id, users.driver_id"
]
}
Alternativamente, pode-se utilizar a seguinte estrutura:
{
"from": "users",
"rows": "users.id, users.name, categories.name as category",
"left": [
["categories", "categories.id", "users.category_id"],
["drivers", "drivers.id", "users.driver_id"]
]
}