This commit is contained in:
2023-10-13 21:06:23 +03:00
parent 129e3af471
commit 9e37a7f730
34 changed files with 845 additions and 780 deletions
+7 -5
View File
@@ -158,7 +158,7 @@ class RecordController extends Controller
public function newInline(Request $request)
{
$schema = $this->channelService->getSchema($request->input("schema"));
$schema = $this->channelService->getSchema($request->input("schema"))->get();
$record = $this->recordService->createEmpty($schema);
$queryRecord = QueryRecord::fromRecord($record);
@@ -221,12 +221,14 @@ class RecordController extends Controller
->limit(1)
->childrenDepth(2)
->parentsDepth(1)
->tree();
->run();
$record = $graph->records->first();
return ok(
[
"graph" => $graph->toArray(),
"record" => $graph->first()->toArray(),
"graph" => toArray($graph),
"record" => toArray($record)
]
);
}
@@ -287,7 +289,7 @@ class RecordController extends Controller
$newGraph = $this->query
->filter(["id" => $recordId])
->limit(10)
->childrenDepth(2)
->childrenDepth(1)
->parentsDepth(1)
->run();
-185
View File
@@ -1,185 +0,0 @@
<?php
namespace Lucent\Query;
use Illuminate\Support\Facades\DB;
final class Filter
{
private array $operatorsList;
public function __construct(
public array $arguments = [],
)
{
}
public function add(array $arguments): Filter
{
$this->arguments = $arguments;
return $this;
}
private function formatArguments(array $arguments): array
{
return (array)collect($arguments)->reduce(fn($c, $v, $k) => $this->formatArgument($c, $v, $k), []);
}
private function formatArgument(array $arguments, mixed $value, string $filter): array
{
$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" => "%{$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 = $this->operatorsList[$operator];
$arguments[] = [
"field" => str_replace(".", "->", $field),
"operator" => $matchedOperator->db,
"value" => $formattedValue
];
return $arguments;
}
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($this->operatorsList)->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(Query $query): array
{
[$arguments, $referenceArguments] = $this->separateMainFromReferenceArguments();
if (empty($referenceArguments)) {
return [$arguments, []];
};
$subqueries = collect($referenceArguments)->reduce(function ($c, $v, $k) {
$keyWithoutRef = str_replace("children.", "", $k);
[$field] = explode(".", $keyWithoutRef);
$referenceField = str_replace($field . ".", "", $keyWithoutRef);
$c[$field][$referenceField] = $v;
return $c;
}, []);
$sourceIds = collect($subqueries)->reduce(function ($c, $subquery, $k) use ($query) {
$graph = $query->filter($subquery)->run();
if (!$graph->hasResults()) {
return $c;
}
$targetIds = collect($graph->records)->pluck("id");
$sourceIds = DB::table("edges")->whereIn("target", $targetIds)->where("field", $k)->get()->pluck("source");
return array_merge($c, $sourceIds->toArray());
}, []);
return [$arguments, [
"field" => "id",
"operator" => "in",
"value" => $sourceIds
]];
}
private function separateMainFromReferenceArguments(): array
{
return collect($this->arguments)->partition(function ($v, $k) {
if (!str_starts_with($k, "children.")) {
return true;
}
return false;
})->toArray();
}
public function run(Query $query): array
{
[$argumentsWithoutReferences, $referencesFilter] = $this->formatReferences($query);
$this->operatorsList = Operator::list();
$formattedArguments = $this->formatArguments($argumentsWithoutReferences);
if (!empty($referencesFilter)) {
$formattedArguments[] = $referencesFilter;
}
return $formattedArguments;
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace Lucent\Query\Filter;
final class AndFilter implements Filter
{
public function __construct(
public array $params = []
)
{
}
public function toArray():array{
return $this->params;
}
}
+12
View File
@@ -0,0 +1,12 @@
<?php
namespace Lucent\Query\Filter;
class Argument
{
public function __construct(
public string $field,
public string $operator,
public mixed $value,
){}
}
+7
View File
@@ -0,0 +1,7 @@
<?php namespace Lucent\Query\Filter;
interface Filter
{
public function toArray():array;
}
+19
View File
@@ -0,0 +1,19 @@
<?php
namespace Lucent\Query\Filter;
final class OrFilter implements Filter
{
public function __construct(
public array $params = []
)
{
}
public function toArray():array{
return $this->params;
}
}
+290
View File
@@ -0,0 +1,290 @@
<?php
namespace Lucent\Query;
use Illuminate\Contracts\Foundation\Application;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;
use Lucent\Query\Filter\AndFilter;
use Lucent\Query\Filter\Argument;
use Lucent\Query\Filter\Filter;
use Lucent\Query\Filter\OrFilter;
final class FilterParser
{
public function __construct(public Application $app)
{
}
/**
* @param array $arguments
* @return array<Argument>
*/
private function formatArguments(array $arguments): array
{
return collect($arguments)->reduce(function ($c, $v, $k) {
$c[] = $this->formatArgument($v, $k);
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" => "%{$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
{
$subqueries = collect($referenceArguments)->reduce(function ($c, $v, $k) {
$keyWithoutRef = str_replace("children.", "", $k);
[$field] = explode(".", $keyWithoutRef);
$referenceField = str_replace($field . ".", "", $keyWithoutRef);
$c[$field][$referenceField] = $v;
return $c;
}, []);
$sourceIds = collect($subqueries)->reduce(function ($c, $subquery, $k) {
$query = $this->app->make(Query::class);
$graph = $query->filter($subquery)->run();
if (!$graph->hasResults()) {
return $c;
}
$targetIds = collect($graph->records)->pluck("id");
$sourceIds = DB::table("edges")->whereIn("target", $targetIds)->where("field", $k)->get()->pluck("source");
return array_merge($c, $sourceIds->toArray());
}, []);
return new Argument(
field: "id",
operator: "in",
value: $sourceIds
);
}
private function separateMainFromReferenceArguments(Filter $arguments): array
{
return collect($arguments->toArray())->partition(function ($v, $k) {
if (!str_starts_with($k, "children.")) {
return true;
}
return false;
})->toArray();
}
/**
* @return array<Argument>
*/
private function parseArguments(Filter $arguments): array
{
[$normalArguments, $referenceArguments] = $this->separateMainFromReferenceArguments($arguments);
$formattedArguments = $this->formatArguments($normalArguments);
if (!empty($referenceArguments)) {
$formattedArguments[] = $this->formatReferences($referenceArguments);
}
return $formattedArguments;
}
public function parse(Builder $builder, Filter $filter): Builder
{
$arguments = $this->parseArguments($filter);
return match (get_class($filter)) {
AndFilter::class => $this->parseAnd($builder, $arguments),
OrFilter::class => $this->parseOr($builder, $arguments),
};
}
/**
* @param array<Argument> $arguments
*/
private function parseAnd(Builder $builder, array $arguments): Builder
{
$ignoredFilters = [];
foreach ($arguments as $argument) {
if (in_array($argument->field, $ignoredFilters)) {
continue;
} else if ($argument->operator == "in") {
$builder->whereIn($argument->field, $argument->value);
} else if ($argument->operator == "nin") {
$builder->whereNotIn($argument->field, $argument->value);
} elseif ($argument->operator == "eqobject") {
$object = $argument->value;
// unset related filters used here
$addToIgnored = collect($arguments)
->filter(fn(Argument $f) => str_starts_with($f->field, $object))
->values()
->map(fn($f) => $f->field)
->toArray();
$ignoredFilters = array_merge($ignoredFilters, $addToIgnored);
$objectFilters = collect($arguments)
->filter(fn($f) => str_starts_with($f->field, $object))
->values()
->reduce(function ($c, $f) use ($object) {
$field = str_replace($object . "->", "", $f->field);
$c[$field] = $f->value;
return $c;
});
// 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;
}
/**
* @param array<Argument> $arguments
*/
private function parseOr(Builder $builder, array $arguments): Builder
{
$builder->where(function (Builder $orBuilder) use ($arguments) {
$ignoredFilters = [];
foreach ($arguments as $argument) {
if (in_array($argument->field, $ignoredFilters)) {
continue;
} else if ($argument->operator == "in") {
$orBuilder->orWhereIn($argument->field, $argument->value);
} else if ($argument->operator == "nin") {
$orBuilder->orWhereNotIn($argument->field, $argument->value);
} elseif ($argument->operator == "eqobject") {
$object = $argument->value;
// unset related filters used here
$addToIgnored = collect($arguments)
->filter(fn(Argument $f) => str_starts_with($f->field, $object))
->values()
->map(fn($f) => $f->field)
->toArray();
$ignoredFilters = array_merge($ignoredFilters, $addToIgnored);
$objectFilters = collect($arguments)
->filter(fn($f) => str_starts_with($f->field, $object))
->values()
->reduce(function ($c, $f) use ($object) {
$field = str_replace($object . "->", "", $f->field);
$c[$field] = $f->value;
return $c;
});
// 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;
}
}
+36 -1
View File
@@ -16,6 +16,7 @@ final class Graph
public function __construct(
public Collection $records,
public Collection $edges,
public Collection $parentEdges,
public ?int $total = null,
)
{
@@ -66,6 +67,15 @@ final class Graph
public function tree(): Collection
{
return $this->getRootRecords()
->map([$this, 'findParents'])
->map([$this, 'findChildren'])
;
return $rootRecords;
return $this->records->filter(function (QueryRecord $record) {
return $this->edges->filter(fn(Edge $ed) => $ed->target == $record->id)->isEmpty();
})->values()
@@ -81,7 +91,6 @@ final class Graph
foreach ($recordEdges as $element) {
$groupRecordEdges[$element->field][] = $element;
}
$children = [];
foreach ($groupRecordEdges as $field => $edges) {
@@ -99,4 +108,30 @@ final class Graph
return $record;
}
public function findParents(QueryRecord $record): QueryRecord
{
$recordEdges = $this->parentEdges->filter(fn(Edge $ed) => $ed->target === $record->id)->values()->sort(fn($a, $b) => $a->rank <=> $b->rank)->values();
$groupRecordEdges = [];
foreach ($recordEdges as $element) {
$groupRecordEdges[$element->field][] = $element;
}
$parents = [];
foreach ($groupRecordEdges as $field => $edges) {
$parents[$field] = [];
foreach ($edges as $anEdge) {
$aRecord = $this->records->filter(fn(QueryRecord $rec) => $rec->id == $anEdge->source)->values();
if (empty($aRecord[0])) {
continue;
}
$parents[$field][] = $this->findParents($aRecord[0]);
}
}
$record->_parents = $parents;
return $record;
}
}
+61 -62
View File
@@ -4,9 +4,10 @@ namespace Lucent\Query;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;
use Lucent\Channel\ChannelService;
use Lucent\Edge\Edge;
use Lucent\Primitive\Collection;
use Lucent\Query\Filter\AndFilter;
use Lucent\Query\Filter\OrFilter;
use Lucent\Record\InputFormatter;
use Lucent\Record\QueryRecord;
use Lucent\Record\Record;
@@ -14,11 +15,14 @@ use Lucent\Record\Record;
final class Query
{
public Filter $filter;
/**
* @var array<AndFilter> $filters
*/
public array $filters;
public QueryOptions $options;
public function __construct(
public readonly ChannelService $channelService,
public readonly FilterParser $filterParser,
public readonly InputFormatter $inputFormatter,
)
{
@@ -27,7 +31,13 @@ final class Query
public function filter(array $filterArguments): Query
{
$this->filter = new Filter($filterArguments);
$this->filters[] = new AndFilter($filterArguments);
return $this;
}
public function orFilter(array $filterArguments): Query
{
$this->filters[] = new OrFilter($filterArguments);
return $this;
}
@@ -62,16 +72,22 @@ final class Query
->get()->toArray();
}
$resultsRecordsUnique = collect(array_merge($resultsRecords, $edgeRecords))->unique("id")->values()->toArray();
$resultEdges = collect(array_merge($resultChildrenEdges, $resultParentEdges))
->unique(fn($edge) => $edge->source . $edge->target . $edge->field)
->toArray();
// $resultEdges = collect(array_merge($resultChildrenEdges, $resultParentEdges))
// ->unique(fn($edge) => $edge->source . $edge->target . $edge->field)
// ->toArray();
return $this->formatRecords($resultsRecordsUnique, $resultEdges);
$this->reset();
return $this->formatRecords($resultsRecordsUnique, $resultChildrenEdges, $resultParentEdges);
}
private function formatRecords(array $records, array $edges): Graph
private function reset()
{
$this->options = new QueryOptions();
$this->filters = [];
}
private function formatRecords(array $records, array $edges, array $parentEdges): Graph
{
$queryRecords = collect($records)->map(function ($recordData) {
@@ -89,10 +105,17 @@ final class Query
})->sortBy("rank")->values()->toArray();
$queryParentEdges = collect($parentEdges)->map(function ($edgeData) {
return Edge::fromArray((array)$edgeData);
})->sortBy("rank")->values()->toArray();
return new Graph(
new Collection($queryRecords),
new Collection($queryEdges),
new Collection($queryParentEdges),
);
}
@@ -103,61 +126,21 @@ final class Query
}
private function parseFilters(Builder $query): Builder
{
$filters = $this->filter->run(new Query($this->channelService, $this->inputFormatter));
$ignoredFilters = [];
foreach ($filters as $filter) {
if (in_array($filter["field"], $ignoredFilters)) {
continue;
} else if ($filter["operator"] == "in") {
$query->whereIn($filter["field"], $filter["value"]);
} else if ($filter["operator"] == "nin") {
$query->whereNotIn($filter["field"], $filter["value"]);
} elseif ($filter["operator"] == "eqobject") {
$object = $filter["value"];
// unset related filters used here
$addToIgnored = collect($filters)
->filter(fn($f) => str_starts_with($f["field"], $object))
->values()
->map(fn($f) => $f["field"])
->toArray();
$ignoredFilters = array_merge($ignoredFilters, $addToIgnored);
$objectFilters = collect($filters)
->filter(fn($f) => str_starts_with($f["field"], $object))
->values()
->reduce(function ($c, $f) use ($object) {
$field = str_replace($object . "->", "", $f["field"]);
$c[$field] = $f["value"];
return $c;
});
// 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 {
$query->where($filter["field"], $filter["operator"], $filter["value"]);
}
foreach ($this->filters as $filter) {
$query = $this->filterParser->parse($query, $filter);
}
$query->whereIn("status", $this->options->status);
return $query;
}
/**
* @throws SubqueryNoResultException
*/
private function mainQuery(): array
{
$query = DB::table("records");
$query = $this->parseFilters($query);
if($this->options->limit > 0){
if ($this->options->limit > 0) {
$query->limit($this->options->limit);
$query->offset($this->options->skip);
}
@@ -174,14 +157,19 @@ final class Query
function getChildren(array $ids): array
{
$subquery = DB::table('edges AS g')
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 0 as depth '))
->whereIn('source', $ids)
->limit($this->options->childrenLimit)
->select(DB::raw('g.source,g.target,g.rank,g.sourceSchema,g.targetSchema,g.field, 1 as depth '))
->whereIn('source', $ids);
if (!empty($this->options->childrenFields)) {
$subquery->whereIn('field', $this->options->childrenFields);
}
$subquery->limit($this->options->childrenLimit)
->unionAll(
DB::table(DB::raw("edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.source = sg.target")
->where("sg.depth", "<=", $this->options->childrenDepth)
->where("depth", "<", $this->options->childrenDepth)
->orderBy("rank")
);
@@ -191,18 +179,17 @@ final class Query
->get()->toArray();
}
private
function getParents(array $ids): array
private function getParents(array $ids): array
{
$subquery = DB::table('edges AS g')
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 0 as depth '))
->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
->limit($this->options->parentsLimit)
->whereIn('g.target', $ids)
->unionAll(
DB::table(DB::raw("edges AS g, search_graph AS sg "))
->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,sg.depth + 1 as depth')
->whereRaw("g.target = sg.source")
->where("sg.depth", "<=", $this->options->parentsDepth)
->where("depth", "<", $this->options->parentsDepth)
->orderBy("rank")
);
@@ -251,6 +238,18 @@ final class Query
return $this;
}
public function childrenFields(array $fields): Query
{
$this->options->childrenFields = $fields;
return $this;
}
public function parentFields(array $fields): Query
{
$this->options->parentFields = $fields;
return $this;
}
public function parentsDepth(int $depth): Query
{
$this->options->parentsDepth = $depth;
+2
View File
@@ -13,6 +13,8 @@ final class QueryOptions
public int $parentsDepth = -1,
public int $childrenLimit = -1,
public int $parentsLimit = -1,
public array $childrenFields = [],
public array $parentFields = [],
public array $sort = [],
public array $status = ["published", "draft"]
)
-43
View File
@@ -1,43 +0,0 @@
<?php
namespace Lucent\Query;
use Lucent\Edge\Edge;
use Lucent\Primitive\Collection;
use Lucent\Record\QueryRecord;
final class QueryResult
{
/**
* @param Collection<QueryRecord> $records
* @param Collection<Edge> $edges
* @param int|null $total
*/
public function __construct(
public Collection $records,
public Collection $edges,
public ?int $total = null,
)
{
}
public function getTotal(): ?int
{
return $this->total;
}
public function hasResults(): bool
{
return !empty($this->records);
}
public function graph(): Graph
{
return new Graph($this->records, $this->edges);
}
}
-17
View File
@@ -1,17 +0,0 @@
<?php
namespace Lucent\Query;
use Exception;
final class SubqueryNoResultException extends Exception
{
// Redefine the exception so message isn't optional
public function __construct(string $message, int $code = 0, Exception $previous = null)
{
// make sure everything is assigned properly
parent::__construct($message, $code, $previous);
}
}
+1
View File
@@ -16,6 +16,7 @@ class QueryRecord
public bool $isRoot,
public ?File $_file = null,
public array $_children = [],
public array $_parents = [],
)
{
}
+19 -11
View File
@@ -83,9 +83,11 @@ readonly class RecordService
_file: $uploadResult->recordFile,
);
$errors = $this->recordValidator->check($schemaName, $record->data, $uniqueEdgesCollection);
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
if (Status::from($status) === Status::PUBLISHED) {
$errors = $this->recordValidator->check($schemaName, $record->data, $uniqueEdgesCollection);
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
}
}
RecordRepo::create($record);
@@ -117,6 +119,7 @@ readonly class RecordService
}
$formattedData = $this->inputFormatter->fill($record->schema, new RecordData($data));
$uniqueEdgesCollection = null;
if ($updateEdges) {
$uniqueEdges = collect($edges)
->map(function ($edge, $index) {
@@ -127,9 +130,17 @@ readonly class RecordService
->unique(fn($e) => $e['field'] . $e['source'] . $e['target'] . $e['sourceSchema'])
->values()->toArray();
$uniqueEdgesCollection = EdgeCollection::fromArray($uniqueEdges);
$errors = $this->recordValidator->check($record->schema, $formattedData, $uniqueEdgesCollection);
} else {
$errors = $this->recordValidator->check($record->schema, $formattedData, null);
}
if (Status::from($status) === Status::PUBLISHED) {
$errors = $this->recordValidator->check($record->schema, $record->data, $uniqueEdgesCollection);
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
}
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
}
}
@@ -143,9 +154,7 @@ readonly class RecordService
);
if ($errors->isNotEmpty()) {
$this->recordValidator->throwException($errors);
}
RecordRepo::update($newRecord);
if ($updateEdges) {
@@ -237,7 +246,6 @@ readonly class RecordService
public function createEmpty(
Schema $schema,
string $userId,
): Record
{
@@ -252,7 +260,7 @@ readonly class RecordService
id: Id::new(),
schema: $schema->name,
status: Status::DRAFT,
_sys: System::newRecord($userId),
_sys: System::newRecord($this->authService->currentUserId()),
data: $formattedData,
_file: null,
);
+3
View File
@@ -42,6 +42,9 @@ class StaticGenerator
}
if(!file_exists(public_path($directory."/index.html"))){
if(file_exists(public_path($directory))){
rmdir(public_path($directory));
}
continue;
}
unlink(public_path($directory."/index.html"));
+6 -6
View File
@@ -7,13 +7,13 @@
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>@yield('title') - Lucent Data Platform</title>
<!-- if development -->
@php
echo '<script type="module" crossorigin src="http://127.0.0.1:5173/@vite/client"></script>';
@endphp
<script type="module" crossorigin src="http://127.0.0.1:5173/main.js"></script>
{{-- @php--}}
{{-- echo '<script type="module" crossorigin src="http://127.0.0.1:5173/@vite/client"></script>';--}}
{{-- @endphp--}}
{{-- <script type="module" crossorigin src="http://127.0.0.1:5173/main.js"></script>--}}
<!-- if production -->
{{-- <link rel="stylesheet" href="/vendor/lucent/dist/{{ $manifest['main.css']["file"] }}" />--}}
{{-- <script type="module" src="/vendor/lucent/dist/{{ $manifest['main.js']["file"] }}"></script>--}}
<link rel="stylesheet" href="/vendor/lucent/dist/{{ $manifest['main.css']["file"] }}" />
<script type="module" src="/vendor/lucent/dist/{{ $manifest['main.js']["file"] }}"></script>
<link rel="icon" type="image/x-icon" href="/favicon.ico">