refactoring of filters
This commit is contained in:
@@ -12,7 +12,6 @@
|
|||||||
export let inModal;
|
export let inModal;
|
||||||
export let modalUrl;
|
export let modalUrl;
|
||||||
export let graph;
|
export let graph;
|
||||||
|
|
||||||
let filter = {
|
let filter = {
|
||||||
label: "",
|
label: "",
|
||||||
operator: "",
|
operator: "",
|
||||||
@@ -58,9 +57,11 @@
|
|||||||
const filterRecord = extractFilterRecord(graph, value);
|
const filterRecord = extractFilterRecord(graph, value);
|
||||||
|
|
||||||
function extractFilterRecord(graph, value) {
|
function extractFilterRecord(graph, value) {
|
||||||
|
|
||||||
if (!filter.isReference) {
|
if (!filter.isReference) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
console.log(graph)
|
||||||
return graph.records.find(r => r.id === value);
|
return graph.records.find(r => r.id === value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,7 +83,7 @@
|
|||||||
{#if filter.isReference && filterRecord}
|
{#if filter.isReference && filterRecord}
|
||||||
{filter.label} is {previewTitle(channel.schemas, filterRecord)}
|
{filter.label} is {previewTitle(channel.schemas, filterRecord)}
|
||||||
{:else}
|
{:else}
|
||||||
{filter.label} {operators.find((o) => o.name === filter.operator)?.symbol ?? ""} {value}
|
{filter.label} {operators.find((o) => o.name === filter.operator)?.symbol ?? ""} {operators.find((o) => o.name === filter.operator)?.hasValue ? value : ""}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
export let inModal;
|
export let inModal;
|
||||||
export let modalUrl;
|
export let modalUrl;
|
||||||
|
|
||||||
|
|
||||||
let dropdown;
|
let dropdown;
|
||||||
let search = "";
|
let search = "";
|
||||||
let systemFieldsFiltered = systemFields;
|
let systemFieldsFiltered = systemFields;
|
||||||
@@ -70,6 +69,13 @@
|
|||||||
activeOperator = operators.find(o => o.name === "eq")
|
activeOperator = operators.find(o => o.name === "eq")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function selectOperator(e, operator) {
|
||||||
|
activeOperator = operator;
|
||||||
|
if (!operator.hasValue) {
|
||||||
|
applyFilter(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function applyFilter(e) {
|
function applyFilter(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
let filterPrefix = "";
|
let filterPrefix = "";
|
||||||
@@ -146,7 +152,7 @@
|
|||||||
<div class="selected-filter">field: {activeField.label}</div>
|
<div class="selected-filter">field: {activeField.label}</div>
|
||||||
|
|
||||||
{#each activeOperators as operator}
|
{#each activeOperators as operator}
|
||||||
<button class="dropdown-item button" on:click={e => activeOperator = operator }>
|
<button class="dropdown-item button" on:click={e => selectOperator(e,operator)}>
|
||||||
{operator.label}
|
{operator.label}
|
||||||
</button>
|
</button>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
<h2 class="mb-5">Enter Lucent</h2>
|
<h2 class="mb-5">Enter Lucent</h2>
|
||||||
|
|
||||||
<form hx-post="/lucent/login" >
|
<form hx-post="/lucent/login" >
|
||||||
|
@csrf
|
||||||
<p>Submit your email address and you will receive a <b>login link</b> to your email</p>
|
<p>Submit your email address and you will receive a <b>login link</b> to your email</p>
|
||||||
<p>Don't forget to check your spam folder</p>
|
<p>Don't forget to check your spam folder</p>
|
||||||
<div class="mt-5 mb-3">
|
<div class="mt-5 mb-3">
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use Lucent\Account\AccountService;
|
|||||||
use Lucent\Account\AuthService;
|
use Lucent\Account\AuthService;
|
||||||
use Lucent\Channel\ChannelService;
|
use Lucent\Channel\ChannelService;
|
||||||
use Lucent\LucentException;
|
use Lucent\LucentException;
|
||||||
use Lucent\Query\Operator;
|
use Lucent\Query\Operator\OperatorRegistry;
|
||||||
use Lucent\Query\Query;
|
use Lucent\Query\Query;
|
||||||
use Lucent\Record\InputData\EdgeInputData;
|
use Lucent\Record\InputData\EdgeInputData;
|
||||||
use Lucent\Record\InputData\RecordInputData;
|
use Lucent\Record\InputData\RecordInputData;
|
||||||
@@ -31,7 +31,8 @@ class RecordController extends Controller
|
|||||||
private readonly ChannelService $channelService,
|
private readonly ChannelService $channelService,
|
||||||
private readonly Svelte $svelte,
|
private readonly Svelte $svelte,
|
||||||
private readonly Query $query,
|
private readonly Query $query,
|
||||||
private readonly Manager $recordManager
|
private readonly Manager $recordManager,
|
||||||
|
private readonly OperatorRegistry $operatorRegistry
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -79,7 +80,6 @@ class RecordController extends Controller
|
|||||||
|
|
||||||
$records = $graph->getRootRecords()->toArray();
|
$records = $graph->getRootRecords()->toArray();
|
||||||
|
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
"schemas" => $this->channelService->channel->schemas,
|
"schemas" => $this->channelService->channel->schemas,
|
||||||
"schema" => $schema,
|
"schema" => $schema,
|
||||||
@@ -87,7 +87,7 @@ class RecordController extends Controller
|
|||||||
"records" => $records,
|
"records" => $records,
|
||||||
"graph" => toArray($graph),
|
"graph" => toArray($graph),
|
||||||
"systemFields" => array_values(System::list()),
|
"systemFields" => array_values(System::list()),
|
||||||
"operators" => array_values(Operator::list()),
|
"operators" => $this->operatorRegistry->all(),
|
||||||
"sortParam" => $sort,
|
"sortParam" => $sort,
|
||||||
"sortField" => $schema->fields->merge(array_values(System::list()))->firstWhere(fn($field) => $field->name === $sort || "-" . $field->name === $sort || "data." . $field->name === $sort || "-data." . $field->name === $sort),
|
"sortField" => $schema->fields->merge(array_values(System::list()))->firstWhere(fn($field) => $field->name === $sort || "-" . $field->name === $sort || "data." . $field->name === $sort || "-data." . $field->name === $sort),
|
||||||
"limit" => $limit,
|
"limit" => $limit,
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
class BuilderConverter
|
||||||
|
{
|
||||||
|
public function for(Argument $argument): IBuilderConverter
|
||||||
|
{
|
||||||
|
return new ($argument->operator->converter)($argument);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class Equals implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->where($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhere($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): string
|
||||||
|
{
|
||||||
|
return trim($this->argument->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class EqualsFalse implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->where($this->argument->field, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhere($this->argument->field, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class EqualsNumber implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
|
||||||
|
return $builder->where($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhere($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): int|float
|
||||||
|
{
|
||||||
|
$value = trim($this->argument->value);
|
||||||
|
return str_contains($value, ".") ? floatval($value) : intval($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class EqualsTrue implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->where($this->argument->field, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhere($this->argument->field, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class Exists implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereNot($this->argument->field, "")->whereNotNull($this->argument->field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereNot($this->argument->field, "")->whereNotNull($this->argument->field);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class Filter implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereJsonContains($this->argument->field, [$this->argument->value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereJsonContains($this->argument->field, [$this->argument->value]);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class GreaterThan implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
|
||||||
|
return $builder->where($this->argument->field, ">", $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhere($this->argument->field, ">", $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): int|float
|
||||||
|
{
|
||||||
|
$value = trim($this->argument->value);
|
||||||
|
if (is_numeric($value)) {
|
||||||
|
return str_contains($value, ".") ? floatval($value) : intval($value);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class GreaterThanEquals implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
|
||||||
|
return $builder->where($this->argument->field, ">=", $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhere($this->argument->field, ">=", $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): int|float
|
||||||
|
{
|
||||||
|
$value = trim($this->argument->value);
|
||||||
|
if (is_numeric($value)) {
|
||||||
|
return str_contains($value, ".") ? floatval($value) : intval($value);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
|
||||||
|
interface IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder;
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class In implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereIn($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereIn($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): array
|
||||||
|
{
|
||||||
|
$value = $this->argument->value;
|
||||||
|
if (is_string($value)) {
|
||||||
|
$value = explode(",", $value);
|
||||||
|
}
|
||||||
|
return array_map(fn($v) => trim($v), $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class InNum implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereIn($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereIn($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): array
|
||||||
|
{
|
||||||
|
$value = $this->argument->value;
|
||||||
|
if (is_string($value)) {
|
||||||
|
$value = explode(",", $value);
|
||||||
|
}
|
||||||
|
return array_map(fn($v) => $this->formatNumber($v), $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatNumber(string $value): float|int
|
||||||
|
{
|
||||||
|
$value = trim($value);
|
||||||
|
return str_contains($value, ".") ? floatval($value) : intval($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class IsNull implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereNull($this->argument->field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereNull($this->argument->field);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class LessThan implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
|
||||||
|
return $builder->where($this->argument->field, "<", $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhere($this->argument->field, "<", $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): int|float
|
||||||
|
{
|
||||||
|
$value = trim($this->argument->value);
|
||||||
|
if (is_numeric($value)) {
|
||||||
|
return str_contains($value, ".") ? floatval($value) : intval($value);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class LessThanEquals implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
|
||||||
|
return $builder->where($this->argument->field, "<=", $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhere($this->argument->field, "<=", $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): int|float
|
||||||
|
{
|
||||||
|
$value = trim($this->argument->value);
|
||||||
|
if (is_numeric($value)) {
|
||||||
|
return str_contains($value, ".") ? floatval($value) : intval($value);
|
||||||
|
}
|
||||||
|
return $value;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class NotEquals implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereNot($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereNot($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): string
|
||||||
|
{
|
||||||
|
return trim($this->argument->value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class NotEqualsFalse implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereNot($this->argument->field, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereNot($this->argument->field, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class NotEqualsNumber implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereNot($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereNot($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): int|float
|
||||||
|
{
|
||||||
|
$value = trim($this->argument->value);
|
||||||
|
return str_contains($value, ".") ? floatval($value) : intval($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class NotEqualsTrue implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereNot($this->argument->field, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereNot($this->argument->field, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class NotExists implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->where(fn($b) => $b->where($this->argument->field, "")->orWhereNull($this->argument->field));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhere(fn($b) => $b->where($this->argument->field, "")->orWhereNull($this->argument->field));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class NotIn implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereNotIn($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereNotIn($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): array
|
||||||
|
{
|
||||||
|
$value = $this->argument->value;
|
||||||
|
if (is_string($value)) {
|
||||||
|
$value = explode(",", $value);
|
||||||
|
}
|
||||||
|
return array_map(fn($v) => trim($v), $value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class NotInNum implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereNotIn($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereNotIn($this->argument->field, $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): array
|
||||||
|
{
|
||||||
|
$value = $this->argument->value;
|
||||||
|
if (is_string($value)) {
|
||||||
|
$value = explode(",", $value);
|
||||||
|
}
|
||||||
|
return array_map(fn($v) => $this->formatNumber($v), $value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatNumber(string $value): float|int
|
||||||
|
{
|
||||||
|
$value = trim($value);
|
||||||
|
return str_contains($value, ".") ? floatval($value) : intval($value);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class NotNull implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->whereNotNull($this->argument->field);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhereNotNull($this->argument->field);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\BuilderConverter;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder;
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
readonly class Regex implements IBuilderConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(private Argument $argument)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toAndQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
|
||||||
|
return $builder->where($this->argument->field, "like", $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function toOrQueryBuilder(Builder $builder): Builder
|
||||||
|
{
|
||||||
|
return $builder->orWhere($this->argument->field, "like", $this->formatValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private function formatValue(): string
|
||||||
|
{
|
||||||
|
return "%" . strtolower(trim($this->argument->value)) . "%";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,11 +2,15 @@
|
|||||||
|
|
||||||
namespace Lucent\Query\Filter;
|
namespace Lucent\Query\Filter;
|
||||||
|
|
||||||
|
use Lucent\Query\Operator\Operator;
|
||||||
|
|
||||||
class Argument
|
class Argument
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public string $field,
|
public string $field,
|
||||||
public string $operator,
|
public Operator $operator,
|
||||||
public mixed $value,
|
public mixed $value,
|
||||||
){}
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+16
-139
@@ -5,19 +5,26 @@ namespace Lucent\Query;
|
|||||||
use Illuminate\Contracts\Foundation\Application;
|
use Illuminate\Contracts\Foundation\Application;
|
||||||
use Illuminate\Database\Query\Builder;
|
use Illuminate\Database\Query\Builder;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Lucent\Query\BuilderConverter\BuilderConverter;
|
||||||
use Lucent\Query\Filter\AndFilter;
|
use Lucent\Query\Filter\AndFilter;
|
||||||
use Lucent\Query\Filter\Argument;
|
use Lucent\Query\Filter\Argument;
|
||||||
use Lucent\Query\Filter\Filter;
|
use Lucent\Query\Filter\Filter;
|
||||||
use Lucent\Query\Filter\OrFilter;
|
use Lucent\Query\Filter\OrFilter;
|
||||||
|
use Lucent\Query\Operator\In;
|
||||||
|
use Lucent\Query\Operator\OperatorDetector;
|
||||||
|
use function explode;
|
||||||
|
|
||||||
final class FilterParser
|
final class FilterParser
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct(public Application $app)
|
public function __construct(
|
||||||
|
public Application $app,
|
||||||
|
public BuilderConverter $builderConverter,
|
||||||
|
public OperatorDetector $operatorDetector,
|
||||||
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $arguments
|
* @param array $arguments
|
||||||
* @return array<Argument>
|
* @return array<Argument>
|
||||||
@@ -25,105 +32,11 @@ final class FilterParser
|
|||||||
private function formatArguments(array $arguments): array
|
private function formatArguments(array $arguments): array
|
||||||
{
|
{
|
||||||
return collect($arguments)->reduce(function ($c, $v, $k) {
|
return collect($arguments)->reduce(function ($c, $v, $k) {
|
||||||
$c[] = $this->formatArgument($v, $k);
|
$c[] = $this->operatorDetector->detect($v, $k);
|
||||||
return $c;
|
return $c;
|
||||||
}, []);
|
}, []);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function formatArgument(mixed $value, string $filter): Argument
|
|
||||||
{
|
|
||||||
|
|
||||||
$operator = $this->detectOperator($filter);
|
|
||||||
|
|
||||||
$field = $this->detectField($filter, $operator);
|
|
||||||
$formattedValue = match ($operator) {
|
|
||||||
"eq" => $this->formatText($value),
|
|
||||||
"ne" => $this->formatText($value),
|
|
||||||
"eqnum" => $this->formatNumber($value),
|
|
||||||
"nenum" => $this->formatNumber($value),
|
|
||||||
"object" => $this->formatText($value),
|
|
||||||
"in" => $this->formatListString($value),
|
|
||||||
"nin" => $this->formatListString($value),
|
|
||||||
"innum" => $this->formatListNum($value),
|
|
||||||
"ninnum" => $this->formatListNum($value),
|
|
||||||
"eqtrue" => true,
|
|
||||||
"eqfalse" => false,
|
|
||||||
"netrue" => true,
|
|
||||||
"nefalse" => false,
|
|
||||||
"regex" => "%" . strtolower($value) . "%",
|
|
||||||
"gt" => is_numeric($value) ? floatval($value) : $value,
|
|
||||||
"gte" => is_numeric($value) ? floatval($value) : $value,
|
|
||||||
"lt" => is_numeric($value) ? floatval($value) : $value,
|
|
||||||
"lte" => is_numeric($value) ? floatval($value) : $value,
|
|
||||||
"null" => null,
|
|
||||||
"nnull" => null,
|
|
||||||
"exists" => true,
|
|
||||||
"nexists" => false,
|
|
||||||
default => $value,
|
|
||||||
};
|
|
||||||
|
|
||||||
$matchedOperator = Operator::list()[$operator];
|
|
||||||
return new Argument(
|
|
||||||
field: str_replace(".", "->", $field),
|
|
||||||
operator: $matchedOperator->db,
|
|
||||||
value: $formattedValue
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function formatText(string $value): string
|
|
||||||
{
|
|
||||||
return trim($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function formatNumber(string $value): float
|
|
||||||
{
|
|
||||||
return floatval($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function formatListString(mixed $value): array
|
|
||||||
{
|
|
||||||
if (is_string($value)) {
|
|
||||||
$value = explode(",", $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_map(fn($v) => $this->formatText($v), $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function formatListNum(mixed $value): array
|
|
||||||
{
|
|
||||||
if (\is_string($value)) {
|
|
||||||
$value = explode(",", $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return \array_map(fn($v) => $this->formatNumber($v), $value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function detectOperator(string $filter): string
|
|
||||||
{
|
|
||||||
$exploded = \explode("_", $filter);
|
|
||||||
$candidate = end($exploded);
|
|
||||||
$operatorsListNames = collect(Operator::list())->map(fn($o) => $o->name)->toArray();
|
|
||||||
|
|
||||||
if (\in_array($candidate, $operatorsListNames)) {
|
|
||||||
return $candidate;
|
|
||||||
}
|
|
||||||
return 'eq';
|
|
||||||
}
|
|
||||||
|
|
||||||
private function detectField(string $filter, string $operator): string
|
|
||||||
{
|
|
||||||
|
|
||||||
$exploded = explode("_", $filter);
|
|
||||||
$candidate = array_pop($exploded);
|
|
||||||
if ($candidate === $operator) {
|
|
||||||
return implode("_", $exploded);
|
|
||||||
}
|
|
||||||
return $filter;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private function formatReferences(array $referenceArguments): Argument
|
private function formatReferences(array $referenceArguments): Argument
|
||||||
{
|
{
|
||||||
$subqueries = collect($referenceArguments)->reduce(function ($c, $v, $k) {
|
$subqueries = collect($referenceArguments)->reduce(function ($c, $v, $k) {
|
||||||
@@ -151,7 +64,7 @@ final class FilterParser
|
|||||||
|
|
||||||
return new Argument(
|
return new Argument(
|
||||||
field: "id",
|
field: "id",
|
||||||
operator: "in",
|
operator: In::make(),
|
||||||
value: $sourceIds
|
value: $sourceIds
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -174,7 +87,6 @@ final class FilterParser
|
|||||||
private function parseArguments(Filter $arguments): array
|
private function parseArguments(Filter $arguments): array
|
||||||
{
|
{
|
||||||
[$normalArguments, $referenceArguments] = $this->separateMainFromReferenceArguments($arguments);
|
[$normalArguments, $referenceArguments] = $this->separateMainFromReferenceArguments($arguments);
|
||||||
|
|
||||||
$formattedArguments = $this->formatArguments($normalArguments);
|
$formattedArguments = $this->formatArguments($normalArguments);
|
||||||
if (!empty($referenceArguments)) {
|
if (!empty($referenceArguments)) {
|
||||||
$formattedArguments[] = $this->formatReferences($referenceArguments);
|
$formattedArguments[] = $this->formatReferences($referenceArguments);
|
||||||
@@ -198,26 +110,8 @@ final class FilterParser
|
|||||||
*/
|
*/
|
||||||
private function parseAnd(Builder $builder, array $arguments): Builder
|
private function parseAnd(Builder $builder, array $arguments): Builder
|
||||||
{
|
{
|
||||||
foreach ($arguments as $argument) {
|
return collect($arguments)
|
||||||
if ($argument->operator == "in") {
|
->reduce(fn($cBuilder, Argument $arg) => $this->builderConverter->for($arg)->toAndQueryBuilder($cBuilder), $builder);
|
||||||
$builder->whereIn($argument->field, $argument->value);
|
|
||||||
} else if ($argument->operator == "nin") {
|
|
||||||
$builder->whereNotIn($argument->field, $argument->value);
|
|
||||||
} else if ($argument->operator == "exists") {
|
|
||||||
$builder->where($argument->field, "!=", "");
|
|
||||||
$builder->where($argument->field, "!=", null);
|
|
||||||
} elseif ($argument->operator == "filter") {
|
|
||||||
$builder->whereJsonContains($argument->field, [$argument->value]);
|
|
||||||
// target result
|
|
||||||
// filter[data.previousNames_object]=previousNames&filter[previousNames.name_eq]=alpha&filter[previousNames.id_eqnum]=24
|
|
||||||
// $query->whereJsonContains("data->previousNames", [["name" => "alpha", "id" => 24]]);
|
|
||||||
// $query->whereJsonContains($filter["field"], [$objectFilters]);
|
|
||||||
} else {
|
|
||||||
$builder->where($argument->field, $argument->operator, $argument->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $builder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -225,27 +119,10 @@ final class FilterParser
|
|||||||
*/
|
*/
|
||||||
private function parseOr(Builder $builder, array $arguments): Builder
|
private function parseOr(Builder $builder, array $arguments): Builder
|
||||||
{
|
{
|
||||||
$builder->where(function (Builder $orBuilder) use ($arguments) {
|
return $builder->where(function (Builder $orBuilder) use ($arguments) {
|
||||||
foreach ($arguments as $argument) {
|
return collect($arguments)
|
||||||
if ($argument->operator == "in") {
|
->reduce(fn($cBuilder, Argument $arg) => $this->builderConverter->for($arg)->toOrQueryBuilder($cBuilder), $orBuilder);
|
||||||
$orBuilder->orWhereIn($argument->field, $argument->value);
|
|
||||||
} else if ($argument->operator == "nin") {
|
|
||||||
$orBuilder->orWhereNotIn($argument->field, $argument->value);
|
|
||||||
} else if ($argument->operator == "exists") {
|
|
||||||
$orBuilder->where($argument->field, "!=", "");
|
|
||||||
$orBuilder->where($argument->field, "!=", null);
|
|
||||||
} elseif ($argument->operator == "filter") {
|
|
||||||
$orBuilder->whereJsonContains($argument->field, [$argument->value]);
|
|
||||||
// target result
|
|
||||||
// filter[data.previousNames_object]=previousNames&filter[previousNames.name_eq]=alpha&filter[previousNames.id_eqnum]=24
|
|
||||||
// $query->whereJsonContains("data->previousNames", [["name" => "alpha", "id" => 24]]);
|
|
||||||
// $query->whereJsonContains($filter["field"], [$objectFilters]);
|
|
||||||
} else {
|
|
||||||
$orBuilder->orWhere($argument->field, $argument->operator, $argument->value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
return $builder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,186 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Lucent\Query;
|
|
||||||
|
|
||||||
|
|
||||||
final class Operator
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @psalm-param string[] $uis
|
|
||||||
*/
|
|
||||||
public function __construct(
|
|
||||||
public string $name,
|
|
||||||
public string $label,
|
|
||||||
public string $symbol,
|
|
||||||
public string $db,
|
|
||||||
public array $uis,
|
|
||||||
)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array<string, Operator>
|
|
||||||
*/
|
|
||||||
public static function list(): array
|
|
||||||
{
|
|
||||||
|
|
||||||
return [
|
|
||||||
"regex" => new Operator(
|
|
||||||
name: "regex",
|
|
||||||
label: "Search",
|
|
||||||
symbol: "~",
|
|
||||||
db: 'like',
|
|
||||||
uis: ["id", "text", "textarea", "url", "color", "date", "datetime"],
|
|
||||||
),
|
|
||||||
"eq" => new Operator(
|
|
||||||
name: "eq",
|
|
||||||
label: "Equals",
|
|
||||||
symbol: "is",
|
|
||||||
db: '=',
|
|
||||||
uis: ["id", "text", "textarea", "url", "color", "date", "datetime", "reference"],
|
|
||||||
),
|
|
||||||
"ne" => new Operator(
|
|
||||||
name: "ne",
|
|
||||||
label: "Not Equals",
|
|
||||||
symbol: "is not",
|
|
||||||
db: '!=',
|
|
||||||
uis: ["id", "text", "textarea", "url", "color", "date", "datetime"],
|
|
||||||
),
|
|
||||||
"eqnum" => new Operator(
|
|
||||||
name: "eqnum",
|
|
||||||
label: "Equals number",
|
|
||||||
symbol: "is",
|
|
||||||
db: '=',
|
|
||||||
uis: ["number"],
|
|
||||||
),
|
|
||||||
"neqnum" => new Operator(
|
|
||||||
name: "nenum",
|
|
||||||
label: "Not Equals number",
|
|
||||||
symbol: "is not",
|
|
||||||
db: '$ne',
|
|
||||||
uis: ["number"],
|
|
||||||
),
|
|
||||||
"filter" => new Operator(
|
|
||||||
name: "filter",
|
|
||||||
label: "Equals Object",
|
|
||||||
symbol: "is",
|
|
||||||
db: 'filter',
|
|
||||||
uis: [],
|
|
||||||
),
|
|
||||||
"eqtrue" => new Operator(
|
|
||||||
name: "eqtrue",
|
|
||||||
label: "Equals true",
|
|
||||||
symbol: "is",
|
|
||||||
db: '=',
|
|
||||||
uis: ["checkbox"],
|
|
||||||
),
|
|
||||||
"eqfalse" => new Operator(
|
|
||||||
name: "eqfalse",
|
|
||||||
label: "Equals false",
|
|
||||||
symbol: "is not",
|
|
||||||
db: '=',
|
|
||||||
uis: ["checkbox"],
|
|
||||||
),
|
|
||||||
"netrue" => new Operator(
|
|
||||||
name: "netrue",
|
|
||||||
label: "Not equals true",
|
|
||||||
symbol: "!=",
|
|
||||||
db: '$ne',
|
|
||||||
uis: ["checkbox"],
|
|
||||||
),
|
|
||||||
"nefalse" => new Operator(
|
|
||||||
name: "nefalse",
|
|
||||||
label: "Not equals false",
|
|
||||||
symbol: "!=",
|
|
||||||
db: '$ne',
|
|
||||||
uis: ["checkbox"],
|
|
||||||
),
|
|
||||||
"in" => new Operator(
|
|
||||||
name: "in",
|
|
||||||
label: "In list",
|
|
||||||
symbol: "in",
|
|
||||||
db: 'in',
|
|
||||||
uis: ["id", "text", "textarea", "url", "color", "date", "datetime"],
|
|
||||||
),
|
|
||||||
"innum" => new Operator(
|
|
||||||
name: "innum",
|
|
||||||
label: "In list of numbers",
|
|
||||||
symbol: "in",
|
|
||||||
db: '$in',
|
|
||||||
uis: ["number"],
|
|
||||||
),
|
|
||||||
"nin" => new Operator(
|
|
||||||
name: "nin",
|
|
||||||
label: "Not in list",
|
|
||||||
symbol: "not in",
|
|
||||||
db: 'nin',
|
|
||||||
uis: ["id", "text", "textarea", "url", "color", "date", "datetime"],
|
|
||||||
),
|
|
||||||
"ninnum" => new Operator(
|
|
||||||
name: "ninnum",
|
|
||||||
label: "Not In list of numbers",
|
|
||||||
symbol: "not in",
|
|
||||||
db: '$nin',
|
|
||||||
uis: ["number"],
|
|
||||||
),
|
|
||||||
"lt" => new Operator(
|
|
||||||
name: "lt",
|
|
||||||
label: "Less than",
|
|
||||||
symbol: "<",
|
|
||||||
db: '<',
|
|
||||||
uis: ["number", "date", "datetime"],
|
|
||||||
),
|
|
||||||
"lte" => new Operator(
|
|
||||||
name: "lte",
|
|
||||||
label: "Less than equals",
|
|
||||||
symbol: "<=",
|
|
||||||
db: '<=',
|
|
||||||
uis: ["number", "date", "datetime"],
|
|
||||||
),
|
|
||||||
"gt" => new Operator(
|
|
||||||
name: "gt",
|
|
||||||
label: "Greater than",
|
|
||||||
symbol: ">",
|
|
||||||
db: '>',
|
|
||||||
uis: ["number", "date", "datetime"],
|
|
||||||
),
|
|
||||||
"gte" => new Operator(
|
|
||||||
name: "gte",
|
|
||||||
label: "Greater than equals",
|
|
||||||
symbol: ">=",
|
|
||||||
db: '>=',
|
|
||||||
uis: ["number", "date", "datetime"],
|
|
||||||
),
|
|
||||||
"null" => new Operator(
|
|
||||||
name: "null",
|
|
||||||
label: "Is null",
|
|
||||||
symbol: "=",
|
|
||||||
db: '$eq',
|
|
||||||
uis: ["*"],
|
|
||||||
),
|
|
||||||
"nnull" => new Operator(
|
|
||||||
name: "nnull",
|
|
||||||
label: "Not null",
|
|
||||||
symbol: "!=",
|
|
||||||
db: '$ne',
|
|
||||||
uis: ["*"],
|
|
||||||
),
|
|
||||||
"exists" => new Operator(
|
|
||||||
name: "exists",
|
|
||||||
label: "Exists",
|
|
||||||
symbol: "exists",
|
|
||||||
db: 'exists',
|
|
||||||
uis: ["*"],
|
|
||||||
),
|
|
||||||
"nexists" => new Operator(
|
|
||||||
name: "nexists",
|
|
||||||
label: "Not exists",
|
|
||||||
symbol: "not exists",
|
|
||||||
db: '$exists',
|
|
||||||
uis: ["*"],
|
|
||||||
),
|
|
||||||
|
|
||||||
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class Equals extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "eq";
|
||||||
|
public string $label = "Equals";
|
||||||
|
public string $symbol = "is";
|
||||||
|
public array $uis = ["id", "text", "textarea", "url", "color", "date", "datetime", "reference"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\Equals::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class EqualsFalse extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "eqfalse";
|
||||||
|
public string $label = "Equals False";
|
||||||
|
public string $symbol = "is";
|
||||||
|
public array $uis = ["checkbox"];
|
||||||
|
public bool $hasValue = false;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\EqualsFalse::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class EqualsNumber extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "eqnum";
|
||||||
|
public string $label = "Equals Number";
|
||||||
|
public string $symbol = "is";
|
||||||
|
public array $uis = ["number"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\EqualsNumber::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class EqualsTrue extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "eqtrue";
|
||||||
|
public string $label = "Equals True";
|
||||||
|
public string $symbol = "is";
|
||||||
|
public array $uis = ["checkbox"];
|
||||||
|
public bool $hasValue = false;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\EqualsTrue::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class Exists extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "exists";
|
||||||
|
public string $label = "Exists";
|
||||||
|
public string $symbol = "exists";
|
||||||
|
public array $uis = ["*"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\Exists::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class Filter extends Operator
|
||||||
|
{
|
||||||
|
public string $name = "filter";
|
||||||
|
public string $label = "Equals Object";
|
||||||
|
public string $symbol = "is";
|
||||||
|
public array $uis = [];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\Filter::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class GreaterThan extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "gt";
|
||||||
|
public string $label = "Greater than";
|
||||||
|
public string $symbol = ">";
|
||||||
|
public array $uis = ["number", "date", "datetime"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\GreaterThan::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class GreaterThanEquals extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "gte";
|
||||||
|
public string $label = "Greater than equals";
|
||||||
|
public string $symbol = ">";
|
||||||
|
public array $uis = ["number", "date", "datetime"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\GreaterThanEquals::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class In extends Operator
|
||||||
|
{
|
||||||
|
public string $name = "in";
|
||||||
|
public string $label = "In list";
|
||||||
|
public string $symbol = "in";
|
||||||
|
public array $uis = ["id", "text", "textarea", "url", "color", "date", "datetime"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\In::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class InNum extends Operator
|
||||||
|
{
|
||||||
|
public string $name = "innum";
|
||||||
|
public string $label = "In number list";
|
||||||
|
public string $symbol = "in";
|
||||||
|
public array $uis = ["number"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\NotInNum::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class IsNull extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "null";
|
||||||
|
public string $label = "Is Null";
|
||||||
|
public string $symbol = "is null";
|
||||||
|
public array $uis = ["*"];
|
||||||
|
public bool $hasValue = false;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\IsNull::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class LessThan extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "lt";
|
||||||
|
public string $label = "Less than";
|
||||||
|
public string $symbol = ">";
|
||||||
|
public array $uis = ["number", "date", "datetime"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\LessThan::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class LessThanEquals extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "lte";
|
||||||
|
public string $label = "Less than equals";
|
||||||
|
public string $symbol = ">";
|
||||||
|
public array $uis = ["number", "date", "datetime"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\LessThanEquals::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class NotEquals extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "ne";
|
||||||
|
public string $label = "Not Equals";
|
||||||
|
public string $symbol = "is not";
|
||||||
|
public array $uis = ["id", "text", "textarea", "url", "color", "date", "datetime", "reference"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\NotEquals::class;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class NotEqualsFalse extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "nefalse";
|
||||||
|
public string $label = "Not Equals False";
|
||||||
|
public string $symbol = "is";
|
||||||
|
public array $uis = ["checkbox"];
|
||||||
|
public bool $hasValue = false;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\NotEqualsFalse::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class NotEqualsNumber extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "neqnum";
|
||||||
|
public string $label = "Not Equals Number";
|
||||||
|
public string $symbol = "is";
|
||||||
|
public array $uis = ["number"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\NotEqualsNumber::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class NotEqualsTrue extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "netrue";
|
||||||
|
public string $label = "Not Equals True";
|
||||||
|
public string $symbol = "is";
|
||||||
|
public array $uis = ["checkbox"];
|
||||||
|
public bool $hasValue = false;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\NotEqualsTrue::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class NotExists extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "nexists";
|
||||||
|
public string $label = "Not Exists";
|
||||||
|
public string $symbol = "not exists";
|
||||||
|
public array $uis = ["*"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\NotExists::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class NotIn extends Operator
|
||||||
|
{
|
||||||
|
public string $name = "nin";
|
||||||
|
public string $label = "Not in list";
|
||||||
|
public string $symbol = "in";
|
||||||
|
public array $uis = ["id", "text", "textarea", "url", "color", "date", "datetime"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\NotIn::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class NotInNum extends Operator
|
||||||
|
{
|
||||||
|
public string $name = "ninnum";
|
||||||
|
public string $label = "Not in number list";
|
||||||
|
public string $symbol = "not in";
|
||||||
|
public array $uis = ["number"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\InNum::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class NotNull extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "nnull";
|
||||||
|
public string $label = "Is not Null";
|
||||||
|
public string $symbol = "is not null";
|
||||||
|
public array $uis = ["*"];
|
||||||
|
public bool $hasValue = false;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\NotNull::class;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
|
||||||
|
abstract class Operator
|
||||||
|
{
|
||||||
|
public string $name;
|
||||||
|
public string $label;
|
||||||
|
public string $symbol;
|
||||||
|
public array $uis;
|
||||||
|
public bool $hasValue;
|
||||||
|
/**
|
||||||
|
* @var class-string
|
||||||
|
*/
|
||||||
|
public string $converter;
|
||||||
|
|
||||||
|
public static function make(): Operator
|
||||||
|
{
|
||||||
|
return new static();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
use Lucent\Query\Filter\Argument;
|
||||||
|
|
||||||
|
class OperatorDetector
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public OperatorRegistry $operatorRegistry
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function detect(mixed $value, string $filter): Argument
|
||||||
|
{
|
||||||
|
$operator = $this->detectOperator($filter);
|
||||||
|
$field = $this->detectField($filter, $operator->name);
|
||||||
|
return new Argument(
|
||||||
|
field: str_replace(".", "->", $field),
|
||||||
|
operator: $operator,
|
||||||
|
value: $value
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function detectOperator(string $filter): Operator
|
||||||
|
{
|
||||||
|
$exploded = explode("_", $filter);
|
||||||
|
$candidate = end($exploded);
|
||||||
|
return $this->operatorRegistry->matchByName($candidate);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function detectField(string $filter, string $operator): string
|
||||||
|
{
|
||||||
|
$exploded = explode("_", $filter);
|
||||||
|
$candidate = array_pop($exploded);
|
||||||
|
if ($candidate === $operator) {
|
||||||
|
return implode("_", $exploded);
|
||||||
|
}
|
||||||
|
return $filter;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
|
||||||
|
final class OperatorRegistry
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @return list<Operator>
|
||||||
|
*/
|
||||||
|
public function all(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
new Equals(),
|
||||||
|
new NotEquals(),
|
||||||
|
new EqualsNumber(),
|
||||||
|
new NotEqualsNumber(),
|
||||||
|
new EqualsTrue(),
|
||||||
|
new EqualsFalse(),
|
||||||
|
new NotEqualsFalse(),
|
||||||
|
new NotEqualsTrue(),
|
||||||
|
new Regex(),
|
||||||
|
new In(),
|
||||||
|
new NotIn(),
|
||||||
|
new InNum(),
|
||||||
|
new NotInNum(),
|
||||||
|
new GreaterThan(),
|
||||||
|
new GreaterThanEquals(),
|
||||||
|
new LessThan(),
|
||||||
|
new LessThanEquals(),
|
||||||
|
new IsNull(),
|
||||||
|
new NotNull(),
|
||||||
|
new Exists(),
|
||||||
|
new NotExists(),
|
||||||
|
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function matchByName(string $name): Operator
|
||||||
|
{
|
||||||
|
$operator = collect($this->all())->where('name', $name)->first();
|
||||||
|
if (empty($operator)) {
|
||||||
|
return new Equals();
|
||||||
|
}
|
||||||
|
return $operator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Operator;
|
||||||
|
|
||||||
|
class Regex extends Operator
|
||||||
|
{
|
||||||
|
|
||||||
|
public string $name = "regex";
|
||||||
|
public string $label = "Search";
|
||||||
|
public string $symbol = "~";
|
||||||
|
public array $uis = ["id", "text", "textarea", "url", "color", "date", "datetime"];
|
||||||
|
public bool $hasValue = true;
|
||||||
|
public string $converter = \Lucent\Query\BuilderConverter\Regex::class;
|
||||||
|
|
||||||
|
}
|
||||||
+2
-3
@@ -161,7 +161,7 @@ final class Query
|
|||||||
|
|
||||||
private function findNotLinked(Builder $query): Builder
|
private function findNotLinked(Builder $query): Builder
|
||||||
{
|
{
|
||||||
if(empty($this->options->notLinked)){
|
if (empty($this->options->notLinked)) {
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,8 +169,7 @@ final class Query
|
|||||||
$query
|
$query
|
||||||
->select("records.*")
|
->select("records.*")
|
||||||
->join('edges', 'records.id', '=', 'edges.target', 'left outer')
|
->join('edges', 'records.id', '=', 'edges.target', 'left outer')
|
||||||
->whereNull("edges.target")
|
->whereNull("edges.target");
|
||||||
;
|
|
||||||
return $query;
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user