Query Engine¶
O MIDDAG possui um query engine com query builder imutavel. Toda chamada retorna uma nova instancia, preservando a query original.
Query básica¶
use local_middag\facade\query_executor;
use local_middag\facade\query_builder;
use local_middag\framework\shared\enum\operator;
$query = query_builder::make()
->domain(\local_meuplugin\extensions\catalogo\item_catalogo::class)
->where('status', operator::EQ, 'active');
$result = search_executor::execute($query);
foreach ($result as $item) {
echo $item->get_id();
}
Operadores¶
| Operador | SQL | Uso |
|---|---|---|
operator::EQ |
= |
Igualdade |
operator::NEQ |
<> |
Diferente |
operator::GT |
> |
Maior que |
operator::GTE |
>= |
Maior ou igual |
operator::LT |
< |
Menor que |
operator::LTE |
<= |
Menor ou igual |
operator::LIKE |
LIKE |
Pattern matching (%valor%) |
operator::IN |
IN |
Pertence a lista |
operator::NOT_IN |
NOT IN |
Não pertence a lista |
operator::BETWEEN |
BETWEEN |
Dentro de faixa (inclusive) |
operator::IS |
IS |
Comparacao com NULL |
operator::IS_NOT |
IS NOT |
Comparacao negada com NULL |
Paginacao¶
$query = query_builder::make()
->domain(\local_meuplugin\extensions\catalogo\item_catalogo::class)
->where('status', operator::EQ, 'active')
->paginate(page: 1, per_page: 20);
$result = search_executor::execute($query);
$result->items(); // Itens da página atual.
$result->total(); // Total de registros (ignora páginação).
$result->page(); // Página atual.
$result->perpage(); // Itens por página.
$result->pages(); // Total de páginas.
$result->count(); // Quantidade de itens nesta página.
$result->is_empty(); // Nenhum resultado?
$result->first(); // Primeiro item ou null.
$result->last(); // Ultimo item ou null.
O result implementa Countable e IteratorAggregate. Use diretamente em foreach.
Ordenacao¶
$query = query_builder::make()
->domain(\local_meuplugin\extensions\catalogo\item_catalogo::class)
->order_by('timecreated DESC');
O parametro é uma string SQL raw: 'campo ASC' ou 'campo DESC'.
Metadata¶
Filtre por campos de metadata (tabela auxiliar):
$query = query_builder::make()
->domain(\local_meuplugin\extensions\catalogo\item_catalogo::class)
->where_meta('cor', operator::EQ, 'azul')
->where_meta_in('tamanho', ['P', 'M', 'G']);
Para carregar metadata nos resultados (eager loading):
$query = query_builder::make()
->domain(\local_meuplugin\extensions\catalogo\item_catalogo::class)
->with_metadata(['cor', 'tamanho', 'peso']);
Global scopes¶
Global scopes são filtros automaticos aplicados a toda query (multi-tenancy, soft deletes, etc.).
Criar um global scope¶
namespace local_meuplugin\extensions\catalogo;
use local_middag\base\global_scope;
use local_middag\framework\infrastructure\query_engine\query_builder_interface;
class active_items_scope extends global_scope
{
public function apply(query_builder_interface $builder): query_builder_interface
{
return $builder->where('status', \local_middag\framework\shared\enum\operator::EQ, 'active');
}
public function should_apply(): bool
{
return true;
}
}
Ignorar scopes em uma query específica¶
// Ignorar um scope específico.
$query = query_builder::make()
->without_global_scope('active_items');
// Ignorar todos os global scopes.
$query = query_builder::make()
->without_global_scopes();
Atalhos de filtragem¶
// IN / NOT IN
$query = query_builder::make()
->where_in('type', ['article', 'page'])
->where_not_in('status', ['deleted', 'archived']);
// BETWEEN
$query = query_builder::make()
->where_between('timecreated', $start_timestamp, $end_timestamp);
// LIMIT sem páginação
$query = query_builder::make()
->limit(10);
Joins¶
$query = query_builder::make()
->domain(\local_meuplugin\extensions\catalogo\item_catalogo::class)
->join_course('c')
->join_user('u')
->where('c.visible', operator::EQ, 1);
Joins disponiveis:
| Metodo | Tabela |
|---|---|
join_item($alias) |
middag_items |
join_course($alias) |
course |
join_user($alias) |
user |
join($table, $alias, $on, $type) |
Qualquer tabela |
Relations (eager loading)¶
$query = query_builder::make()
->domain(\local_meuplugin\extensions\catalogo\item_catalogo::class)
->with_relation('author')
->with_relation('category');
Relations são registradas pela extension e resolvidas automaticamente pelo query engine.
Select específico¶
$query = query_builder::make()
->domain(\local_meuplugin\extensions\catalogo\item_catalogo::class)
->select(['id', 'fullname', 'status']);
Resultados como stdClass¶
Por padrão, resultados são hidratados como entities do dominio. Para receber stdClass raw:
$query = query_builder::make()
->domain(\local_meuplugin\extensions\catalogo\item_catalogo::class)
->as_std_class();
Query completa¶
Exemplo combinando multiplas condicoes:
use local_middag\facade\query_executor;
use local_middag\facade\query_builder;
use local_middag\framework\shared\enum\operator;
$query = query_builder::make()
->domain(\local_meuplugin\extensions\catalogo\item_catalogo::class)
->where('status', operator::EQ, 'active')
->where('timecreated', operator::GTE, $desde_timestamp)
->where_in('type', ['article', 'page'])
->where_meta('featured', operator::EQ, '1')
->with_metadata(['cor', 'tamanho'])
->with_relation('author')
->join_course('c')
->where('c.visible', operator::EQ, 1)
->order_by('timecreated DESC')
->paginate(page: 1, per_page: 20);
$result = search_executor::execute($query);
echo "Total: {$result->total()}, Paginas: {$result->pages()}";
foreach ($result as $item) {
echo $item->get_id() . ' - ' . $item->get_fullname();
}