diff --git a/front/js/svelte/common/OffCanvas.svelte b/front/js/svelte/common/OffCanvas.svelte
index 035210e..61a1db9 100644
--- a/front/js/svelte/common/OffCanvas.svelte
+++ b/front/js/svelte/common/OffCanvas.svelte
@@ -3,25 +3,25 @@
import {onDestroy, onMount} from "svelte";
import offcanvas from "bootstrap/js/src/offcanvas.js";
export let title = "";
- let offcanvasEl;
- let offcanvasInstance;
+ let offCanvasEl;
+ let offCanvasInstance;
export function show() {
- offcanvasInstance.show();
+ if(!offCanvasInstance){
+ offCanvasInstance = new offcanvas(offCanvasEl);
+ }
+ offCanvasInstance.show();
}
onMount(()=>{
- offcanvasInstance = new offcanvas(offcanvasEl);
+ offCanvasInstance = new offcanvas(offCanvasEl);
});
-
-
- export function hide(e) {
- e.preventDefault();
- offcanvasInstance.hide();
+ export function hide() {
+ offCanvasInstance.hide();
}
-
-
+
{/if}
r.edge))),
+ edges: JSON.parse(JSON.stringify(graph?.map(r => r.edge.target+r.edge.field) ?? [])),
};
hasUnsavedData = checkUnsavedData();
@@ -49,7 +46,6 @@
setOriginalData()
})
-
afterUpdate(() => {
hasUnsavedData = checkUnsavedData();
});
@@ -79,11 +75,9 @@
return !isEqual(originalContent, {
data: data,
status: status,
- edges: graph.map(r => r.edge),
+ edges: graph?.map(r => r.edge.target+r.edge.field) ?? [],
});
}
-
-
diff --git a/front/js/svelte/records/form/references/EdgeData.svelte b/front/js/svelte/records/form/references/EdgeData.svelte
index b49b096..999288a 100644
--- a/front/js/svelte/records/form/references/EdgeData.svelte
+++ b/front/js/svelte/records/form/references/EdgeData.svelte
@@ -3,13 +3,16 @@
import {getContext} from "svelte";
import Form from "../Form.svelte";
import OffCanvas from "../../../common/OffCanvas.svelte";
- import Preview from "../../../newPreview/Preview.svelte";
+ import PreviewCard from "../../PreviewCard.svelte";
+ import axios from "axios";
export let field;
+ export let record;
export let edge;
let form;
let offCanvas;
-
+ $: validationErrors = null;
+ $: errorMessage = null;
const channel = getContext("channel");
let schema = channel.schemas.find(s => s.name === field.data);
@@ -17,20 +20,56 @@
offCanvas.show();
}
-
-
function save(e){
e.preventDefault();
- console.log("yo")
+ console.log("SAVE: Attempt");
+ validationErrors = null;
+ return new Promise(function (resolve, reject) {
+ axios
+ .put(channel.lucentUrl + "/edges", edge)
+ .then(function (response) {
+ console.log("SAVE: SAVED");
+ edge = response.data;
+ form.setOriginalData();
+ resolve(null);
+ offCanvas.hide();
+ })
+ .catch(function (error) {
+ // setOriginalContent();
+ if (error.response) {
+ if (typeof error.response.data.error === "string") {
+ errorMessage = error.response.data.error;
+ } else {
+ validationErrors = error.response.data.error;
+ console.log(validationErrors)
+ }
+ }
+ resolve(null);
+
+ });
+ });
+
}
+
+
diff --git a/front/js/svelte/records/form/references/Reference.svelte b/front/js/svelte/records/form/references/Reference.svelte
index 90b4f47..b415034 100644
--- a/front/js/svelte/records/form/references/Reference.svelte
+++ b/front/js/svelte/records/form/references/Reference.svelte
@@ -88,7 +88,7 @@
hasDelete={true}
editable={!!field?.data}
{field}
- edge={reference.edge}
+ bind:edge={reference.edge}
on:remove={removeReference}
/>
diff --git a/front/js/svelte/records/form/references/reference.js b/front/js/svelte/records/form/references/reference.js
index 524500d..e124266 100644
--- a/front/js/svelte/records/form/references/reference.js
+++ b/front/js/svelte/records/form/references/reference.js
@@ -10,6 +10,7 @@ export function insertEdges(existingRecords, sourceRecord, targetRecords, fieldN
sourceSchema: sourceRecord.schema,
targetSchema: r.schema,
field: fieldName,
+ data: {},
rank: ""
}
diff --git a/src/Commands/RemoveOrphanEdges.php b/src/Commands/RemoveOrphanEdges.php
index 55c33eb..fcf86d9 100644
--- a/src/Commands/RemoveOrphanEdges.php
+++ b/src/Commands/RemoveOrphanEdges.php
@@ -3,7 +3,7 @@
namespace Lucent\Commands;
use Illuminate\Console\Command;
-use Lucent\Edge\EdgeService;
+use Lucent\Graph\Edge\EdgeService;
use Lucent\Query\Query;
class RemoveOrphanEdges extends Command
diff --git a/src/Database/migrations/04_revisions.php b/src/Database/migrations/04_revisions.php
index 392ae4b..30a428d 100644
--- a/src/Database/migrations/04_revisions.php
+++ b/src/Database/migrations/04_revisions.php
@@ -21,6 +21,7 @@ return new class extends Migration {
$table->jsonb('_file');
$table->jsonb('_edges');
});
+
}
/**
diff --git a/src/Database/migrations/08_EdgeRevisions.php b/src/Database/migrations/08_EdgeRevisions.php
new file mode 100644
index 0000000..9f7ce49
--- /dev/null
+++ b/src/Database/migrations/08_EdgeRevisions.php
@@ -0,0 +1,33 @@
+dropColumn("schema");
+ $table->dropColumn("_file");
+ });
+ }
+
+ /**
+ * Reverse the migrations.
+ *
+ * @return void
+ */
+ public function down()
+ {
+ Schema::table('revisions', function (Blueprint $table) {
+ $table->string('schema');
+ $table->jsonb('_file');
+ });
+ }
+};
diff --git a/src/Edge/EdgeData.php b/src/Edge/EdgeData.php
deleted file mode 100644
index 839a2e1..0000000
--- a/src/Edge/EdgeData.php
+++ /dev/null
@@ -1,50 +0,0 @@
-data = array_merge($this->data, $data->toArray());
- return $this;
- }
-
- public function get(string $key, mixed $default = null): mixed
- {
- return $this->data[$key] ?? $default;
- }
-
- public function set(string $key, mixed $value): EdgeData
- {
- $this->data[$key] = $value;
- return $this;
- }
-
- public function isEmpty(string $key): bool
- {
- return empty($this->get($key));
- }
-
- public function isDefined(string $key): bool
- {
- return !empty($this->get($key));
- }
-
-
- public function toArray(): array
- {
- return $this->data;
- }
-
- public function jsonSerialize(): array
- {
- return $this->data;
- }
-
-
-}
diff --git a/src/Edge/EdgeRepo.php b/src/Edge/EdgeRepo.php
deleted file mode 100644
index 9cbc95f..0000000
--- a/src/Edge/EdgeRepo.php
+++ /dev/null
@@ -1,85 +0,0 @@
-insert($edge->toDB());
- } catch (PDOException $e) {
- if ($e->getCode() == 23505) {
- throw new LucentException("Edge already exists");
- }
- throw $e;
- }
-
- }
-
- /**
- * @param string $from
- * @param EdgeCollection $edges
- * @return void
- */
- public function update(string $from, EdgeCollection $edges): void
- {
- DB::table("edges")->where("source", $from)->delete();
- if($edges->isEmpty()){
- return;
- }
-
- $edgesDB = collect($edges)->map(fn(Edge $e) => $e->toDB())->toArray();
- DB::table("edges")->insert($edgesDB);
- }
-
-
- public function findAll(): EdgeCollection
- {
- $edges = DB::table("edges")->get();
- return new EdgeCollection(...$edges->map([$this, 'mapEdge'])->toArray());
- }
-
- public function mapEdge(stdClass $edge): Edge
- {
- if (empty($edge->data)) {
- $data = none();
- } else {
- $data = some(new EdgeData(json_decode($edge->data)));
- }
-
-
- return new Edge(
- source: $edge->source,
- target: $edge->target,
- sourceSchema: $edge->sourceSchema,
- targetSchema: $edge->targetSchema,
- field: $edge->field,
- data: $data,
- rank: $edge->rank,
- depth: $edge->depth ?? 0
- );
-
- }
-
- public function remove(Edge $edge): void
- {
- DB::table("edges")
- ->where("source", $edge->source)
- ->where("target", $edge->target)
- ->where("sourceSchema", $edge->sourceSchema)
- ->where("targetSchema", $edge->targetSchema)
- ->where("field", $edge->field)
- ->delete();
- }
-
-}
diff --git a/src/Edge/EdgeService.php b/src/Edge/EdgeService.php
deleted file mode 100644
index 0386a37..0000000
--- a/src/Edge/EdgeService.php
+++ /dev/null
@@ -1,59 +0,0 @@
-edgeRepo->insert($edge);
- return $edge;
- }
-
- /**
- * @param string $from
- * @param EdgeCollection $edges
- * @return void
- */
- public function update(string $from, EdgeCollection $edges): void
- {
- $this->edgeRepo->update($from, $edges);
- }
-
- public function findAll(): EdgeCollection
- {
- return $this->edgeRepo->findAll();
- }
-
- public function remove(Edge $edge): void
- {
- $this->edgeRepo->remove($edge);
- }
-
-}
diff --git a/src/File/FileService.php b/src/File/FileService.php
index af41f5f..6192102 100644
--- a/src/File/FileService.php
+++ b/src/File/FileService.php
@@ -4,9 +4,9 @@ namespace Lucent\File;
use Illuminate\Http\UploadedFile;
use Lucent\Channel\ChannelService;
+use Lucent\Graph\Record\FileInfo;
+use Lucent\Graph\Record\QueryRecord;
use Lucent\LucentException;
-use Lucent\Record\FileInfo;
-use Lucent\Record\QueryRecord;
use Lucent\Schema\Schema\Schema;
use Lucent\Schema\Schema\Type;
use Lucent\Support\Result\Result;
diff --git a/src/File/FileUploadResult.php b/src/File/FileUploadResult.php
index 38d1d1c..3e81590 100644
--- a/src/File/FileUploadResult.php
+++ b/src/File/FileUploadResult.php
@@ -2,7 +2,7 @@
namespace Lucent\File;
-use Lucent\Record\FileInfo;
+use Lucent\Graph\Record\FileInfo;
class FileUploadResult
{
diff --git a/src/File/ImageService.php b/src/File/ImageService.php
index bcc95f9..8b5b41f 100644
--- a/src/File/ImageService.php
+++ b/src/File/ImageService.php
@@ -6,7 +6,7 @@ use Exception;
use Illuminate\Log\Logger;
use Intervention\Image\ImageManager;
use Lucent\Channel\ChannelService;
-use Lucent\Record\QueryRecord;
+use Lucent\Graph\Record\QueryRecord;
class ImageService
{
diff --git a/src/File/Uploader.php b/src/File/Uploader.php
index 334d997..0d6792a 100644
--- a/src/File/Uploader.php
+++ b/src/File/Uploader.php
@@ -9,8 +9,8 @@ use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Intervention\Image\ImageManagerStatic;
+use Lucent\Graph\Record\FileInfo as RecordFile;
use Lucent\LucentException;
-use Lucent\Record\FileInfo as RecordFile;
use Lucent\Schema\Schema\Schema;
use Spatie\ImageOptimizer\OptimizerChainFactory;
diff --git a/src/Record/RecordData.php b/src/Graph/Data/FieldData.php
similarity index 63%
rename from src/Record/RecordData.php
rename to src/Graph/Data/FieldData.php
index 784147f..dc2ab2b 100644
--- a/src/Record/RecordData.php
+++ b/src/Graph/Data/FieldData.php
@@ -1,14 +1,14 @@
data = array_merge($this->data, $data->toArray());
@@ -20,7 +20,7 @@ class RecordData extends ArrayContainer
return $this->data[$key] ?? $default;
}
- public function set(string $key, mixed $value): RecordData
+ public function set(string $key, mixed $value): FieldData
{
$this->data[$key] = $value;
return $this;
@@ -47,5 +47,13 @@ class RecordData extends ArrayContainer
return $this->data;
}
+ public static function fromArray(array $data):self{
+ return new self($data);
+ }
+
+ public static function fromJson(string $data):self{
+ return self::fromArray(json_decode($data,true));
+ }
+
}
diff --git a/src/Record/InputFormatter.php b/src/Graph/Data/InputFormatter.php
similarity index 66%
rename from src/Record/InputFormatter.php
rename to src/Graph/Data/InputFormatter.php
index 4085273..d5df614 100644
--- a/src/Record/InputFormatter.php
+++ b/src/Graph/Data/InputFormatter.php
@@ -1,6 +1,6 @@
channelService->getSchema($schemaName)->get();
+
return $schema->fields
->filter(fn(FieldInterface $field)=> $field instanceof FieldDataInterface)
- ->reduce(fn(RecordData $carry, FieldDataInterface $field) => $field->format($input, $carry), new RecordData([]));
+ ->reduce(fn(FieldData $carry, FieldDataInterface $field) => $field->format($input, $carry), new FieldData([]));
}
diff --git a/src/Graph/Edge/Contracts/EdgeData.php b/src/Graph/Edge/Contracts/EdgeData.php
new file mode 100644
index 0000000..0cfdf6a
--- /dev/null
+++ b/src/Graph/Edge/Contracts/EdgeData.php
@@ -0,0 +1,18 @@
+ $data
- */
+
public function __construct(
- public string $source,
- public string $target,
- public string $sourceSchema,
- public string $targetSchema,
- public string $field,
- public Option $data,
- public string $rank = "a",
- public int $depth = 0,
+ public string $source,
+ public string $target,
+ public string $sourceSchema,
+ public string $targetSchema,
+ public string $field,
+ public FieldData $data,
+ public string $rank = "a",
+ public int $depth = 0,
)
{
}
public function equal(Edge $edge): bool
{
- return $this->targetSchema === $edge->targetSchema && $this->field === $edge->field && $this->target === $edge->target && $this->source === $edge->source;
+ return $this->field === $edge->field && $this->target === $edge->target && $this->source === $edge->source;
}
public function toArray(): array
@@ -46,14 +42,13 @@ final class Edge
public static function fromArray(array $data): Edge
{
-
return new Edge(
source: data_get($data, 'source'),
target: data_get($data, 'target'),
sourceSchema: data_get($data, 'sourceSchema'),
targetSchema: data_get($data, 'targetSchema'),
field: data_get($data, 'field'),
- data: Option::fromValue(data_get($data,"data")),
+ data: FieldData::fromArray(data_get($data, "data", [])),
rank: data_get($data, 'rank'),
depth: data_get($data, 'depth', 0),
);
@@ -69,9 +64,11 @@ final class Edge
sourceSchema: data_get($data, 'sourceSchema'),
targetSchema: data_get($data, 'targetSchema'),
field: data_get($data, 'field'),
- data: Option::fromValue(data_get($data,"data")),
+ data: FieldData::fromJson($data->data ?? "{}"),
rank: data_get($data, 'rank'),
depth: data_get($data, 'depth', 0),
);
}
+
+
}
diff --git a/src/Edge/EdgeCollection.php b/src/Graph/Edge/EdgeCollection.php
similarity index 57%
rename from src/Edge/EdgeCollection.php
rename to src/Graph/Edge/EdgeCollection.php
index a57db42..e9cd7e2 100644
--- a/src/Edge/EdgeCollection.php
+++ b/src/Graph/Edge/EdgeCollection.php
@@ -1,16 +1,16 @@
+ * @extends Collection
*/
final class EdgeCollection extends Collection
{
- public function __construct(
+ private function __construct(
Edge ...$array
)
{
@@ -25,10 +25,24 @@ final class EdgeCollection extends Collection
return collect($this)->values()->toArray();
}
+ public function toDB(): array
+ {
+ return collect($this)->map(fn(Edge $edge) => $edge->toDB())->toArray();
+ }
+
+ /**
+ * @param array $data
+ * @return EdgeCollection
+ */
public static function fromArray(array $data): EdgeCollection
{
$edges = collect($data)
- ->map([Edge::class, 'fromArray'])
+ ->map(function (mixed $edge) {
+ if ($edge instanceof Edge) {
+ return $edge;
+ }
+ return Edge::fromArray($edge);
+ })
->unique(fn(Edge $e) => $e->field . $e->source . $e->target);
return new EdgeCollection(...$edges);
}
diff --git a/src/Graph/Edge/EdgeRepo.php b/src/Graph/Edge/EdgeRepo.php
new file mode 100644
index 0000000..0e13ab1
--- /dev/null
+++ b/src/Graph/Edge/EdgeRepo.php
@@ -0,0 +1,89 @@
+where("source", $sourceId)->delete();
+ DB::table("edges")->insert($edgeCollection->toDB());
+ });
+ }
+
+ public function insert(Edge $edge): void
+ {
+ try {
+ DB::table("edges")->insert($edge->toDB());
+ } catch (PDOException $e) {
+ if ($e->getCode() == 23505) {
+ throw new LucentException("Edge already exists");
+ }
+ throw $e;
+ }
+
+ }
+
+ public function update(Edge $edge): void
+ {
+ DB::table("edges")
+ ->where("source", $edge->source)
+ ->where("target", $edge->target)
+ ->where("field", $edge->field)
+ ->update([
+ "data" => json_encode($edge->data),
+ "rank" => $edge->rank,
+ ]);
+ }
+
+
+// public function findAll(): EdgeCollection
+// {
+// $edges = DB::table("edges")->get();
+// return new EdgeCollection(...$edges->map([$this, 'mapEdge'])->toArray());
+// }
+//
+// public function mapEdge(stdClass $edge): Edge
+// {
+// if (empty($edge->data)) {
+// $data = none();
+// } else {
+// $data = some(new FieldData(json_decode($edge->data)));
+// }
+//
+//
+// return new Edge(
+// source: $edge->source,
+// target: $edge->target,
+// sourceSchema: $edge->sourceSchema,
+// targetSchema: $edge->targetSchema,
+// field: $edge->field,
+// data: $data,
+// rank: $edge->rank,
+// depth: $edge->depth ?? 0
+// );
+//
+// }
+//
+// public function remove(Edge $edge): void
+// {
+// DB::table("edges")
+// ->where("source", $edge->source)
+// ->where("target", $edge->target)
+// ->where("sourceSchema", $edge->sourceSchema)
+// ->where("targetSchema", $edge->targetSchema)
+// ->where("field", $edge->field)
+// ->delete();
+// }
+
+}
diff --git a/src/Graph/Edge/EdgeService.php b/src/Graph/Edge/EdgeService.php
new file mode 100644
index 0000000..7453070
--- /dev/null
+++ b/src/Graph/Edge/EdgeService.php
@@ -0,0 +1,95 @@
+ $edges
+ * @return EdgeCollection
+ */
+ public function replaceEdgesForRecord(Record $record, Collection $edges): EdgeCollection
+ {
+ $edgeCollection = $this->getUniqueRecordEdges($edges, $record);
+ $this->edgeRepo->replaceBySourceId($record->id, $edgeCollection);
+ return $edgeCollection;
+
+ }
+
+ public function update(EdgeData $data) :Result{
+
+ $edge = $this->mapper->fromArray(toArray($data));
+ $this->edgeRepo->update($edge);
+ return Success::create($edge);
+ }
+//
+// /**
+// * @throws LucentException
+// */
+// public function create(
+// string $source,
+// string $target,
+// string $sourceSchema,
+// string $targetSchema,
+// string $field,
+// string $rank,
+// ): Edge
+// {
+//
+//
+// $edge = new Edge(
+//
+// source: $source,
+// target: $target,
+// sourceSchema: $sourceSchema,
+// targetSchema: $targetSchema,
+// field: $field,
+// rank: $rank,
+// );
+// $this->edgeRepo->insert($edge);
+// return $edge;
+// }
+//
+// /**
+// * @param string $from
+// * @param EdgeCollection $edges
+// * @return void
+// */
+// public function update(string $from, EdgeCollection $edges): void
+// {
+// $this->edgeRepo->update($from, $edges);
+// }
+//
+// public function findAll(): EdgeCollection
+// {
+// return $this->edgeRepo->findAll();
+// }
+//
+// public function remove(Edge $edge): void
+// {
+// $this->edgeRepo->remove($edge);
+// }
+
+ private function getUniqueRecordEdges(Collection $edges, Record $record): EdgeCollection
+ {
+ $edges = $edges
+ ->map(fn(RecordEdgeData $edge, $index) => $edge->toEdge($record, $index));
+ return EdgeCollection::fromArray($edges->toArray());
+ }
+}
diff --git a/src/Graph/Edge/Mapper.php b/src/Graph/Edge/Mapper.php
new file mode 100644
index 0000000..05bc5fe
--- /dev/null
+++ b/src/Graph/Edge/Mapper.php
@@ -0,0 +1,45 @@
+getEdgeDataSchema($edge);
+ if(!empty($edgeSchema)){
+ $edge->data = $this->inputFormatter->fill($edgeSchema, $edge->data);
+ }
+
+
+ return $edge;
+ }
+
+ public function fromArray(array $data): Edge
+ {
+ $edge = Edge::fromArray($data);
+ $edgeSchema = $this->getEdgeDataSchema($edge);
+ if(!empty($edgeSchema)){
+ $edge->data = $this->inputFormatter->fill($edgeSchema, $edge->data);
+ }
+ return $edge;
+ }
+
+ private function getEdgeDataSchema(Edge $edge): string
+ {
+
+ return $this->channelService->getSchema($edge->sourceSchema)->get()->fields->where("name", $edge->field)->first()->data;
+ }
+}
\ No newline at end of file
diff --git a/src/Record/Contracts/EditorTree.php b/src/Graph/Record/Contracts/EditorTree.php
similarity index 81%
rename from src/Record/Contracts/EditorTree.php
rename to src/Graph/Record/Contracts/EditorTree.php
index 637ab0b..7bfafa7 100644
--- a/src/Record/Contracts/EditorTree.php
+++ b/src/Graph/Record/Contracts/EditorTree.php
@@ -1,8 +1,8 @@
schema,
targetSchema: $this->targetSchema,
field: $this->field,
- data: $this->data,
+ data: $this->data->map([FieldData::class,'fromArray'])->getOrElse(new FieldData([])),
rank: $index,
);
}
diff --git a/src/Record/Contracts/UpdateRecordData.php b/src/Graph/Record/Contracts/UpdateRecordData.php
similarity index 86%
rename from src/Record/Contracts/UpdateRecordData.php
rename to src/Graph/Record/Contracts/UpdateRecordData.php
index 76c421c..8496b6f 100644
--- a/src/Record/Contracts/UpdateRecordData.php
+++ b/src/Graph/Record/Contracts/UpdateRecordData.php
@@ -1,8 +1,8 @@
schema,
status: Status::from($data->status),
_sys: System::fromArray(json_decode($data->_sys, true)),
- data: new RecordData(json_decode($data->data, true)),
+ data: new FieldData(json_decode($data->data, true)),
);
}
}
\ No newline at end of file
diff --git a/src/Record/File.php b/src/Graph/Record/File.php
similarity index 82%
rename from src/Record/File.php
rename to src/Graph/Record/File.php
index f896612..8265b94 100644
--- a/src/Record/File.php
+++ b/src/Graph/Record/File.php
@@ -1,19 +1,20 @@
schema,
status: Status::from($data->status),
_sys: System::fromArray(json_decode($data->_sys, true)),
- data: new RecordData(json_decode($data->data, true)),
+ data: new FieldData(json_decode($data->data, true)),
_file: FileInfo::fromJSON($data->_file),
);
}
diff --git a/src/Record/FileInfo.php b/src/Graph/Record/FileInfo.php
similarity index 96%
rename from src/Record/FileInfo.php
rename to src/Graph/Record/FileInfo.php
index 05529e9..edf6550 100644
--- a/src/Record/FileInfo.php
+++ b/src/Graph/Record/FileInfo.php
@@ -1,6 +1,6 @@
query
- ->filter(["id_in" => $this->getIdsExcept($ignoreId)])
- ->limit(7)
- ->run();
-
-
+ $graph = $this->query->run(
+ fn($builder) => $builder->filter(["id_in" => $this->getIdsExcept($ignoreId)])
+ ->limit(7)
+ );
return $this->order($graph->records->toArray());
}
}
diff --git a/src/Record/Mapper.php b/src/Graph/Record/Mapper.php
similarity index 86%
rename from src/Record/Mapper.php
rename to src/Graph/Record/Mapper.php
index 86cf8a1..d78056b 100644
--- a/src/Record/Mapper.php
+++ b/src/Graph/Record/Mapper.php
@@ -1,7 +1,8 @@
toDB();
@@ -21,14 +21,14 @@ class RecordRepo
/**
* @param array $ids
*/
- public static function updateStatusBulk(Status $status, array $ids): void
+ public function updateStatusBulk(Status $status, array $ids): void
{
DB::table("records")->whereIn("id", $ids)->update([
'status' => $status->value
]);
}
- public static function update(Record $record): void
+ public function update(Record $record): void
{
$recordToDB = $record->toDB();
diff --git a/src/Record/RecordService.php b/src/Graph/Record/RecordService.php
similarity index 85%
rename from src/Record/RecordService.php
rename to src/Graph/Record/RecordService.php
index 685e707..4470107 100644
--- a/src/Record/RecordService.php
+++ b/src/Graph/Record/RecordService.php
@@ -1,20 +1,21 @@
channelService->getSchema($data->schemaName)->get();
- $formattedData = $this->inputFormatter->fill($data->schemaName, new RecordData($data->data));
+ $formattedData = $this->inputFormatter->fill($data->schemaName, new FieldData($data->data));
$newRecordId = $data->id->getOrElse(Id::new());
$record = new Document(
@@ -61,32 +61,58 @@ readonly class RecordService
data: $formattedData,
);
- $uniqueEdges = $this->getUniqueEdges($data->edges, $record);
-
if ($data->status === Status::PUBLISHED) {
$errors = $this->recordValidator->check($data->schemaName, $record->data);
if ($errors->isNotEmpty()) {
return Error::create($errors);
}
}
- RecordRepo::create($record);
- $this->edgeService->update($record->id, $uniqueEdges);
- $this->revisionService->create($record, $uniqueEdges);
+
+ $this->recordRepo->create($record);
+ $edgeCollection = $this->edgeService->replaceEdgesForRecord($record,$data->edges);
+ $this->revisionService->create($record, $edgeCollection);
return Success::create($record->id);
}
/**
- * @param Collection $edges
- * @param Record $record
- * @return EdgeCollection
+ * @param UpdateRecordData $data
+ * @return Result>
*/
- private function getUniqueEdges(Collection $edges, Record $record): EdgeCollection
+ public function update(UpdateRecordData $data): Result
{
- $edges = $edges
- ->map(fn(RecordEdgeData $edge, $index) => $edge->toEdge($record, $index));
- return new EdgeCollection(...$edges->toArray());
+ $record = $this->query->filter(["id" => $data->id])->run()->rootRecords->first();
+
+ if (empty($record)) {
+ return Error::create("Record id is missing");
+ }
+ $formattedData = $this->inputFormatter->fill($record->schema, new FieldData($data->data));
+
+ if ($data->status === Status::PUBLISHED) {
+ $errors = $this->recordValidator->check($record->schema, $record->data);
+ if ($errors->isNotEmpty()) {
+ return Error::create($errors);
+ }
+ }
+
+ $newRecord = new Document(
+ id: $record->id,
+ schema: $record->schema,
+ status: $data->status,
+ _sys: $record->_sys->update($this->authService->currentUserId()),
+ data: $record->data->merge($formattedData),
+ );
+
+ $this->recordRepo->update($newRecord);
+
+ $edgeCollection = EdgeCollection::fromArray([]);
+ if ($data->updateEdges) {
+ $edgeCollection = $this->edgeService->replaceEdgesForRecord($record,$data->edges);
+ }
+ $this->revisionService->create($newRecord, $edgeCollection);
+ return Success::create($record->id);
}
+
/**
* @throws LucentException
* @throws ValidatorException
@@ -104,7 +130,7 @@ readonly class RecordService
{
$schema = $this->channelService->getSchema($schemaName)->get();
- $formattedData = $this->inputFormatter->fill($schemaName, new RecordData($data));
+ $formattedData = $this->inputFormatter->fill($schemaName, new FieldData($data));
if (empty($formattedData["id"])) {
$formattedData["id"] = Id::new();
}
@@ -151,45 +177,7 @@ readonly class RecordService
}
- /**
- * @param UpdateRecordData $data
- * @return Result>
- */
- public function update(UpdateRecordData $data): Result
- {
- $record = $this->query->filter(["id" => $data->id])->run()->rootRecords->first();
- if (empty($record)) {
- return Error::create("Record id is missing");
- }
- $formattedData = $this->inputFormatter->fill($record->schema, new RecordData($data->data));
-
- $uniqueEdges = new EdgeCollection();
- if ($data->updateEdges) {
- $uniqueEdges = $this->getUniqueEdges($data->edges, $record);
- }
- if ($data->status === Status::PUBLISHED) {
- $errors = $this->recordValidator->check($record->schema, $record->data);
- if ($errors->isNotEmpty()) {
- return Error::create($errors);
- }
- }
-
- $newRecord = new Document(
- id: $record->id,
- schema: $record->schema,
- status: $data->status,
- _sys: $record->_sys->update($this->authService->currentUserId()),
- data: $record->data->merge($formattedData),
- );
-
- RecordRepo::update($newRecord);
- if ($data->updateEdges) {
- $this->edgeService->update($newRecord->id, $uniqueEdges);
- }
- $this->revisionService->create($newRecord, $uniqueEdges);
- return Success::create($record->id);
- }
/**
*/
@@ -290,7 +278,7 @@ readonly class RecordService
return $carry;
}, []);
- $formattedData = $this->inputFormatter->fill($schema->name, new RecordData($defaultValues));
+ $formattedData = $this->inputFormatter->fill($schema->name, new FieldData($defaultValues));
return new Document(
id: Id::new(),
schema: $schema->name,
diff --git a/src/Record/Status.php b/src/Graph/Record/Status.php
similarity index 79%
rename from src/Record/Status.php
rename to src/Graph/Record/Status.php
index bad0d46..8da5b07 100644
--- a/src/Record/Status.php
+++ b/src/Graph/Record/Status.php
@@ -1,6 +1,6 @@
edgeService->update(new EdgeData(
+ source: $request->input("source"),
+ target: $request->input("target"),
+ sourceSchema: $request->input("sourceSchema"),
+ targetSchema: $request->input("targetSchema"),
+ field: $request->input("field"),
+ data: $request->input("data"),
+ rank: $request->input("rank"),
+ ));
+ return result($res);
+ }
+
+
+}
diff --git a/src/Http/Controller/FileController.php b/src/Http/Controller/FileController.php
index 35497e6..e4836d5 100644
--- a/src/Http/Controller/FileController.php
+++ b/src/Http/Controller/FileController.php
@@ -2,13 +2,13 @@
namespace Lucent\Http\Controller;
-use Lucent\Http\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Lucent\Channel\ChannelService;
use Lucent\File\FileUploadResult;
+use Lucent\Graph\Record\RecordService;
+use Lucent\Http\Controller;
use Lucent\Query\Query;
-use Lucent\Record\RecordService;
use function Lucent\File\loadDisk;
use function Lucent\File\uploadFile;
use function Lucent\Response\fail;
diff --git a/src/Http/Controller/RecordController.php b/src/Http/Controller/RecordController.php
index 526a3ad..99efcda 100644
--- a/src/Http/Controller/RecordController.php
+++ b/src/Http/Controller/RecordController.php
@@ -2,27 +2,28 @@
namespace Lucent\Http\Controller;
-use Lucent\Http\Controller;
use Illuminate\Http\Request;
use Lucent\Account\AccountService;
use Lucent\Channel\ChannelService;
+use Lucent\Graph\Record\Contracts\EditorTree;
+use Lucent\Graph\Record\Contracts\NewDocumentData;
+use Lucent\Graph\Record\Contracts\RecordEdgeData;
+use Lucent\Graph\Record\Contracts\UpdateRecordData;
+use Lucent\Graph\Record\Manager;
+use Lucent\Graph\Record\QueryRecord;
+use Lucent\Graph\Record\RecordService;
+use Lucent\Graph\Record\Status;
+use Lucent\Http\Controller;
use Lucent\LucentException;
+use Lucent\Query\Builder;
use Lucent\Query\Operator;
use Lucent\Query\Query;
-use Lucent\Record\Contracts\EditorTree;
-use Lucent\Record\Contracts\NewDocumentData;
-use Lucent\Record\Contracts\RecordEdgeData;
-use Lucent\Record\Contracts\UpdateRecordData;
-use Lucent\Record\Manager;
-use Lucent\Record\QueryRecord;
-use Lucent\Record\RecordService;
-use Lucent\Record\Status;
use Lucent\Schema\Schema\System;
use Lucent\Schema\Validator\ValidatorException;
use Lucent\Support\Collection;
use Lucent\Support\Result\Success;
use Lucent\Svelte\Svelte;
-use PhpOption\Option;
+use Lucent\Support\Option\Option;
use function Lucent\Response\fail;
use function Lucent\Response\ok;
use function Lucent\Response\result;
@@ -36,7 +37,7 @@ class RecordController extends Controller
private readonly Svelte $svelte,
private readonly Query $query,
private readonly Manager $recordManager,
- private readonly EditorTree $editorTree
+ private readonly EditorTree $editorTree
)
{
}
@@ -64,19 +65,17 @@ class RecordController extends Controller
"status_in" => "draft,published",
], $filter);
-
$skip = data_get($urlParams, "skip") ?? 0;
$limit = 30;
- $graph = $this->query
- ->filter($arguments)
+ $graph = $this->query->run(fn(Builder $builder) => $builder->filter($arguments)
->limit($limit)
->status(explode(",", $arguments["status_in"]))
->skip($skip)
->sort($sort)
->childrenFields($schema?->visible ?? [])
->childrenDepth(1)
- ->parentsDepth(0)
- ->runWithCount();
+ ->withCount()
+ );
$data = [
"schemas" => $this->channelService->channel->schemas,
@@ -102,6 +101,7 @@ class RecordController extends Controller
}
return $data;
}
+
$data["inModal"] = false;
return $this->svelte->render(
layout: "channel",
@@ -204,15 +204,14 @@ class RecordController extends Controller
{
$rid = $request->route("rid");
- $graph = $this->query
- ->filter(["id" => $rid])
+ $graph = $this->query->run(fn(Builder $builder) => $builder->filter(["id" => $rid])
->limit(1)
->skip(0)
- ->childrenDepth(2)
- ->childrenLimit(200)
+ ->childrenDepth(1)
+ ->childrenLimit(500)
->parentsDepth(1)
- ->parentsLimit(200)
- ->run();
+ );
+
if ($graph->rootRecords->isEmpty()) {
return $this->svelte->render(
@@ -316,9 +315,9 @@ class RecordController extends Controller
$recordEdgeData = (new Collection($request->input("edges")))->map(fn($item) => new RecordEdgeData(
target: $item["target"],
- targetSchema:$item["targetSchema"],
+ targetSchema: $item["targetSchema"],
field: $item["field"],
- data: Option::fromValue(data_get($item,"data")),
+ data: Option::fromValue(data_get($item, "data")),
));
$res = match ($request->input("isCreateMode")) {
diff --git a/src/Http/web.php b/src/Http/web.php
index a49c95f..31e6af1 100644
--- a/src/Http/web.php
+++ b/src/Http/web.php
@@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Route;
use Lucent\Http\Controller\AccountController;
use Lucent\Http\Controller\AuthController;
use Lucent\Http\Controller\BuildController;
+use Lucent\Http\Controller\EdgeController;
use Lucent\Http\Controller\FileController;
use Lucent\Http\Controller\HomeController;
use Lucent\Http\Controller\MemberController;
@@ -60,6 +61,11 @@ Route::group([
Route::post('/{rid}/rollback/{version}', [RecordController::class, 'rollback']);
});
+ Route::middleware(["lucent.auth"])->prefix("/edges")->group(function () {
+
+ Route::put('/', [EdgeController::class, 'update']);
+ });
+
Route::middleware(["lucent.auth"])->group(function () {
Route::get('/records/{rid}/revisions', [RevisionController::class, 'index']);
@@ -82,6 +88,5 @@ Route::group([
});
-
});
diff --git a/src/Lexorank/Lexorank.php b/src/Lexorank/Lexorank.php
index b81ad29..3c47ba1 100644
--- a/src/Lexorank/Lexorank.php
+++ b/src/Lexorank/Lexorank.php
@@ -10,7 +10,6 @@ use function ord;
use function strcmp;
use function substr;
-/** @psalm-immutable */
final class Lexorank
{
diff --git a/src/LucentServiceProvider.php b/src/LucentServiceProvider.php
index 42a3b80..7f9fe08 100644
--- a/src/LucentServiceProvider.php
+++ b/src/LucentServiceProvider.php
@@ -16,6 +16,7 @@ use Lucent\JsonSchema\Command\GenerateJsonSchema;
use Lucent\Query\DatabaseGraph\DatabaseGraph;
use Lucent\Query\DatabaseGraph\PgsqlDatabaseGraph;
use Lucent\Query\DatabaseGraph\SqliteDatabaseGraph;
+use Lucent\Query\Query;
use Lucent\Schema\Commands\CompileSchemas;
class LucentServiceProvider extends ServiceProvider
@@ -33,6 +34,8 @@ class LucentServiceProvider extends ServiceProvider
return new ImageManager(['driver' => 'imagick']);
});
+
+
$this->app->bind(DatabaseGraph::class, function () {
return match (config("lucent.database")) {
"sqlite" => new SqliteDatabaseGraph(),
@@ -61,17 +64,17 @@ class LucentServiceProvider extends ServiceProvider
$this->loadViewsFrom(__DIR__ . '/Views', 'lucent');
$this->loadRoutesFrom(__DIR__ . '/Http/web.php');
- $this->loadRoutesFrom(__DIR__ . '/Http/api.php');
+// $this->loadRoutesFrom(__DIR__ . '/Http/api.php');
$this->loadMigrationsFrom(__DIR__ . '/Database/migrations');
if ($this->app->runningInConsole()) {
$this->commands([
- CompileSchemas::class,
- RebuildThumbnails::class,
- LiveLink::class,
- RemoveOrphanEdges::class,
- GenerateJsonSchema::class,
+// CompileSchemas::class,
+// RebuildThumbnails::class,
+// LiveLink::class,
+// RemoveOrphanEdges::class,
+// GenerateJsonSchema::class,
]);
}
diff --git a/src/Query/Builder.php b/src/Query/Builder.php
new file mode 100644
index 0000000..ae57e0f
--- /dev/null
+++ b/src/Query/Builder.php
@@ -0,0 +1,237 @@
+ $filters
+ */
+ public function __construct(
+ public array $filters = [],
+ public int $limit = 20,
+ public int $skip = 0,
+ public int $childrenDepth = -1,
+ 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"],
+ public bool $withCount = false
+ )
+ {
+
+ }
+
+
+ public function filter(array $filterArguments): Builder
+ {
+ $this->filters[] = new AndFilter($filterArguments);
+ return $this;
+ }
+
+ public function orFilter(array $filterArguments): Builder
+ {
+ $this->filters[] = new OrFilter($filterArguments);
+ return $this;
+ }
+
+ public function limit(int $limit): Builder
+ {
+ $this->limit = $limit;
+ return $this;
+ }
+
+ public function skip(int $skip): Builder
+ {
+ $this->skip = $skip;
+ return $this;
+ }
+
+ public function childrenDepth(int $depth): Builder
+ {
+ $this->childrenDepth = $depth;
+ return $this;
+ }
+
+ public function childrenLimit(int $limit): Builder
+ {
+ $this->childrenLimit = $limit;
+ return $this;
+ }
+
+ public function childrenFields(array $fields): Builder
+ {
+ $this->childrenFields = $fields;
+ return $this;
+ }
+
+ public function parentFields(array $fields): Builder
+ {
+ $this->parentFields = $fields;
+ return $this;
+ }
+
+ public function parentsDepth(int $depth): Builder
+ {
+ $this->parentsDepth = $depth;
+ return $this;
+ }
+
+ public function parentsLimit(int $limit): Builder
+ {
+ $this->parentsLimit = $limit;
+ return $this;
+ }
+
+
+ public function sort(string $sort): Builder
+ {
+ $this->sort[] = $sort;
+ return $this;
+ }
+
+ public function status(array $status): Builder
+ {
+ $this->status = $status;
+ return $this;
+ }
+
+ public function withCount(): Builder
+ {
+
+ $this->withCount = true;
+ return $this;
+ }
+
+
+
+ public function resolveRecordFilters(LaravelBuilder $laravelBuilder): LaravelBuilder
+ {
+ foreach ($this->filters as $filter) {
+ $groupFilters = $this->groupFilters($filter);
+ $filterParser = new FilterParser();
+ $arguments = $filterParser->formatArguments($groupFilters->record);
+ $laravelBuilder = match (get_class($filter)) {
+ AndFilter::class => $this->parseAnd($laravelBuilder, $arguments),
+ OrFilter::class => $this->parseOr($laravelBuilder, $arguments),
+ };
+ }
+ return $laravelBuilder;
+ }
+
+ public function resolveReferenceFilters(LaravelBuilder $laravelBuilder): LaravelBuilder
+ {
+ foreach ($this->filters as $filter) {
+ $groupFilters = $this->groupFilters($filter);
+ $filterParser = new FilterParser();
+ if(empty($groupFilters->reference)){
+ break;
+ }
+ $arguments[] = $filterParser->formatReferencesArguments($groupFilters->reference);
+ $laravelBuilder = match (get_class($filter)) {
+ AndFilter::class => $this->parseAnd($laravelBuilder, $arguments),
+ OrFilter::class => $this->parseOr($laravelBuilder, $arguments),
+ };
+ }
+ return $laravelBuilder;
+ }
+
+ public function resolveEdgeFilters(LaravelBuilder $laravelBuilder): LaravelBuilder
+ {
+ foreach ($this->filters as $filter) {
+ $groupFilters = $this->groupFilters($filter);
+ if(empty($groupFilters->edge)){
+ break;
+ }
+ $filterParser = new FilterParser();
+ $arguments[] = $filterParser->formatEdgesArguments($groupFilters->edge);
+ $laravelBuilder = match (get_class($filter)) {
+ AndFilter::class => $this->parseAnd($laravelBuilder, $arguments),
+ OrFilter::class => $this->parseOr($laravelBuilder, $arguments),
+ };
+ }
+ return $laravelBuilder;
+ }
+
+ private function groupFilters(Filter $arguments): FilterGroup
+ {
+ return collect($arguments->toArray())->reduce(function ($c, $v, $k) {
+
+ if (str_starts_with($k, "children.")) {
+ $c->reference[$k] = $v;
+ return $c;
+ }
+ if (str_starts_with($k, "edges.")) {
+ $c->edge[$k] = $v;
+ return $c;
+ }
+ $c->record[$k] = $v;
+ return $c;
+ }, new FilterGroup());
+ }
+
+
+ /**
+ * @param array $arguments
+ */
+ private function parseAnd(LaravelBuilder $builder, array $arguments): LaravelBuilder
+ {
+ foreach ($arguments as $argument) {
+ if ($argument->operator == "in") {
+ $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;
+ }
+
+ /**
+ * @param array $arguments
+ */
+ private function parseOr(LaravelBuilder $builder, array $arguments): LaravelBuilder
+ {
+ $builder->where(function (LaravelBuilder $orBuilder) use ($arguments) {
+ foreach ($arguments as $argument) {
+ if ($argument->operator == "in") {
+ $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]);
+ // 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;
+ }
+}
\ No newline at end of file
diff --git a/src/Query/Filter/AndFilter.php b/src/Query/Data/AndFilter.php
similarity index 87%
rename from src/Query/Filter/AndFilter.php
rename to src/Query/Data/AndFilter.php
index 6e9c36b..adb74b2 100644
--- a/src/Query/Filter/AndFilter.php
+++ b/src/Query/Data/AndFilter.php
@@ -1,6 +1,6 @@
$ids
- * @return Collection
+ * @return Collection
*/
- public function getChildren(array $ids, QueryOptions $options): Collection;
+ public function getChildren(array $ids, Builder $options): Collection;
/**
* @param array $ids
- * @return Collection
+ * @return Collection
*/
- public function getParents(array $ids, QueryOptions $options): Collection;
+ public function getParents(array $ids, Builder $options): Collection;
}
\ No newline at end of file
diff --git a/src/Query/DatabaseGraph/PgsqlDatabaseGraph.php b/src/Query/DatabaseGraph/PgsqlDatabaseGraph.php
index a126d97..1b09370 100644
--- a/src/Query/DatabaseGraph/PgsqlDatabaseGraph.php
+++ b/src/Query/DatabaseGraph/PgsqlDatabaseGraph.php
@@ -3,23 +3,24 @@
namespace Lucent\Query\DatabaseGraph;
use Illuminate\Support\Facades\DB;
-use Lucent\Edge\Edge;
-use Lucent\Query\QueryOptions;
+use Lucent\Query\Builder;
use Lucent\Support\Collection;
+use stdClass;
class PgsqlDatabaseGraph implements DatabaseGraph
{
-
/**
* @param array $ids
- * @return Collection
+ * @return Collection
*/
- public function getChildren(array $ids, QueryOptions $options): Collection
+ public function getChildren(array $ids, Builder $options): Collection
{
$subquery = DB::table('edges AS g')
- ->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
+ ->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,g.data, 1 as depth '))
->whereIn('source', $ids);
+ $subquery = $options->resolveEdgeFilters($subquery);
+
if (!empty($options->childrenFields)) {
$subquery->whereIn('field', $options->childrenFields);
}
@@ -27,7 +28,7 @@ class PgsqlDatabaseGraph implements DatabaseGraph
$subquery->limit($options->childrenLimit)
->union(
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')
+ ->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,g.data,sg.depth + 1 as depth')
->whereRaw("g.source = sg.target")
->where("depth", "<", $options->childrenDepth)
->orderBy("rank")
@@ -36,19 +37,21 @@ class PgsqlDatabaseGraph implements DatabaseGraph
return new Collection(DB::table('search_graph')
// ->select(DB::raw("*, 1 as depth "))
->withRecursiveExpression('search_graph', $subquery)
- ->get()->map([Edge::class, 'fromDB']));
+ ->get());
}
/**
* @param array $ids
- * @return Collection
+ * @return Collection
*/
- public function getParents(array $ids, QueryOptions $options): Collection
+ public function getParents(array $ids, Builder $options): Collection
{
$subquery = DB::table('edges AS g')
- ->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
+ ->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,g.data, 1 as depth '))
->whereIn('g.target', $ids);
+ $subquery = $options->resolveEdgeFilters($subquery);
+
if (!empty($options->parentFields)) {
$subquery->whereIn('field', $options->parentFields);
}
@@ -57,7 +60,7 @@ class PgsqlDatabaseGraph implements DatabaseGraph
->limit($options->parentsLimit)
->union(
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')
+ ->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,g.data,sg.depth + 1 as depth')
->whereRaw("g.target = sg.source")
->where("depth", "<", $options->parentsDepth)
->orderBy("rank")
@@ -66,6 +69,6 @@ class PgsqlDatabaseGraph implements DatabaseGraph
return new Collection(DB::table('search_graph')
// ->select(DB::raw('sg.source,sg.target,sg.rank,sg."sourceSchema",sg."targetSchema",sg.field,sg.depth'))
->withRecursiveExpression('search_graph', $subquery)
- ->get()->map([Edge::class, 'fromDB']));
+ ->get());
}
}
\ No newline at end of file
diff --git a/src/Query/DatabaseGraph/SqliteDatabaseGraph.php b/src/Query/DatabaseGraph/SqliteDatabaseGraph.php
index 9342bd3..e050701 100644
--- a/src/Query/DatabaseGraph/SqliteDatabaseGraph.php
+++ b/src/Query/DatabaseGraph/SqliteDatabaseGraph.php
@@ -3,22 +3,26 @@
namespace Lucent\Query\DatabaseGraph;
use Illuminate\Support\Facades\DB;
-use Lucent\Edge\Edge;
-use Lucent\Query\QueryOptions;
+use Lucent\Query\Builder;
+
use Lucent\Support\Collection;
+use stdClass;
class SqliteDatabaseGraph implements DatabaseGraph
{
+
/**
* @param array $ids
- * @return Collection
+ * @return Collection
*/
- public function getChildren(array $ids, QueryOptions $options): Collection
+ public function getChildren(array $ids, Builder $options):Collection
{
$subquery = DB::table('edges AS g')
- ->select(DB::raw('g.source,g.target,g.rank,g.sourceSchema,g.targetSchema,g.field, 1 as depth '))
+ ->select(DB::raw('g.source,g.target,g.rank,g.sourceSchema,g.targetSchema,g.field,g.data, 1 as depth '))
->whereIn('source', $ids);
+ $subquery = $options->resolveEdgeFilters($subquery);
+
if (!empty($options->childrenFields)) {
$subquery->whereIn('field', $options->childrenFields);
}
@@ -26,7 +30,7 @@ class SqliteDatabaseGraph implements DatabaseGraph
$subquery->limit($options->childrenLimit)
->union(
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')
+ ->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,g.data,sg.depth + 1 as depth')
->whereRaw("g.source = sg.target")
->where("depth", "<", $options->childrenDepth)
->orderBy("rank")
@@ -35,19 +39,20 @@ class SqliteDatabaseGraph implements DatabaseGraph
return new Collection(DB::table('search_graph')
// ->select(DB::raw("*, 1 as depth "))
->withRecursiveExpression('search_graph', $subquery)
- ->get()->map([Edge::class, 'fromDB']));
+ ->get());
}
/**
* @param array $ids
- * @return Collection
+ * @return Collection
*/
- public function getParents(array $ids, QueryOptions $options): Collection
+ public function getParents(array $ids, Builder $options):Collection
{
$subquery = DB::table('edges AS g')
- ->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field, 1 as depth '))
+ ->select(DB::raw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,g.data, 1 as depth '))
->whereIn('g.target', $ids);
+ $subquery = $options->resolveEdgeFilters($subquery);
if (!empty($options->parentFields)) {
$subquery->whereIn('field', $options->parentFields);
}
@@ -56,7 +61,7 @@ class SqliteDatabaseGraph implements DatabaseGraph
->limit($options->parentsLimit)
->union(
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')
+ ->selectRaw('g.source,g.target,g.rank,"g"."sourceSchema","g"."targetSchema",g.field,g.data,sg.depth + 1 as depth')
->whereRaw("g.target = sg.source")
->where("depth", "<", $options->parentsDepth)
->orderBy("rank")
@@ -65,6 +70,6 @@ class SqliteDatabaseGraph implements DatabaseGraph
return new Collection(DB::table('search_graph')
// ->select(DB::raw('sg.source,sg.target,sg.rank,sg."sourceSchema",sg."targetSchema",sg.field,sg.depth'))
->withRecursiveExpression('search_graph', $subquery)
- ->get()->map([Edge::class, 'fromDB']));
+ ->get());
}
}
\ No newline at end of file
diff --git a/src/Query/FilterParser.php b/src/Query/FilterParser.php
index cbcaa41..abb4e66 100644
--- a/src/Query/FilterParser.php
+++ b/src/Query/FilterParser.php
@@ -2,29 +2,24 @@
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;
+use Lucent\Query\Data\Argument;
final class FilterParser
{
- public function __construct(public Application $app)
+ public function __construct()
{
}
-
/**
* @param array $arguments
* @return array
*/
- private function formatArguments(array $arguments): array
+ public function formatArguments(array $arguments): array
{
return collect($arguments)->reduce(function ($c, $v, $k) {
+
$c[] = $this->formatArgument($v, $k);
return $c;
}, []);
@@ -32,7 +27,6 @@ final class FilterParser
private function formatArgument(mixed $value, string $filter): Argument
{
-
$operator = $this->detectOperator($filter);
$field = $this->detectField($filter, $operator);
@@ -92,21 +86,21 @@ final class FilterParser
private function formatListNum(mixed $value): array
{
- if (\is_string($value)) {
+ if (is_string($value)) {
$value = explode(",", $value);
}
- return \array_map(fn($v) => $this->formatNumber($v), $value);
+ return array_map(fn($v) => $this->formatNumber($v), $value);
}
private function detectOperator(string $filter): string
{
- $exploded = \explode("_", $filter);
+ $exploded = explode("_", $filter);
$candidate = end($exploded);
$operatorsListNames = collect(Operator::list())->map(fn($o) => $o->name)->toArray();
- if (\in_array($candidate, $operatorsListNames)) {
+ if (in_array($candidate, $operatorsListNames)) {
return $candidate;
}
return 'eq';
@@ -123,29 +117,22 @@ final class FilterParser
return $filter;
}
-
- private function formatReferences(array $referenceArguments): Argument
+ public function formatEdgesArguments(array $edgesArguments): Argument
{
- $subqueries = collect($referenceArguments)->reduce(function ($c, $v, $k) {
- $keyWithoutRef = str_replace("children.", "", $k);
+ $subqueries = collect($edgesArguments)->reduce(function ($c, $v, $k) {
+ $keyWithoutRef = str_replace("edges.", "", $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");
+ $laravelBuilder = DB::table("edges");
+ $queryBuilder = new Builder();
+ $queryBuilder->filter($subquery);
+ $laravelBuilder = $queryBuilder->resolveRecordFilters($laravelBuilder);
+ $sourceIds = $laravelBuilder->where("field", $k)->get()->pluck("source");
return array_merge($c, $sourceIds->toArray());
}, []);
@@ -157,96 +144,42 @@ final class FilterParser
}
- private function separateMainFromReferenceArguments(Filter $arguments): array
+
+ public function formatReferencesArguments(array $referenceArguments): Argument
{
- return collect($arguments->toArray())->partition(function ($v, $k) {
- if (!str_starts_with($k, "children.")) {
- return true;
+ $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) {
+ $laravelBuilder = DB::table("records");
+ $queryBuilder = new Builder();
+ $queryBuilder->filter($subquery);
+ $laravelBuilder = $queryBuilder->resolveRecordFilters($laravelBuilder);
+ $res = $laravelBuilder->get();
+
+ if ($res->isEmpty()) {
+ return $c;
}
- return false;
- })->toArray();
+
+ $targetIds = $res->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
+ );
+
}
-
-
- /**
- * @return array
- */
- 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 $arguments
- */
- private function parseAnd(Builder $builder, array $arguments): Builder
- {
- foreach ($arguments as $argument) {
- if ($argument->operator == "in") {
- $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;
- }
-
- /**
- * @param array $arguments
- */
- private function parseOr(Builder $builder, array $arguments): Builder
- {
- $builder->where(function (Builder $orBuilder) use ($arguments) {
- foreach ($arguments as $argument) {
- if ($argument->operator == "in") {
- $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;
- }
-
-
}
diff --git a/src/Query/Graph.php b/src/Query/Graph.php
index dd6d10c..bd7a61c 100644
--- a/src/Query/Graph.php
+++ b/src/Query/Graph.php
@@ -2,9 +2,9 @@
namespace Lucent\Query;
-use Lucent\Edge\Edge;
-use Lucent\Record\QueryRecord;
-use Lucent\Record\Record;
+use Lucent\Graph\Edge\Edge;
+use Lucent\Graph\Record\QueryRecord;
+use Lucent\Graph\Record\Record;
use Lucent\Support\Collection;
use Lucent\Support\Option\Option;
@@ -21,7 +21,7 @@ final class Graph
public Collection $records,
public Collection $edges,
public Collection $parentEdges,
- public QueryOptions $queryOptions,
+ public Builder $queryBuilder,
public ?int $total = null,
)
{
@@ -40,7 +40,7 @@ final class Graph
public function hasResults(): bool
{
- return !empty($this->records);
+ return $this->rootRecords->isNotEmpty();
}
public function tree(): Collection
@@ -54,16 +54,16 @@ final class Graph
public function findChildren(QueryRecord $record, int $depth = 1): QueryRecord
{
- if ($this->queryOptions->childrenDepth < $depth) {
+ if ($this->queryBuilder->childrenDepth < $depth) {
return $record;
}
$record->_children = $this->edges
->filter(fn(Edge $ed) => $ed->source === $record->record->id)
- ->unique(fn(Edge $ed) => $ed->targetSchema . $ed->field . $ed->target . $ed->source)
+ ->unique(fn(Edge $ed) => $ed->field . $ed->target . $ed->source)
->sort(fn($a, $b) => $a->rank <=> $b->rank)
->values()
->map(function (Edge $edge): Option {
- $records = $this->records->filter(fn(Record $rec) => $rec->id == $edge->target)->values();
+ $records = $this->records->filter(fn(Record $rec) => $rec->id === $edge->target)->values();
if ($records->isEmpty()) {
return none();
}
@@ -82,7 +82,7 @@ final class Graph
public function findParents(QueryRecord $record, int $depth = 1): QueryRecord
{
- if ($this->queryOptions->parentsDepth < $depth) {
+ if ($this->queryBuilder->parentsDepth < $depth) {
return $record;
}
$record->_parents = $this->parentEdges
diff --git a/src/Query/Operator.php b/src/Query/Operator.php
index 879e6cd..3912ac9 100644
--- a/src/Query/Operator.php
+++ b/src/Query/Operator.php
@@ -6,7 +6,7 @@ namespace Lucent\Query;
final class Operator
{
/**
- * @psalm-param string[] $uis
+ * @param string[] $uis
*/
public function __construct(
public string $name,
diff --git a/src/Query/Query.php b/src/Query/Query.php
index d38108f..6ae727d 100644
--- a/src/Query/Query.php
+++ b/src/Query/Query.php
@@ -2,63 +2,41 @@
namespace Lucent\Query;
-use Illuminate\Database\Query\Builder;
+use Illuminate\Database\Query\Builder as LaravelBuilder;
use Illuminate\Support\Facades\DB;
+use Lucent\Graph\Record\Mapper;
+use Lucent\Graph\Edge\Mapper as EdgeMapper;
use Lucent\Query\DatabaseGraph\DatabaseGraph;
-use Lucent\Query\Filter\AndFilter;
-use Lucent\Query\Filter\OrFilter;
-use Lucent\Record\InputFormatter;
-use Lucent\Record\Mapper;
-use Lucent\Record\Record;
use Lucent\Support\Collection;
-final class Query
+final class Query
{
- /**
- * @var array $filters
- */
- public array $filters;
- public QueryOptions $options;
-
public function __construct(
- public readonly FilterParser $filterParser,
- public readonly InputFormatter $inputFormatter,
- public readonly DatabaseGraph $databaseGraph,
- public readonly Mapper $recordMapper,
+ public readonly FilterParser $filterParser,
+ public readonly DatabaseGraph $databaseGraph,
+ public readonly Mapper $recordMapper,
+ public readonly EdgeMapper $edgeMapper,
)
{
- $this->options = new QueryOptions();
}
- public function filter(array $filterArguments): Query
+ public function run(callable $builderFunc): Graph
{
- $this->filters[] = new AndFilter($filterArguments);
- return $this;
- }
-
- public function orFilter(array $filterArguments): Query
- {
- $this->filters[] = new OrFilter($filterArguments);
- return $this;
- }
-
-
- public function run(): Graph
- {
- $rootRecords = $this->mainQuery();
+ $builder = $builderFunc(new Builder());
+ [$rootRecords, $total] = $this->mainQuery($builder);
$ids = $rootRecords->pluck("id");
$resultChildrenEdgesTargetIds = [];
$resultChildrenEdges = new Collection();
- if ($this->options->childrenDepth > 0 && $ids->isNotEmpty()) {
- $resultChildrenEdges = $this->databaseGraph->getChildren($ids->toArray(), $this->options);
+ if ($builder->childrenDepth > 0 && $ids->isNotEmpty()) {
+ $resultChildrenEdges = $this->databaseGraph->getChildren($ids->toArray(), $builder)->map([$this->edgeMapper, 'fromDB']);
$resultChildrenEdgesTargetIds = $resultChildrenEdges->pluck("target");
}
$resultParentSourceTargetIds = [];
$resultParentEdges = new Collection();
- if ($this->options->parentsDepth > 0 && $ids->isNotEmpty()) {
- $resultParentEdges = $this->databaseGraph->getParents($ids->toArray(), $this->options);
+ if ($builder->parentsDepth > 0 && $ids->isNotEmpty()) {
+ $resultParentEdges = $this->databaseGraph->getParents($ids->toArray(), $builder)->map([$this->edgeMapper, 'fromDB']);
$resultParentSourceTargetIds = $resultParentEdges->pluck("source");
}
@@ -67,7 +45,7 @@ final class Query
if (!empty($edgesIds)) {
$edgeRecords = new Collection(DB::table('records')
->whereIn("id", $edgesIds)
- ->whereIn("status", $this->options->status)
+ ->whereIn("status", $builder->status)
->get()->map([$this->recordMapper, 'fromDB']));
}
@@ -76,127 +54,43 @@ final class Query
$edgeRecords,
$resultChildrenEdges,
$resultParentEdges,
- $this->options
+ $builder,
+ $total
);
- $this->reset();
return $graph;
-
}
- private function reset(): void
- {
- $this->options = new QueryOptions();
- $this->filters = [];
- }
- public function tree(): Collection
- {
- return $this->run()->tree();
- }
-
- private function parseFilters(Builder $query): Builder
- {
- foreach ($this->filters as $filter) {
- $query = $this->filterParser->parse($query, $filter);
- }
- $query->whereIn("status", $this->options->status);
- return $query;
- }
/**
- * @return Collection
+ * @return array[Collection,?int]
*/
- private function mainQuery(): Collection
+ private function mainQuery(Builder $builder): array
{
$query = DB::table("records");
- $query = $this->parseFilters($query);
- if ($this->options->limit > 0) {
- $query->limit($this->options->limit);
- $query->offset($this->options->skip);
+ $query = $builder->resolveRecordFilters($query);
+ $query = $builder->resolveReferenceFilters($query);
+ $query = $builder->resolveEdgeFilters($query);
+ $query->whereIn("status", $builder->status);
+
+ $total = null;
+
+ if ($builder->withCount) {
+ $total = $query->count();
}
- $query = $this->orderByQuery($query);
- return new Collection($query->get()->map([$this->recordMapper, 'fromDB']));
+
+ if ($builder->limit > 0) {
+ $query->limit($builder->limit);
+ $query->offset($builder->skip);
+ }
+
+ $query = $this->orderByQuery($query, $builder);
+ return [new Collection($query->get()->map([$this->recordMapper, 'fromDB'])), $total];
}
-
- public
- function runWithCount(): Graph
+ public function orderByQuery(LaravelBuilder $query, Builder $builder): LaravelBuilder
{
-
- $query = DB::table("records");
- $query = $this->parseFilters($query);
- $graph = $this->run();
- $graph->total = $query->count();
- return $graph;
- }
-
-
- public function limit(int $limit): Query
- {
- $this->options->limit = $limit;
- return $this;
- }
-
- public
- function skip(int $skip): Query
- {
- $this->options->skip = $skip;
- return $this;
- }
-
- public function childrenDepth(int $depth): Query
- {
- $this->options->childrenDepth = $depth;
- return $this;
- }
-
- public function childrenLimit(int $limit): Query
- {
- $this->options->childrenLimit = $limit;
- 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;
- return $this;
- }
-
- public function parentsLimit(int $limit): Query
- {
- $this->options->parentsLimit = $limit;
- return $this;
- }
-
-
- public function sort(string $sort): Query
- {
- $this->options->sort[] = $sort;
- return $this;
- }
-
- public function status(array $status): Query
- {
- $this->options->status = $status;
- return $this;
- }
-
- public
- function orderByQuery(Builder $query): Builder
- {
- foreach ($this->options->sort as $item) {
+ foreach ($builder->sort as $item) {
$field = str_replace(".", "->", ltrim($item, '-'));
$dir = str_starts_with($item, '-') ? "desc" : "asc";
if ($field) {
diff --git a/src/Query/QueryOptions.php b/src/Query/QueryOptions.php
deleted file mode 100644
index 4c03aa0..0000000
--- a/src/Query/QueryOptions.php
+++ /dev/null
@@ -1,25 +0,0 @@
- response($result->success()->get(), $successCode ?? 200),
+ Success::class => response(toArray($result->success()->get()), $successCode ?? 200),
Error::class => response([
"error" => $result->error()->get()
], $errorCode ?? 400)
diff --git a/src/Revision/Revision.php b/src/Revision/Revision.php
index c4f83ad..1a80462 100644
--- a/src/Revision/Revision.php
+++ b/src/Revision/Revision.php
@@ -3,12 +3,10 @@
namespace Lucent\Revision;
use Illuminate\Support\Str;
-use Lucent\Edge\EdgeCollection;
-use Lucent\Record\FileInfo;
-use Lucent\Record\Record;
-use Lucent\Record\RecordData;
-use Lucent\Record\System;
-use PhpOption\Option;
+use Lucent\Graph\Data\FieldData;
+use Lucent\Graph\Edge\EdgeCollection;
+use Lucent\Graph\Record\Record;
+use Lucent\Graph\Record\System;
readonly class Revision
{
@@ -16,20 +14,16 @@ readonly class Revision
/**
* @param string $id
* @param string $recordId
- * @param string $schema
* @param System $_sys
- * @param RecordData $data
+ * @param FieldData $data
* @param EdgeCollection $_edges
- * @param Option $_file
*/
function __construct(
- public string $id,
- public string $recordId,
- public string $schema,
- public System $_sys,
- public RecordData $data,
- public EdgeCollection $_edges,
- public Option $_file,
+ public string $id,
+ public string $recordId,
+ public System $_sys,
+ public FieldData $data,
+ public EdgeCollection $_edges,
)
{
@@ -45,11 +39,9 @@ readonly class Revision
return new Revision(
id: (string)Str::uuid(),
recordId: $record->id,
- schema: $record->schema,
_sys: $record->_sys,
data: $record->data,
_edges: $edges,
- _file: empty($record->_file) ? none() : some($record->_file)
);
}
diff --git a/src/Revision/RevisionRepo.php b/src/Revision/RevisionRepo.php
index 163feb4..364edd7 100644
--- a/src/Revision/RevisionRepo.php
+++ b/src/Revision/RevisionRepo.php
@@ -3,10 +3,8 @@
namespace Lucent\Revision;
use Illuminate\Support\Facades\DB;
-use Lucent\Edge\EdgeCollection;
-use Lucent\Record\FileInfo;
-use Lucent\Record\RecordData;
-use Lucent\Record\System;
+use Lucent\Graph\Data\FieldData;
+use Lucent\Graph\Record\System;
use Lucent\Support\Collection;
use PhpOption\Option;
use stdClass;
@@ -77,11 +75,9 @@ class RevisionRepo
return [
"id" => $revision->id,
"recordId" => $revision->recordId,
- "schema" => $revision->schema,
"_sys" => json_encode($revision->_sys),
- "_file" => $revision->_file->map(fn($v) => json_encode($v))->getOrElse(null),
"data" => json_encode($revision->data),
- "_edges" => $revision->_edges->getOrElse(null)->toJson(),
+ "_edges" => $revision->_edges->toJson(),
];
}
@@ -92,11 +88,9 @@ class RevisionRepo
return new Revision(
id: $data->id,
recordId: $data->recordId,
- schema: $data->schema,
_sys: System::fromArray(json_decode($data->_sys, true)),
- data: new RecordData(json_decode($data->data, true)),
- _edges: Option::fromValue($data->_edges)->map([EdgeCollection::class,'fromJson']),
- _file: Option::fromValue($data->_file)->map([FileInfo::class,'fromJSON'])
+ data: new FieldData(json_decode($data->data, true)),
+ _edges: $data->_edges->fromJson($data->_edges),
);
}
}
diff --git a/src/Revision/RevisionService.php b/src/Revision/RevisionService.php
index 5b2f3c7..10f0c40 100644
--- a/src/Revision/RevisionService.php
+++ b/src/Revision/RevisionService.php
@@ -3,8 +3,8 @@
namespace Lucent\Revision;
use Lucent\Channel\ChannelService;
-use Lucent\Edge\EdgeCollection;
-use Lucent\Record\Record;
+use Lucent\Graph\Edge\EdgeCollection;
+use Lucent\Graph\Record\Record;
use Lucent\Support\Collection;
use PhpOption\Option;
@@ -13,7 +13,7 @@ readonly class RevisionService
public function __construct(
private ChannelService $channelService,
- private RevisionRepo $revisionRepo,
+ private RevisionRepo $revisionRepo,
)
{
}
@@ -42,15 +42,15 @@ readonly class RevisionService
* @param EdgeCollection $edges
* @return void
*/
- public function create(Record $record,EdgeCollection $edges): void
+ public function create(Record $record, EdgeCollection $edges): void
{
$schema = $this->channelService->getSchema($record->schema)->get();
- if($schema->revisions <= 0){
+ if ($schema->revisions <= 0) {
return;
}
$revision = Revision::fromRecord($record, $edges);
$this->revisionRepo->create($revision);
- $this->revisionRepo->cleanupRecord($record->id,$schema->revisions);
+ $this->revisionRepo->cleanupRecord($record->id, $schema->revisions);
}
diff --git a/src/Schema/BlockUi/Heading.php b/src/Schema/BlockUi/Heading.php
index dcfbf86..1e18e83 100644
--- a/src/Schema/BlockUi/Heading.php
+++ b/src/Schema/BlockUi/Heading.php
@@ -2,7 +2,7 @@
namespace Lucent\Schema\BlockUi;
-use Lucent\Record\RecordData;
+use Lucent\Graph\Data\FieldData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -23,7 +23,7 @@ class Heading implements FieldInterface,FieldDataInterface
$this->info = new FieldInfo("heading", "Heading", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
$output->set($this->name,$value);
diff --git a/src/Schema/BlockUi/Markdown.php b/src/Schema/BlockUi/Markdown.php
index 0be9082..0610237 100644
--- a/src/Schema/BlockUi/Markdown.php
+++ b/src/Schema/BlockUi/Markdown.php
@@ -2,7 +2,7 @@
namespace Lucent\Schema\BlockUi;
-use Lucent\Record\RecordData;
+use Lucent\Graph\Data\FieldData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -23,7 +23,7 @@ class Markdown implements FieldInterface,FieldDataInterface
$this->info = new FieldInfo("markdown", "Markdown Editor", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
$output->set($this->name,$value);
diff --git a/src/Schema/BlockUi/Rich.php b/src/Schema/BlockUi/Rich.php
index 31ec3af..d6ed33d 100644
--- a/src/Schema/BlockUi/Rich.php
+++ b/src/Schema/BlockUi/Rich.php
@@ -2,7 +2,7 @@
namespace Lucent\Schema\BlockUi;
-use Lucent\Record\RecordData;
+use Lucent\Graph\Data\FieldData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -23,7 +23,7 @@ class Rich implements FieldInterface,FieldDataInterface
$this->info = new FieldInfo("rich", "Rich Editor", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
$output->set($this->name,$value);
diff --git a/src/Schema/BlockUi/Textarea.php b/src/Schema/BlockUi/Textarea.php
index 35ff320..891252e 100644
--- a/src/Schema/BlockUi/Textarea.php
+++ b/src/Schema/BlockUi/Textarea.php
@@ -2,7 +2,7 @@
namespace Lucent\Schema\BlockUi;
-use Lucent\Record\RecordData;
+use Lucent\Graph\Data\FieldData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -23,7 +23,7 @@ class Textarea implements FieldInterface,FieldDataInterface
$this->info = new FieldInfo("textarea", "Textarea", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
$output->set($this->name,$value);
diff --git a/src/Schema/Field/FieldDataInterface.php b/src/Schema/Field/FieldDataInterface.php
index 0f6bc21..cc0241e 100644
--- a/src/Schema/Field/FieldDataInterface.php
+++ b/src/Schema/Field/FieldDataInterface.php
@@ -3,11 +3,11 @@
namespace Lucent\Schema\Field;
-use Lucent\Record\RecordData;
+use Lucent\Graph\Data\FieldData;
interface FieldDataInterface
{
- public function format(RecordData $input, RecordData $output): RecordData;
+ public function format(FieldData $input, FieldData $output): FieldData;
public function isRequired(): bool;
diff --git a/src/Schema/Ui/Block.php b/src/Schema/Ui/Block.php
index 9d01b87..875b737 100644
--- a/src/Schema/Ui/Block.php
+++ b/src/Schema/Ui/Block.php
@@ -2,10 +2,10 @@
namespace Lucent\Schema\Ui;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -31,7 +31,7 @@ class Block implements FieldInterface, FieldDataInterface, RequiredInterface
$this->info = new FieldInfo("block", "Block editor", FieldType::JSON);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
diff --git a/src/Schema/Ui/Checkbox.php b/src/Schema/Ui/Checkbox.php
index d976997..de211d8 100644
--- a/src/Schema/Ui/Checkbox.php
+++ b/src/Schema/Ui/Checkbox.php
@@ -2,10 +2,10 @@
namespace Lucent\Schema\Ui;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -33,7 +33,7 @@ class Checkbox implements FieldInterface,FieldDataInterface, RequiredInterface
$this->info = new FieldInfo("checkbox", "Block Checkbox", FieldType::BOOLEAN);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
diff --git a/src/Schema/Ui/Color.php b/src/Schema/Ui/Color.php
index 19e2d7e..ae527ad 100644
--- a/src/Schema/Ui/Color.php
+++ b/src/Schema/Ui/Color.php
@@ -2,10 +2,10 @@
namespace Lucent\Schema\Ui;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -34,7 +34,7 @@ class Color implements FieldInterface,FieldDataInterface, RequiredInterface
$this->info = new FieldInfo("color", "Color", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
$output->set($this->name,$value);
diff --git a/src/Schema/Ui/Date.php b/src/Schema/Ui/Date.php
index 43d28e1..81485a7 100644
--- a/src/Schema/Ui/Date.php
+++ b/src/Schema/Ui/Date.php
@@ -3,10 +3,10 @@
namespace Lucent\Schema\Ui;
use Carbon\Carbon;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -37,7 +37,7 @@ class Date implements FieldInterface,FieldDataInterface, RequiredInterface, MinM
$this->info = new FieldInfo("date", "Date", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
if (empty($value)) {
diff --git a/src/Schema/Ui/Datetime.php b/src/Schema/Ui/Datetime.php
index 0a305f5..da2bb6c 100644
--- a/src/Schema/Ui/Datetime.php
+++ b/src/Schema/Ui/Datetime.php
@@ -3,10 +3,10 @@
namespace Lucent\Schema\Ui;
use Carbon\Carbon;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -37,7 +37,7 @@ class Datetime implements FieldInterface,FieldDataInterface, RequiredInterface,
$this->info = new FieldInfo("datetime", "Datetime", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
if (empty($value)) {
diff --git a/src/Schema/Ui/Json.php b/src/Schema/Ui/Json.php
index 13ff423..5d7f3a2 100644
--- a/src/Schema/Ui/Json.php
+++ b/src/Schema/Ui/Json.php
@@ -2,10 +2,10 @@
namespace Lucent\Schema\Ui;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -32,7 +32,7 @@ class Json implements FieldInterface,FieldDataInterface, RequiredInterface
$this->info = new FieldInfo("json", "JSON", FieldType::JSON);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
diff --git a/src/Schema/Ui/Markdown.php b/src/Schema/Ui/Markdown.php
index 64383b5..af20ad6 100644
--- a/src/Schema/Ui/Markdown.php
+++ b/src/Schema/Ui/Markdown.php
@@ -2,10 +2,10 @@
namespace Lucent\Schema\Ui;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -32,7 +32,7 @@ class Markdown implements FieldInterface,FieldDataInterface, RequiredInterface
$this->info = new FieldInfo("markdown", "Markdown editor", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
$output->set($this->name,$value);
diff --git a/src/Schema/Ui/Number.php b/src/Schema/Ui/Number.php
index 6086c7d..33e9fbc 100644
--- a/src/Schema/Ui/Number.php
+++ b/src/Schema/Ui/Number.php
@@ -2,10 +2,10 @@
namespace Lucent\Schema\Ui;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -37,7 +37,7 @@ class Number implements FieldInterface, RequiredInterface,FieldDataInterface, Mi
$this->info = new FieldInfo("number", "Number", FieldType::NUMBER);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
if (!is_numeric($value)) {
diff --git a/src/Schema/Ui/Rich.php b/src/Schema/Ui/Rich.php
index e501cec..e37c87b 100644
--- a/src/Schema/Ui/Rich.php
+++ b/src/Schema/Ui/Rich.php
@@ -2,10 +2,10 @@
namespace Lucent\Schema\Ui;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -32,7 +32,7 @@ class Rich implements FieldInterface,FieldDataInterface, RequiredInterface
$this->info = new FieldInfo("rich", "Rich editor", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
$output->set($this->name,$value);
diff --git a/src/Schema/Ui/Slug.php b/src/Schema/Ui/Slug.php
index 6ad8c1b..ce87f08 100644
--- a/src/Schema/Ui/Slug.php
+++ b/src/Schema/Ui/Slug.php
@@ -3,10 +3,10 @@
namespace Lucent\Schema\Ui;
use Illuminate\Support\Str;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -34,7 +34,7 @@ class Slug implements FieldInterface,FieldDataInterface, RequiredInterface
$this->info = new FieldInfo("slug", "Slug", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
if (empty($value)) {
diff --git a/src/Schema/Ui/Text.php b/src/Schema/Ui/Text.php
index 330985c..6a15ae8 100644
--- a/src/Schema/Ui/Text.php
+++ b/src/Schema/Ui/Text.php
@@ -2,10 +2,10 @@
namespace Lucent\Schema\Ui;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -36,7 +36,7 @@ class Text implements FieldInterface,FieldDataInterface, RequiredInterface
$this->info = new FieldInfo("text", "Text", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
$output->set($this->name,$value);
diff --git a/src/Schema/Ui/Textarea.php b/src/Schema/Ui/Textarea.php
index 9e712fb..10ea88f 100644
--- a/src/Schema/Ui/Textarea.php
+++ b/src/Schema/Ui/Textarea.php
@@ -2,10 +2,10 @@
namespace Lucent\Schema\Ui;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -33,7 +33,7 @@ class Textarea implements FieldInterface,FieldDataInterface, RequiredInterface
$this->info = new FieldInfo("textarea", "Textarea", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
$output->set($this->name,$value);
diff --git a/src/Schema/Ui/Uuid.php b/src/Schema/Ui/Uuid.php
index 15d8c21..831424c 100644
--- a/src/Schema/Ui/Uuid.php
+++ b/src/Schema/Ui/Uuid.php
@@ -2,10 +2,10 @@
namespace Lucent\Schema\Ui;
+use Lucent\Graph\Data\FieldData;
use Lucent\JsonSchema\Property\Property;
use Lucent\JsonSchema\Property\PropertyType;
use Lucent\JsonSchema\Property\TypeProperty;
-use Lucent\Record\RecordData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Schema\Field\FieldInfo;
use Lucent\Schema\Field\FieldInterface;
@@ -30,7 +30,7 @@ class Uuid implements FieldInterface,FieldDataInterface, RequiredInterface
$this->info = new FieldInfo("uuid", "FieldType", FieldType::STRING);
}
- public function format(RecordData $input, RecordData $output): RecordData
+ public function format(FieldData $input, FieldData $output): FieldData
{
$value = $input->get($this->name);
$output->set($this->name,$value);
diff --git a/src/Schema/Validator/Validator.php b/src/Schema/Validator/Validator.php
index 2e9cccf..739c142 100644
--- a/src/Schema/Validator/Validator.php
+++ b/src/Schema/Validator/Validator.php
@@ -3,7 +3,7 @@
namespace Lucent\Schema\Validator;
use Lucent\Channel\ChannelService;
-use Lucent\Record\RecordData;
+use Lucent\Graph\Data\FieldData;
use Lucent\Schema\Field\FieldDataInterface;
use Lucent\Support\Collection;
use Lucent\Support\Option\Option;
@@ -23,8 +23,8 @@ class Validator
* @return Collection
*/
public function check(
- string $schemaName,
- RecordData $data,
+ string $schemaName,
+ FieldData $data,
): Collection
{
@@ -39,10 +39,10 @@ class Validator
/**
* @param FieldDataInterface $field
- * @param RecordData $recordData
+ * @param FieldData $recordData
* @return Option
*/
- public function validate(FieldDataInterface $field, RecordData $recordData): Option
+ public function validate(FieldDataInterface $field, FieldData $recordData): Option
{
$value = $recordData->get($field->name);