query rewrite
This commit is contained in:
@@ -3,25 +3,25 @@
|
|||||||
import {onDestroy, onMount} from "svelte";
|
import {onDestroy, onMount} from "svelte";
|
||||||
import offcanvas from "bootstrap/js/src/offcanvas.js";
|
import offcanvas from "bootstrap/js/src/offcanvas.js";
|
||||||
export let title = "";
|
export let title = "";
|
||||||
let offcanvasEl;
|
let offCanvasEl;
|
||||||
let offcanvasInstance;
|
let offCanvasInstance;
|
||||||
|
|
||||||
export function show() {
|
export function show() {
|
||||||
offcanvasInstance.show();
|
if(!offCanvasInstance){
|
||||||
|
offCanvasInstance = new offcanvas(offCanvasEl);
|
||||||
|
}
|
||||||
|
offCanvasInstance.show();
|
||||||
}
|
}
|
||||||
onMount(()=>{
|
onMount(()=>{
|
||||||
offcanvasInstance = new offcanvas(offcanvasEl);
|
offCanvasInstance = new offcanvas(offCanvasEl);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function hide() {
|
||||||
|
offCanvasInstance.hide();
|
||||||
export function hide(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
offcanvasInstance.hide();
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div bind:this={offcanvasEl} class="offcanvas offcanvas-end" tabindex="-1"
|
<div bind:this={offCanvasEl} class="offcanvas offcanvas-end" tabindex="-1"
|
||||||
aria-labelledby="offcanvasEditContent">
|
aria-labelledby="offcanvasEditContent">
|
||||||
<div class="offcanvas-header">
|
<div class="offcanvas-header">
|
||||||
<h5 class="offcanvas-title">{title}</h5>
|
<h5 class="offcanvas-title">{title}</h5>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
import Table from "./Table.svelte";
|
import Table from "./Table.svelte";
|
||||||
import {getContext} from "svelte";
|
import {getContext} from "svelte";
|
||||||
import Grid from "./Grid.svelte";
|
import Grid from "./Grid.svelte";
|
||||||
|
import Tools from "./tools/Tools.svelte";
|
||||||
|
|
||||||
const axios = getContext("axios");
|
const axios = getContext("axios");
|
||||||
export let schema;
|
export let schema;
|
||||||
@@ -53,20 +54,19 @@
|
|||||||
{#if selected.length > 0 && !inModal && isWritable}
|
{#if selected.length > 0 && !inModal && isWritable}
|
||||||
<ActionsOnSelected {schema} {selected} {filter}/>
|
<ActionsOnSelected {schema} {selected} {filter}/>
|
||||||
{:else}
|
{:else}
|
||||||
<!-- <Tools-->
|
<Tools
|
||||||
<!-- bind:schema-->
|
bind:schema
|
||||||
<!-- bind:records-->
|
bind:records
|
||||||
<!-- {systemFields}-->
|
{systemFields}
|
||||||
<!-- {sortParam}-->
|
{sortParam}
|
||||||
<!-- {sortField}-->
|
{sortField}
|
||||||
<!-- {operators}-->
|
{operators}
|
||||||
<!-- {filter}-->
|
{filter}
|
||||||
<!-- {graph}-->
|
{inModal}
|
||||||
<!-- {inModal}-->
|
{modalUrl}
|
||||||
<!-- {modalUrl}-->
|
{isWritable}
|
||||||
<!-- {isWritable}-->
|
on:refresh={refresh}
|
||||||
<!-- on:refresh={refresh}-->
|
/>
|
||||||
<!-- />-->
|
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if schema.type === "collection"}
|
{#if schema.type === "collection"}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
export let value;
|
export let value;
|
||||||
export let inModal;
|
export let inModal;
|
||||||
export let modalUrl;
|
export let modalUrl;
|
||||||
export let graph;
|
export let records
|
||||||
|
|
||||||
let filter = {
|
let filter = {
|
||||||
label: "",
|
label: "",
|
||||||
@@ -51,13 +51,13 @@
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const filterRecord = extractFilterRecord(graph, value);
|
const filterRecord = extractFilterRecord(records, value);
|
||||||
|
|
||||||
function extractFilterRecord(graph, value) {
|
function extractFilterRecord(records, value) {
|
||||||
if (!filter.isReference) {
|
if (!filter.isReference) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return graph.records.find(r => r.id === value);
|
return records.find(r => r.id === value);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeFilter(k) {
|
function removeFilter(k) {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
export let modalUrl;
|
export let modalUrl;
|
||||||
export let isWritable;
|
export let isWritable;
|
||||||
export let records;
|
export let records;
|
||||||
export let graph;
|
|
||||||
export let systemFields = [];
|
export let systemFields = [];
|
||||||
// export let visibleFields = [];
|
// export let visibleFields = [];
|
||||||
|
|
||||||
@@ -37,7 +36,7 @@
|
|||||||
if (inModal) {
|
if (inModal) {
|
||||||
dispatch("refresh", url);
|
dispatch("refresh", url);
|
||||||
} else {
|
} else {
|
||||||
window.location = url;
|
window.location.href = url;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -152,7 +151,7 @@
|
|||||||
value={v}
|
value={v}
|
||||||
{inModal}
|
{inModal}
|
||||||
{modalUrl}
|
{modalUrl}
|
||||||
{graph}
|
{records}
|
||||||
on:refresh
|
on:refresh
|
||||||
/>
|
/>
|
||||||
{/each}
|
{/each}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
// export let isWritable = false;
|
// export let isWritable = false;
|
||||||
// export let users;
|
// export let users;
|
||||||
$: validationErrors = null;
|
$: validationErrors = null;
|
||||||
|
$: errorMessage = null;
|
||||||
|
|
||||||
let form;
|
let form;
|
||||||
|
|
||||||
@@ -90,6 +91,8 @@
|
|||||||
{schema}
|
{schema}
|
||||||
{record}
|
{record}
|
||||||
{isCreateMode}
|
{isCreateMode}
|
||||||
|
{errorMessage}
|
||||||
|
{validationErrors}
|
||||||
on:save={save}
|
on:save={save}
|
||||||
/>
|
/>
|
||||||
<!-- <Graph {graph} {record}/>-->
|
<!-- <Graph {graph} {record}/>-->
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<h3 class="header-normal mt-5 mb-0">
|
<h3 class="header-normal mb-0">
|
||||||
<a
|
<a
|
||||||
class="text-muted d-block text-decoration-none fs-6 mb-1"
|
class="text-muted d-block text-decoration-none fs-6 mb-1"
|
||||||
href="{channel.lucentUrl}/content/{schema.name}"
|
href="{channel.lucentUrl}/content/{schema.name}"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
const channel = getContext("channel");
|
const channel = getContext("channel");
|
||||||
export let record;
|
export let record;
|
||||||
export let field;
|
export let field;
|
||||||
export let edge;
|
export let edge = null;
|
||||||
export let editable = false;
|
export let editable = false;
|
||||||
export let classes = "";
|
export let classes = "";
|
||||||
export let hasDelete = false;
|
export let hasDelete = false;
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<EdgeData bind:this={edgeData} {field} {edge}/>
|
<EdgeData bind:this={edgeData} {record} {field} bind:edge/>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { deepEqual } from 'fast-equals';
|
import { deepEqual } from 'fast-equals';
|
||||||
export function isEqual(obj1, obj2) {
|
export function isEqual(obj1, obj2) {
|
||||||
|
|
||||||
return deepEqual(obj1, obj2);
|
return deepEqual(obj1, obj2);
|
||||||
// if (obj1 === obj2) return true;
|
// if (obj1 === obj2) return true;
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -7,14 +7,12 @@
|
|||||||
import ReferenceField from "./ReferenceField.svelte";
|
import ReferenceField from "./ReferenceField.svelte";
|
||||||
import SaveButtons from "./SaveButtons.svelte";
|
import SaveButtons from "./SaveButtons.svelte";
|
||||||
import EditHeader from "../EditHeader.svelte";
|
import EditHeader from "../EditHeader.svelte";
|
||||||
|
|
||||||
const dispatch = createEventDispatcher();
|
const dispatch = createEventDispatcher();
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
dispatch("save", {
|
dispatch("save", {
|
||||||
status: status
|
status: status
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export let title = null;
|
export let title = null;
|
||||||
@@ -27,19 +25,18 @@
|
|||||||
let originalContent;
|
let originalContent;
|
||||||
let activeContentTab = "";
|
let activeContentTab = "";
|
||||||
$: hasUnsavedData = false;
|
$: hasUnsavedData = false;
|
||||||
$: validationErrors = null;
|
export let validationErrors = null;
|
||||||
$: errorMessage = validationErrors
|
export let errorMessage = validationErrors
|
||||||
? `Record submission failed. ${
|
? `Record submission failed. ${
|
||||||
Object.entries(validationErrors).length
|
Object.entries(validationErrors).length
|
||||||
} error(s)`
|
} error(s)`
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
|
|
||||||
export function setOriginalData() {
|
export function setOriginalData() {
|
||||||
originalContent = {
|
originalContent = {
|
||||||
data: JSON.parse(JSON.stringify(data)),
|
data: JSON.parse(JSON.stringify(data)),
|
||||||
status: status,
|
status: status,
|
||||||
edges: JSON.parse(JSON.stringify(graph.map(r => r.edge))),
|
edges: JSON.parse(JSON.stringify(graph?.map(r => r.edge.target+r.edge.field) ?? [])),
|
||||||
};
|
};
|
||||||
hasUnsavedData = checkUnsavedData();
|
hasUnsavedData = checkUnsavedData();
|
||||||
|
|
||||||
@@ -49,7 +46,6 @@
|
|||||||
setOriginalData()
|
setOriginalData()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
afterUpdate(() => {
|
afterUpdate(() => {
|
||||||
hasUnsavedData = checkUnsavedData();
|
hasUnsavedData = checkUnsavedData();
|
||||||
});
|
});
|
||||||
@@ -79,11 +75,9 @@
|
|||||||
return !isEqual(originalContent, {
|
return !isEqual(originalContent, {
|
||||||
data: data,
|
data: data,
|
||||||
status: status,
|
status: status,
|
||||||
edges: graph.map(r => r.edge),
|
edges: graph?.map(r => r.edge.target+r.edge.field) ?? [],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window on:beforeunload={beforeUnload}/>
|
<svelte:window on:beforeunload={beforeUnload}/>
|
||||||
|
|||||||
@@ -3,13 +3,16 @@
|
|||||||
import {getContext} from "svelte";
|
import {getContext} from "svelte";
|
||||||
import Form from "../Form.svelte";
|
import Form from "../Form.svelte";
|
||||||
import OffCanvas from "../../../common/OffCanvas.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 field;
|
||||||
|
export let record;
|
||||||
export let edge;
|
export let edge;
|
||||||
let form;
|
let form;
|
||||||
let offCanvas;
|
let offCanvas;
|
||||||
|
$: validationErrors = null;
|
||||||
|
$: errorMessage = null;
|
||||||
const channel = getContext("channel");
|
const channel = getContext("channel");
|
||||||
let schema = channel.schemas.find(s => s.name === field.data);
|
let schema = channel.schemas.find(s => s.name === field.data);
|
||||||
|
|
||||||
@@ -17,20 +20,56 @@
|
|||||||
offCanvas.show();
|
offCanvas.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
function save(e){
|
function save(e){
|
||||||
e.preventDefault();
|
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);
|
||||||
|
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<OffCanvas bind:this={offCanvas}>
|
<OffCanvas bind:this={offCanvas}>
|
||||||
|
<div class="p-4">
|
||||||
|
<PreviewCard
|
||||||
|
{record}
|
||||||
|
hasDelete={false}
|
||||||
|
editable={false}
|
||||||
|
{field}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<Form
|
<Form
|
||||||
bind:this={form}
|
bind:this={form}
|
||||||
data={edge.data}
|
data={edge.data}
|
||||||
|
title={"Relational Data for " + field.info.label}
|
||||||
{schema}
|
{schema}
|
||||||
isCreateMode={false}
|
isCreateMode={false}
|
||||||
|
{errorMessage}
|
||||||
|
{validationErrors}
|
||||||
on:save={save}
|
on:save={save}
|
||||||
/>
|
/>
|
||||||
</OffCanvas>
|
</OffCanvas>
|
||||||
|
|||||||
@@ -88,7 +88,7 @@
|
|||||||
hasDelete={true}
|
hasDelete={true}
|
||||||
editable={!!field?.data}
|
editable={!!field?.data}
|
||||||
{field}
|
{field}
|
||||||
edge={reference.edge}
|
bind:edge={reference.edge}
|
||||||
on:remove={removeReference}
|
on:remove={removeReference}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ export function insertEdges(existingRecords, sourceRecord, targetRecords, fieldN
|
|||||||
sourceSchema: sourceRecord.schema,
|
sourceSchema: sourceRecord.schema,
|
||||||
targetSchema: r.schema,
|
targetSchema: r.schema,
|
||||||
field: fieldName,
|
field: fieldName,
|
||||||
|
data: {},
|
||||||
rank: ""
|
rank: ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
namespace Lucent\Commands;
|
namespace Lucent\Commands;
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Lucent\Edge\EdgeService;
|
use Lucent\Graph\Edge\EdgeService;
|
||||||
use Lucent\Query\Query;
|
use Lucent\Query\Query;
|
||||||
|
|
||||||
class RemoveOrphanEdges extends Command
|
class RemoveOrphanEdges extends Command
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ return new class extends Migration {
|
|||||||
$table->jsonb('_file');
|
$table->jsonb('_file');
|
||||||
$table->jsonb('_edges');
|
$table->jsonb('_edges');
|
||||||
});
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration {
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function up()
|
||||||
|
{
|
||||||
|
Schema::table('revisions', function (Blueprint $table) {
|
||||||
|
$table->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');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Lucent\Edge;
|
|
||||||
|
|
||||||
use Lucent\ArrayContainer;
|
|
||||||
|
|
||||||
class EdgeData extends ArrayContainer
|
|
||||||
{
|
|
||||||
|
|
||||||
public function merge(EdgeData $data): EdgeData
|
|
||||||
{
|
|
||||||
|
|
||||||
$this->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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,85 +0,0 @@
|
|||||||
<?php namespace Lucent\Edge;
|
|
||||||
|
|
||||||
use Illuminate\Support\Facades\DB;
|
|
||||||
use Lucent\LucentException;
|
|
||||||
use PDOException;
|
|
||||||
use PhpOption\Option;
|
|
||||||
use stdClass;
|
|
||||||
|
|
||||||
class EdgeRepo
|
|
||||||
{
|
|
||||||
|
|
||||||
public function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
<?php namespace Lucent\Edge;
|
|
||||||
|
|
||||||
use Lucent\LucentException;
|
|
||||||
use PhpOption\Option;
|
|
||||||
|
|
||||||
class EdgeService
|
|
||||||
{
|
|
||||||
public function __construct(public EdgeRepo $edgeRepo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -4,9 +4,9 @@ namespace Lucent\File;
|
|||||||
|
|
||||||
use Illuminate\Http\UploadedFile;
|
use Illuminate\Http\UploadedFile;
|
||||||
use Lucent\Channel\ChannelService;
|
use Lucent\Channel\ChannelService;
|
||||||
|
use Lucent\Graph\Record\FileInfo;
|
||||||
|
use Lucent\Graph\Record\QueryRecord;
|
||||||
use Lucent\LucentException;
|
use Lucent\LucentException;
|
||||||
use Lucent\Record\FileInfo;
|
|
||||||
use Lucent\Record\QueryRecord;
|
|
||||||
use Lucent\Schema\Schema\Schema;
|
use Lucent\Schema\Schema\Schema;
|
||||||
use Lucent\Schema\Schema\Type;
|
use Lucent\Schema\Schema\Type;
|
||||||
use Lucent\Support\Result\Result;
|
use Lucent\Support\Result\Result;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Lucent\File;
|
namespace Lucent\File;
|
||||||
|
|
||||||
use Lucent\Record\FileInfo;
|
use Lucent\Graph\Record\FileInfo;
|
||||||
|
|
||||||
class FileUploadResult
|
class FileUploadResult
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use Exception;
|
|||||||
use Illuminate\Log\Logger;
|
use Illuminate\Log\Logger;
|
||||||
use Intervention\Image\ImageManager;
|
use Intervention\Image\ImageManager;
|
||||||
use Lucent\Channel\ChannelService;
|
use Lucent\Channel\ChannelService;
|
||||||
use Lucent\Record\QueryRecord;
|
use Lucent\Graph\Record\QueryRecord;
|
||||||
|
|
||||||
class ImageService
|
class ImageService
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -9,8 +9,8 @@ use Illuminate\Support\Facades\DB;
|
|||||||
use Illuminate\Support\Facades\Storage;
|
use Illuminate\Support\Facades\Storage;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Intervention\Image\ImageManagerStatic;
|
use Intervention\Image\ImageManagerStatic;
|
||||||
|
use Lucent\Graph\Record\FileInfo as RecordFile;
|
||||||
use Lucent\LucentException;
|
use Lucent\LucentException;
|
||||||
use Lucent\Record\FileInfo as RecordFile;
|
|
||||||
use Lucent\Schema\Schema\Schema;
|
use Lucent\Schema\Schema\Schema;
|
||||||
use Spatie\ImageOptimizer\OptimizerChainFactory;
|
use Spatie\ImageOptimizer\OptimizerChainFactory;
|
||||||
|
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Data;
|
||||||
|
|
||||||
use Lucent\ArrayContainer;
|
use Lucent\ArrayContainer;
|
||||||
|
|
||||||
class RecordData extends ArrayContainer
|
class FieldData extends ArrayContainer
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
public function merge(RecordData $data): RecordData
|
public function merge(FieldData $data): FieldData
|
||||||
{
|
{
|
||||||
|
|
||||||
$this->data = array_merge($this->data, $data->toArray());
|
$this->data = array_merge($this->data, $data->toArray());
|
||||||
@@ -20,7 +20,7 @@ class RecordData extends ArrayContainer
|
|||||||
return $this->data[$key] ?? $default;
|
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;
|
$this->data[$key] = $value;
|
||||||
return $this;
|
return $this;
|
||||||
@@ -47,5 +47,13 @@ class RecordData extends ArrayContainer
|
|||||||
return $this->data;
|
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));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Data;
|
||||||
|
|
||||||
use Lucent\Channel\ChannelService;
|
use Lucent\Channel\ChannelService;
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
@@ -15,12 +15,13 @@ class InputFormatter
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function fill(string $schemaName, RecordData $input): RecordData
|
public function fill(string $schemaName, FieldData $input): FieldData
|
||||||
{
|
{
|
||||||
$schema = $this->channelService->getSchema($schemaName)->get();
|
$schema = $this->channelService->getSchema($schemaName)->get();
|
||||||
|
|
||||||
return $schema->fields
|
return $schema->fields
|
||||||
->filter(fn(FieldInterface $field)=> $field instanceof FieldDataInterface)
|
->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([]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Graph\Edge\Contracts;
|
||||||
|
|
||||||
|
class EdgeData
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public string $source,
|
||||||
|
public string $target,
|
||||||
|
public string $sourceSchema,
|
||||||
|
public string $targetSchema,
|
||||||
|
public string $field,
|
||||||
|
public array $data,
|
||||||
|
public string $rank,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,34 +1,30 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Edge;
|
namespace Lucent\Graph\Edge;
|
||||||
|
|
||||||
use Lucent\LucentException;
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\Validator\Validator as LucentValidator;
|
|
||||||
use PhpOption\Option;
|
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
final class Edge
|
final class Edge
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @param Option<EdgeData> $data
|
|
||||||
*/
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
|
|
||||||
public string $source,
|
public string $source,
|
||||||
public string $target,
|
public string $target,
|
||||||
public string $sourceSchema,
|
public string $sourceSchema,
|
||||||
public string $targetSchema,
|
public string $targetSchema,
|
||||||
public string $field,
|
public string $field,
|
||||||
public Option $data,
|
public FieldData $data,
|
||||||
public string $rank = "a",
|
public string $rank = "a",
|
||||||
public int $depth = 0,
|
public int $depth = 0,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public function equal(Edge $edge): bool
|
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
|
public function toArray(): array
|
||||||
@@ -46,14 +42,13 @@ final class Edge
|
|||||||
|
|
||||||
public static function fromArray(array $data): Edge
|
public static function fromArray(array $data): Edge
|
||||||
{
|
{
|
||||||
|
|
||||||
return new Edge(
|
return new Edge(
|
||||||
source: data_get($data, 'source'),
|
source: data_get($data, 'source'),
|
||||||
target: data_get($data, 'target'),
|
target: data_get($data, 'target'),
|
||||||
sourceSchema: data_get($data, 'sourceSchema'),
|
sourceSchema: data_get($data, 'sourceSchema'),
|
||||||
targetSchema: data_get($data, 'targetSchema'),
|
targetSchema: data_get($data, 'targetSchema'),
|
||||||
field: data_get($data, 'field'),
|
field: data_get($data, 'field'),
|
||||||
data: Option::fromValue(data_get($data,"data")),
|
data: FieldData::fromArray(data_get($data, "data", [])),
|
||||||
rank: data_get($data, 'rank'),
|
rank: data_get($data, 'rank'),
|
||||||
depth: data_get($data, 'depth', 0),
|
depth: data_get($data, 'depth', 0),
|
||||||
);
|
);
|
||||||
@@ -69,9 +64,11 @@ final class Edge
|
|||||||
sourceSchema: data_get($data, 'sourceSchema'),
|
sourceSchema: data_get($data, 'sourceSchema'),
|
||||||
targetSchema: data_get($data, 'targetSchema'),
|
targetSchema: data_get($data, 'targetSchema'),
|
||||||
field: data_get($data, 'field'),
|
field: data_get($data, 'field'),
|
||||||
data: Option::fromValue(data_get($data,"data")),
|
data: FieldData::fromJson($data->data ?? "{}"),
|
||||||
rank: data_get($data, 'rank'),
|
rank: data_get($data, 'rank'),
|
||||||
depth: data_get($data, 'depth', 0),
|
depth: data_get($data, 'depth', 0),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Edge;
|
namespace Lucent\Graph\Edge;
|
||||||
|
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @extends \Illuminate\Support\Collection<int|string, Edge>
|
* @extends Collection<int|string, Edge>
|
||||||
*/
|
*/
|
||||||
final class EdgeCollection extends Collection
|
final class EdgeCollection extends Collection
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct(
|
private function __construct(
|
||||||
Edge ...$array
|
Edge ...$array
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -25,10 +25,24 @@ final class EdgeCollection extends Collection
|
|||||||
return collect($this)->values()->toArray();
|
return collect($this)->values()->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function toDB(): array
|
||||||
|
{
|
||||||
|
return collect($this)->map(fn(Edge $edge) => $edge->toDB())->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<mixed|Edge> $data
|
||||||
|
* @return EdgeCollection
|
||||||
|
*/
|
||||||
public static function fromArray(array $data): EdgeCollection
|
public static function fromArray(array $data): EdgeCollection
|
||||||
{
|
{
|
||||||
$edges = collect($data)
|
$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);
|
->unique(fn(Edge $e) => $e->field . $e->source . $e->target);
|
||||||
return new EdgeCollection(...$edges);
|
return new EdgeCollection(...$edges);
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
<?php namespace Lucent\Graph\Edge;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
|
use Lucent\LucentException;
|
||||||
|
use PDOException;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
class EdgeRepo
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function replaceBySourceId(string $sourceId, EdgeCollection $edgeCollection): void
|
||||||
|
{
|
||||||
|
DB::transaction(function () use ($sourceId, $edgeCollection) {
|
||||||
|
DB::table("edges")->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();
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,95 @@
|
|||||||
|
<?php namespace Lucent\Graph\Edge;
|
||||||
|
|
||||||
|
use Lucent\Channel\ChannelService;
|
||||||
|
use Lucent\Graph\Edge\Contracts\EdgeData;
|
||||||
|
use Lucent\Graph\Record\Contracts\RecordEdgeData;
|
||||||
|
use Lucent\Graph\Record\Record;
|
||||||
|
use Lucent\LucentException;
|
||||||
|
use Lucent\Query\Query;
|
||||||
|
use Lucent\Support\Collection;
|
||||||
|
use Lucent\Support\Result\Result;
|
||||||
|
use Lucent\Support\Result\Success;
|
||||||
|
|
||||||
|
class EdgeService
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public EdgeRepo $edgeRepo,
|
||||||
|
public Mapper $mapper,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Record $record
|
||||||
|
* @param Collection<RecordEdgeData> $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());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Graph\Edge;
|
||||||
|
|
||||||
|
use Lucent\Channel\ChannelService;
|
||||||
|
use Lucent\Graph\Data\InputFormatter;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
|
class Mapper
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public InputFormatter $inputFormatter,
|
||||||
|
public ChannelService $channelService
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fromDB(stdClass $data): Edge
|
||||||
|
{
|
||||||
|
$edge = Edge::fromDB($data);
|
||||||
|
$edgeSchema = $this->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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record\Contracts;
|
namespace Lucent\Graph\Record\Contracts;
|
||||||
|
|
||||||
use Lucent\Record\QueryRecord;
|
use Lucent\Graph\Record\QueryRecord;
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
|
|
||||||
class EditorTree
|
class EditorTree
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record\Contracts;
|
namespace Lucent\Graph\Record\Contracts;
|
||||||
|
|
||||||
use Lucent\Record\Status;
|
use Lucent\Graph\Record\Status;
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
use PhpOption\Option;
|
use PhpOption\Option;
|
||||||
|
|
||||||
+6
-5
@@ -1,10 +1,11 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record\Contracts;
|
namespace Lucent\Graph\Record\Contracts;
|
||||||
|
|
||||||
use Lucent\Edge\Edge;
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\Record\Record;
|
use Lucent\Graph\Edge\Edge;
|
||||||
use PhpOption\Option;
|
use Lucent\Graph\Record\Record;
|
||||||
|
use Lucent\Support\Option\Option;
|
||||||
|
|
||||||
class RecordEdgeData
|
class RecordEdgeData
|
||||||
{
|
{
|
||||||
@@ -26,7 +27,7 @@ class RecordEdgeData
|
|||||||
sourceSchema: $record->schema,
|
sourceSchema: $record->schema,
|
||||||
targetSchema: $this->targetSchema,
|
targetSchema: $this->targetSchema,
|
||||||
field: $this->field,
|
field: $this->field,
|
||||||
data: $this->data,
|
data: $this->data->map([FieldData::class,'fromArray'])->getOrElse(new FieldData([])),
|
||||||
rank: $index,
|
rank: $index,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record\Contracts;
|
namespace Lucent\Graph\Record\Contracts;
|
||||||
|
|
||||||
use Lucent\Record\Status;
|
use Lucent\Graph\Record\Status;
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
|
|
||||||
class UpdateRecordData
|
class UpdateRecordData
|
||||||
@@ -1,19 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
class Document implements Record
|
class Document implements Record
|
||||||
{
|
{
|
||||||
|
|
||||||
function __construct(
|
function __construct(
|
||||||
public string $id,
|
public string $id,
|
||||||
public string $schema,
|
public string $schema,
|
||||||
public Status $status,
|
public Status $status,
|
||||||
public System $_sys,
|
public System $_sys,
|
||||||
public RecordData $data,
|
public FieldData $data,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -53,7 +54,7 @@ class Document implements Record
|
|||||||
schema: $data->schema,
|
schema: $data->schema,
|
||||||
status: Status::from($data->status),
|
status: Status::from($data->status),
|
||||||
_sys: System::fromArray(json_decode($data->_sys, true)),
|
_sys: System::fromArray(json_decode($data->_sys, true)),
|
||||||
data: new RecordData(json_decode($data->data, true)),
|
data: new FieldData(json_decode($data->data, true)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,19 +1,20 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
class File implements Record
|
class File implements Record
|
||||||
{
|
{
|
||||||
|
|
||||||
function __construct(
|
function __construct(
|
||||||
public string $id,
|
public string $id,
|
||||||
public string $schema,
|
public string $schema,
|
||||||
public Status $status,
|
public Status $status,
|
||||||
public System $_sys,
|
public System $_sys,
|
||||||
public RecordData $data,
|
public FieldData $data,
|
||||||
public FileInfo $_file,
|
public FileInfo $_file,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -54,7 +55,7 @@ class File implements Record
|
|||||||
schema: $data->schema,
|
schema: $data->schema,
|
||||||
status: Status::from($data->status),
|
status: Status::from($data->status),
|
||||||
_sys: System::fromArray(json_decode($data->_sys, true)),
|
_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),
|
_file: FileInfo::fromJSON($data->_file),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
|
|
||||||
readonly class FileInfo
|
readonly class FileInfo
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
use Illuminate\Contracts\Session\Session;
|
use Illuminate\Contracts\Session\Session;
|
||||||
use Lucent\Query\Query;
|
use Lucent\Query\Query;
|
||||||
@@ -81,13 +81,11 @@ class Manager
|
|||||||
public function getRecords(?string $ignoreId = null): array
|
public function getRecords(?string $ignoreId = null): array
|
||||||
{
|
{
|
||||||
|
|
||||||
$graph = $this->query
|
$graph = $this->query->run(
|
||||||
->filter(["id_in" => $this->getIdsExcept($ignoreId)])
|
fn($builder) => $builder->filter(["id_in" => $this->getIdsExcept($ignoreId)])
|
||||||
->limit(7)
|
->limit(7)
|
||||||
->run();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
);
|
||||||
return $this->order($graph->records->toArray());
|
return $this->order($graph->records->toArray());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\InputFormatter;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
class Mapper
|
class Mapper
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
use Lucent\Edge\Edge;
|
use Lucent\Graph\Edge\Edge;
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
use Lucent\Support\Option\Option;
|
use Lucent\Support\Option\Option;
|
||||||
|
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
|
||||||
use JsonSerializable;
|
|
||||||
use stdClass;
|
use stdClass;
|
||||||
|
|
||||||
interface Record
|
interface Record
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
@@ -10,7 +10,7 @@ class RecordRepo
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function create(Record $record): void
|
public function create(Record $record): void
|
||||||
{
|
{
|
||||||
$recordToDB = $record->toDB();
|
$recordToDB = $record->toDB();
|
||||||
|
|
||||||
@@ -21,14 +21,14 @@ class RecordRepo
|
|||||||
/**
|
/**
|
||||||
* @param array<string> $ids
|
* @param array<string> $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([
|
DB::table("records")->whereIn("id", $ids)->update([
|
||||||
'status' => $status->value
|
'status' => $status->value
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function update(Record $record): void
|
public function update(Record $record): void
|
||||||
{
|
{
|
||||||
|
|
||||||
$recordToDB = $record->toDB();
|
$recordToDB = $record->toDB();
|
||||||
@@ -1,20 +1,21 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Lucent\Account\AuthService;
|
use Lucent\Account\AuthService;
|
||||||
use Lucent\Channel\ChannelService;
|
use Lucent\Channel\ChannelService;
|
||||||
use Lucent\CommonData\Id;
|
use Lucent\CommonData\Id;
|
||||||
use Lucent\Edge\Edge;
|
|
||||||
use Lucent\Edge\EdgeCollection;
|
|
||||||
use Lucent\Edge\EdgeService;
|
|
||||||
use Lucent\File\FileService;
|
use Lucent\File\FileService;
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
|
use Lucent\Graph\Data\InputFormatter;
|
||||||
|
use Lucent\Graph\Edge\Edge;
|
||||||
|
use Lucent\Graph\Edge\EdgeCollection;
|
||||||
|
use Lucent\Graph\Edge\EdgeService;
|
||||||
|
use Lucent\Graph\Record\Contracts\NewDocumentData;
|
||||||
|
use Lucent\Graph\Record\Contracts\UpdateRecordData;
|
||||||
use Lucent\LucentException;
|
use Lucent\LucentException;
|
||||||
use Lucent\Query\Query;
|
use Lucent\Query\Query;
|
||||||
use Lucent\Record\Contracts\NewDocumentData;
|
|
||||||
use Lucent\Record\Contracts\RecordEdgeData;
|
|
||||||
use Lucent\Record\Contracts\UpdateRecordData;
|
|
||||||
use Lucent\Revision\RevisionService;
|
use Lucent\Revision\RevisionService;
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Schema\Schema;
|
use Lucent\Schema\Schema\Schema;
|
||||||
@@ -25,7 +26,6 @@ use Lucent\Support\Collection;
|
|||||||
use Lucent\Support\Result\Error;
|
use Lucent\Support\Result\Error;
|
||||||
use Lucent\Support\Result\Result;
|
use Lucent\Support\Result\Result;
|
||||||
use Lucent\Support\Result\Success;
|
use Lucent\Support\Result\Success;
|
||||||
use PhpOption\Option;
|
|
||||||
|
|
||||||
readonly class RecordService
|
readonly class RecordService
|
||||||
{
|
{
|
||||||
@@ -50,7 +50,7 @@ readonly class RecordService
|
|||||||
public function createDocument(NewDocumentData $data): Result
|
public function createDocument(NewDocumentData $data): Result
|
||||||
{
|
{
|
||||||
$schema = $this->channelService->getSchema($data->schemaName)->get();
|
$schema = $this->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());
|
$newRecordId = $data->id->getOrElse(Id::new());
|
||||||
|
|
||||||
$record = new Document(
|
$record = new Document(
|
||||||
@@ -61,32 +61,58 @@ readonly class RecordService
|
|||||||
data: $formattedData,
|
data: $formattedData,
|
||||||
);
|
);
|
||||||
|
|
||||||
$uniqueEdges = $this->getUniqueEdges($data->edges, $record);
|
|
||||||
|
|
||||||
if ($data->status === Status::PUBLISHED) {
|
if ($data->status === Status::PUBLISHED) {
|
||||||
$errors = $this->recordValidator->check($data->schemaName, $record->data);
|
$errors = $this->recordValidator->check($data->schemaName, $record->data);
|
||||||
if ($errors->isNotEmpty()) {
|
if ($errors->isNotEmpty()) {
|
||||||
return Error::create($errors);
|
return Error::create($errors);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RecordRepo::create($record);
|
|
||||||
$this->edgeService->update($record->id, $uniqueEdges);
|
$this->recordRepo->create($record);
|
||||||
$this->revisionService->create($record, $uniqueEdges);
|
$edgeCollection = $this->edgeService->replaceEdgesForRecord($record,$data->edges);
|
||||||
|
$this->revisionService->create($record, $edgeCollection);
|
||||||
return Success::create($record->id);
|
return Success::create($record->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param Collection<RecordEdgeData> $edges
|
* @param UpdateRecordData $data
|
||||||
* @param Record $record
|
* @return Result<string|Collection<ValidatorError>>
|
||||||
* @return EdgeCollection
|
|
||||||
*/
|
*/
|
||||||
private function getUniqueEdges(Collection $edges, Record $record): EdgeCollection
|
public function update(UpdateRecordData $data): Result
|
||||||
{
|
{
|
||||||
$edges = $edges
|
$record = $this->query->filter(["id" => $data->id])->run()->rootRecords->first();
|
||||||
->map(fn(RecordEdgeData $edge, $index) => $edge->toEdge($record, $index));
|
|
||||||
return new EdgeCollection(...$edges->toArray());
|
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 LucentException
|
||||||
* @throws ValidatorException
|
* @throws ValidatorException
|
||||||
@@ -104,7 +130,7 @@ readonly class RecordService
|
|||||||
{
|
{
|
||||||
$schema = $this->channelService->getSchema($schemaName)->get();
|
$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"])) {
|
if (empty($formattedData["id"])) {
|
||||||
$formattedData["id"] = Id::new();
|
$formattedData["id"] = Id::new();
|
||||||
}
|
}
|
||||||
@@ -151,45 +177,7 @@ readonly class RecordService
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param UpdateRecordData $data
|
|
||||||
* @return Result<string|Collection<ValidatorError>>
|
|
||||||
*/
|
|
||||||
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;
|
return $carry;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
$formattedData = $this->inputFormatter->fill($schema->name, new RecordData($defaultValues));
|
$formattedData = $this->inputFormatter->fill($schema->name, new FieldData($defaultValues));
|
||||||
return new Document(
|
return new Document(
|
||||||
id: Id::new(),
|
id: Id::new(),
|
||||||
schema: $schema->name,
|
schema: $schema->name,
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
enum Status: string
|
enum Status: string
|
||||||
{
|
{
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Record;
|
namespace Lucent\Graph\Record;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
|
||||||
@@ -3,12 +3,6 @@
|
|||||||
namespace Lucent\Http\Controller\Api;
|
namespace Lucent\Http\Controller\Api;
|
||||||
|
|
||||||
use Lucent\Http\Controller;
|
use Lucent\Http\Controller;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Http\Response;
|
|
||||||
use Lucent\Edge\EdgeService;
|
|
||||||
use Lucent\LucentException;
|
|
||||||
use function Lucent\Response\fail;
|
|
||||||
use function Lucent\Response\ok;
|
|
||||||
|
|
||||||
class EdgeController extends Controller
|
class EdgeController extends Controller
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -3,14 +3,6 @@
|
|||||||
namespace Lucent\Http\Controller\Api;
|
namespace Lucent\Http\Controller\Api;
|
||||||
|
|
||||||
use Lucent\Http\Controller;
|
use Lucent\Http\Controller;
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Illuminate\Support\Facades\Validator;
|
|
||||||
use Lucent\Account\AuthService;
|
|
||||||
use Lucent\File\FileUploadResult;
|
|
||||||
use Lucent\Record\RecordService;
|
|
||||||
use function Lucent\File\uploadFile;
|
|
||||||
use function Lucent\Response\fail;
|
|
||||||
use function Lucent\Response\ok;
|
|
||||||
|
|
||||||
class FileController extends Controller
|
class FileController extends Controller
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -2,16 +2,8 @@
|
|||||||
|
|
||||||
namespace Lucent\Http\Controller\Api;
|
namespace Lucent\Http\Controller\Api;
|
||||||
|
|
||||||
use Lucent\Http\Controller;
|
|
||||||
use Illuminate\Http\Request;
|
|
||||||
use Lucent\Channel\ChannelRepo;
|
use Lucent\Channel\ChannelRepo;
|
||||||
use Lucent\LucentException;
|
use Lucent\Http\Controller;
|
||||||
use Lucent\Query\Query;
|
|
||||||
use Lucent\Record\RecordService;
|
|
||||||
use Lucent\Schema\Validator\ValidatorException;
|
|
||||||
use Throwable;
|
|
||||||
use function Lucent\Response\fail;
|
|
||||||
use function Lucent\Response\ok;
|
|
||||||
|
|
||||||
class RecordController extends Controller
|
class RecordController extends Controller
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Http\Controller;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Lucent\Graph\Edge\Contracts\EdgeData;
|
||||||
|
use Lucent\Graph\Edge\EdgeService;
|
||||||
|
use Lucent\Http\Controller;
|
||||||
|
use function Lucent\Response\result;
|
||||||
|
|
||||||
|
class EdgeController extends Controller
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly EdgeService $edgeService,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update(Request $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
$res = $this->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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
namespace Lucent\Http\Controller;
|
namespace Lucent\Http\Controller;
|
||||||
|
|
||||||
use Lucent\Http\Controller;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Validator;
|
use Illuminate\Support\Facades\Validator;
|
||||||
use Lucent\Channel\ChannelService;
|
use Lucent\Channel\ChannelService;
|
||||||
use Lucent\File\FileUploadResult;
|
use Lucent\File\FileUploadResult;
|
||||||
|
use Lucent\Graph\Record\RecordService;
|
||||||
|
use Lucent\Http\Controller;
|
||||||
use Lucent\Query\Query;
|
use Lucent\Query\Query;
|
||||||
use Lucent\Record\RecordService;
|
|
||||||
use function Lucent\File\loadDisk;
|
use function Lucent\File\loadDisk;
|
||||||
use function Lucent\File\uploadFile;
|
use function Lucent\File\uploadFile;
|
||||||
use function Lucent\Response\fail;
|
use function Lucent\Response\fail;
|
||||||
|
|||||||
@@ -2,27 +2,28 @@
|
|||||||
|
|
||||||
namespace Lucent\Http\Controller;
|
namespace Lucent\Http\Controller;
|
||||||
|
|
||||||
use Lucent\Http\Controller;
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
use Lucent\Account\AccountService;
|
use Lucent\Account\AccountService;
|
||||||
use Lucent\Channel\ChannelService;
|
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\LucentException;
|
||||||
|
use Lucent\Query\Builder;
|
||||||
use Lucent\Query\Operator;
|
use Lucent\Query\Operator;
|
||||||
use Lucent\Query\Query;
|
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\Schema\System;
|
||||||
use Lucent\Schema\Validator\ValidatorException;
|
use Lucent\Schema\Validator\ValidatorException;
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
use Lucent\Support\Result\Success;
|
use Lucent\Support\Result\Success;
|
||||||
use Lucent\Svelte\Svelte;
|
use Lucent\Svelte\Svelte;
|
||||||
use PhpOption\Option;
|
use Lucent\Support\Option\Option;
|
||||||
use function Lucent\Response\fail;
|
use function Lucent\Response\fail;
|
||||||
use function Lucent\Response\ok;
|
use function Lucent\Response\ok;
|
||||||
use function Lucent\Response\result;
|
use function Lucent\Response\result;
|
||||||
@@ -36,7 +37,7 @@ class RecordController extends Controller
|
|||||||
private readonly Svelte $svelte,
|
private readonly Svelte $svelte,
|
||||||
private readonly Query $query,
|
private readonly Query $query,
|
||||||
private readonly Manager $recordManager,
|
private readonly Manager $recordManager,
|
||||||
private readonly EditorTree $editorTree
|
private readonly EditorTree $editorTree
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -64,19 +65,17 @@ class RecordController extends Controller
|
|||||||
"status_in" => "draft,published",
|
"status_in" => "draft,published",
|
||||||
], $filter);
|
], $filter);
|
||||||
|
|
||||||
|
|
||||||
$skip = data_get($urlParams, "skip") ?? 0;
|
$skip = data_get($urlParams, "skip") ?? 0;
|
||||||
$limit = 30;
|
$limit = 30;
|
||||||
$graph = $this->query
|
$graph = $this->query->run(fn(Builder $builder) => $builder->filter($arguments)
|
||||||
->filter($arguments)
|
|
||||||
->limit($limit)
|
->limit($limit)
|
||||||
->status(explode(",", $arguments["status_in"]))
|
->status(explode(",", $arguments["status_in"]))
|
||||||
->skip($skip)
|
->skip($skip)
|
||||||
->sort($sort)
|
->sort($sort)
|
||||||
->childrenFields($schema?->visible ?? [])
|
->childrenFields($schema?->visible ?? [])
|
||||||
->childrenDepth(1)
|
->childrenDepth(1)
|
||||||
->parentsDepth(0)
|
->withCount()
|
||||||
->runWithCount();
|
);
|
||||||
|
|
||||||
$data = [
|
$data = [
|
||||||
"schemas" => $this->channelService->channel->schemas,
|
"schemas" => $this->channelService->channel->schemas,
|
||||||
@@ -102,6 +101,7 @@ class RecordController extends Controller
|
|||||||
}
|
}
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
$data["inModal"] = false;
|
$data["inModal"] = false;
|
||||||
return $this->svelte->render(
|
return $this->svelte->render(
|
||||||
layout: "channel",
|
layout: "channel",
|
||||||
@@ -204,15 +204,14 @@ class RecordController extends Controller
|
|||||||
{
|
{
|
||||||
$rid = $request->route("rid");
|
$rid = $request->route("rid");
|
||||||
|
|
||||||
$graph = $this->query
|
$graph = $this->query->run(fn(Builder $builder) => $builder->filter(["id" => $rid])
|
||||||
->filter(["id" => $rid])
|
|
||||||
->limit(1)
|
->limit(1)
|
||||||
->skip(0)
|
->skip(0)
|
||||||
->childrenDepth(2)
|
->childrenDepth(1)
|
||||||
->childrenLimit(200)
|
->childrenLimit(500)
|
||||||
->parentsDepth(1)
|
->parentsDepth(1)
|
||||||
->parentsLimit(200)
|
);
|
||||||
->run();
|
|
||||||
|
|
||||||
if ($graph->rootRecords->isEmpty()) {
|
if ($graph->rootRecords->isEmpty()) {
|
||||||
return $this->svelte->render(
|
return $this->svelte->render(
|
||||||
@@ -316,9 +315,9 @@ class RecordController extends Controller
|
|||||||
|
|
||||||
$recordEdgeData = (new Collection($request->input("edges")))->map(fn($item) => new RecordEdgeData(
|
$recordEdgeData = (new Collection($request->input("edges")))->map(fn($item) => new RecordEdgeData(
|
||||||
target: $item["target"],
|
target: $item["target"],
|
||||||
targetSchema:$item["targetSchema"],
|
targetSchema: $item["targetSchema"],
|
||||||
field: $item["field"],
|
field: $item["field"],
|
||||||
data: Option::fromValue(data_get($item,"data")),
|
data: Option::fromValue(data_get($item, "data")),
|
||||||
));
|
));
|
||||||
|
|
||||||
$res = match ($request->input("isCreateMode")) {
|
$res = match ($request->input("isCreateMode")) {
|
||||||
|
|||||||
+6
-1
@@ -4,6 +4,7 @@ use Illuminate\Support\Facades\Route;
|
|||||||
use Lucent\Http\Controller\AccountController;
|
use Lucent\Http\Controller\AccountController;
|
||||||
use Lucent\Http\Controller\AuthController;
|
use Lucent\Http\Controller\AuthController;
|
||||||
use Lucent\Http\Controller\BuildController;
|
use Lucent\Http\Controller\BuildController;
|
||||||
|
use Lucent\Http\Controller\EdgeController;
|
||||||
use Lucent\Http\Controller\FileController;
|
use Lucent\Http\Controller\FileController;
|
||||||
use Lucent\Http\Controller\HomeController;
|
use Lucent\Http\Controller\HomeController;
|
||||||
use Lucent\Http\Controller\MemberController;
|
use Lucent\Http\Controller\MemberController;
|
||||||
@@ -60,6 +61,11 @@ Route::group([
|
|||||||
Route::post('/{rid}/rollback/{version}', [RecordController::class, 'rollback']);
|
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::middleware(["lucent.auth"])->group(function () {
|
||||||
Route::get('/records/{rid}/revisions', [RevisionController::class, 'index']);
|
Route::get('/records/{rid}/revisions', [RevisionController::class, 'index']);
|
||||||
|
|
||||||
@@ -82,6 +88,5 @@ Route::group([
|
|||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ use function ord;
|
|||||||
use function strcmp;
|
use function strcmp;
|
||||||
use function substr;
|
use function substr;
|
||||||
|
|
||||||
/** @psalm-immutable */
|
|
||||||
final class Lexorank
|
final class Lexorank
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ use Lucent\JsonSchema\Command\GenerateJsonSchema;
|
|||||||
use Lucent\Query\DatabaseGraph\DatabaseGraph;
|
use Lucent\Query\DatabaseGraph\DatabaseGraph;
|
||||||
use Lucent\Query\DatabaseGraph\PgsqlDatabaseGraph;
|
use Lucent\Query\DatabaseGraph\PgsqlDatabaseGraph;
|
||||||
use Lucent\Query\DatabaseGraph\SqliteDatabaseGraph;
|
use Lucent\Query\DatabaseGraph\SqliteDatabaseGraph;
|
||||||
|
use Lucent\Query\Query;
|
||||||
use Lucent\Schema\Commands\CompileSchemas;
|
use Lucent\Schema\Commands\CompileSchemas;
|
||||||
|
|
||||||
class LucentServiceProvider extends ServiceProvider
|
class LucentServiceProvider extends ServiceProvider
|
||||||
@@ -33,6 +34,8 @@ class LucentServiceProvider extends ServiceProvider
|
|||||||
return new ImageManager(['driver' => 'imagick']);
|
return new ImageManager(['driver' => 'imagick']);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
$this->app->bind(DatabaseGraph::class, function () {
|
$this->app->bind(DatabaseGraph::class, function () {
|
||||||
return match (config("lucent.database")) {
|
return match (config("lucent.database")) {
|
||||||
"sqlite" => new SqliteDatabaseGraph(),
|
"sqlite" => new SqliteDatabaseGraph(),
|
||||||
@@ -61,17 +64,17 @@ class LucentServiceProvider extends ServiceProvider
|
|||||||
|
|
||||||
$this->loadViewsFrom(__DIR__ . '/Views', 'lucent');
|
$this->loadViewsFrom(__DIR__ . '/Views', 'lucent');
|
||||||
$this->loadRoutesFrom(__DIR__ . '/Http/web.php');
|
$this->loadRoutesFrom(__DIR__ . '/Http/web.php');
|
||||||
$this->loadRoutesFrom(__DIR__ . '/Http/api.php');
|
// $this->loadRoutesFrom(__DIR__ . '/Http/api.php');
|
||||||
|
|
||||||
$this->loadMigrationsFrom(__DIR__ . '/Database/migrations');
|
$this->loadMigrationsFrom(__DIR__ . '/Database/migrations');
|
||||||
|
|
||||||
if ($this->app->runningInConsole()) {
|
if ($this->app->runningInConsole()) {
|
||||||
$this->commands([
|
$this->commands([
|
||||||
CompileSchemas::class,
|
// CompileSchemas::class,
|
||||||
RebuildThumbnails::class,
|
// RebuildThumbnails::class,
|
||||||
LiveLink::class,
|
// LiveLink::class,
|
||||||
RemoveOrphanEdges::class,
|
// RemoveOrphanEdges::class,
|
||||||
GenerateJsonSchema::class,
|
// GenerateJsonSchema::class,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,237 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query;
|
||||||
|
|
||||||
|
use Illuminate\Database\Query\Builder as LaravelBuilder;
|
||||||
|
use Lucent\Query\Data\AndFilter;
|
||||||
|
use Lucent\Query\Data\Argument;
|
||||||
|
use Lucent\Query\Data\Filter;
|
||||||
|
use Lucent\Query\Data\FilterGroup;
|
||||||
|
use Lucent\Query\Data\OrFilter;
|
||||||
|
|
||||||
|
class Builder
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @param array<Filter> $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<Argument> $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<Argument> $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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Query\Filter;
|
namespace Lucent\Query\Data;
|
||||||
|
|
||||||
|
|
||||||
final class AndFilter implements Filter
|
final class AndFilter implements Filter
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Query\Filter;
|
namespace Lucent\Query\Data;
|
||||||
|
|
||||||
class Argument
|
class Argument
|
||||||
{
|
{
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
<?php namespace Lucent\Query\Filter;
|
<?php namespace Lucent\Query\Data;
|
||||||
|
|
||||||
|
|
||||||
interface Filter
|
interface Filter
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Lucent\Query\Data;
|
||||||
|
|
||||||
|
class FilterGroup
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
public array $record = [],
|
||||||
|
public array $reference = [],
|
||||||
|
public array $edge = [],
|
||||||
|
)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace Lucent\Query\Filter;
|
namespace Lucent\Query\Data;
|
||||||
|
|
||||||
|
|
||||||
final class OrFilter implements Filter
|
final class OrFilter implements Filter
|
||||||
@@ -2,21 +2,22 @@
|
|||||||
|
|
||||||
namespace Lucent\Query\DatabaseGraph;
|
namespace Lucent\Query\DatabaseGraph;
|
||||||
|
|
||||||
use Lucent\Edge\Edge;
|
use Lucent\Query\Builder;
|
||||||
use Lucent\Query\QueryOptions;
|
use Lucent\Query\QueryOptions;
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
interface DatabaseGraph
|
interface DatabaseGraph
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @param array<string> $ids
|
* @param array<string> $ids
|
||||||
* @return Collection<Edge>
|
* @return Collection<stdClass>
|
||||||
*/
|
*/
|
||||||
public function getChildren(array $ids, QueryOptions $options): Collection;
|
public function getChildren(array $ids, Builder $options): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string> $ids
|
* @param array<string> $ids
|
||||||
* @return Collection<Edge>
|
* @return Collection<stdClass>
|
||||||
*/
|
*/
|
||||||
public function getParents(array $ids, QueryOptions $options): Collection;
|
public function getParents(array $ids, Builder $options): Collection;
|
||||||
}
|
}
|
||||||
@@ -3,23 +3,24 @@
|
|||||||
namespace Lucent\Query\DatabaseGraph;
|
namespace Lucent\Query\DatabaseGraph;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Lucent\Edge\Edge;
|
use Lucent\Query\Builder;
|
||||||
use Lucent\Query\QueryOptions;
|
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
class PgsqlDatabaseGraph implements DatabaseGraph
|
class PgsqlDatabaseGraph implements DatabaseGraph
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string> $ids
|
* @param array<string> $ids
|
||||||
* @return Collection<Edge>
|
* @return Collection<stdClass>
|
||||||
*/
|
*/
|
||||||
public function getChildren(array $ids, QueryOptions $options): Collection
|
public function getChildren(array $ids, Builder $options): Collection
|
||||||
{
|
{
|
||||||
$subquery = DB::table('edges AS g')
|
$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);
|
->whereIn('source', $ids);
|
||||||
|
|
||||||
|
$subquery = $options->resolveEdgeFilters($subquery);
|
||||||
|
|
||||||
if (!empty($options->childrenFields)) {
|
if (!empty($options->childrenFields)) {
|
||||||
$subquery->whereIn('field', $options->childrenFields);
|
$subquery->whereIn('field', $options->childrenFields);
|
||||||
}
|
}
|
||||||
@@ -27,7 +28,7 @@ class PgsqlDatabaseGraph implements DatabaseGraph
|
|||||||
$subquery->limit($options->childrenLimit)
|
$subquery->limit($options->childrenLimit)
|
||||||
->union(
|
->union(
|
||||||
DB::table(DB::raw("edges AS g, search_graph AS sg "))
|
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")
|
->whereRaw("g.source = sg.target")
|
||||||
->where("depth", "<", $options->childrenDepth)
|
->where("depth", "<", $options->childrenDepth)
|
||||||
->orderBy("rank")
|
->orderBy("rank")
|
||||||
@@ -36,19 +37,21 @@ class PgsqlDatabaseGraph implements DatabaseGraph
|
|||||||
return new Collection(DB::table('search_graph')
|
return new Collection(DB::table('search_graph')
|
||||||
// ->select(DB::raw("*, 1 as depth "))
|
// ->select(DB::raw("*, 1 as depth "))
|
||||||
->withRecursiveExpression('search_graph', $subquery)
|
->withRecursiveExpression('search_graph', $subquery)
|
||||||
->get()->map([Edge::class, 'fromDB']));
|
->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string> $ids
|
* @param array<string> $ids
|
||||||
* @return Collection<Edge>
|
* @return Collection<stdClass>
|
||||||
*/
|
*/
|
||||||
public function getParents(array $ids, QueryOptions $options): Collection
|
public function getParents(array $ids, Builder $options): Collection
|
||||||
{
|
{
|
||||||
$subquery = DB::table('edges AS g')
|
$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);
|
->whereIn('g.target', $ids);
|
||||||
|
|
||||||
|
$subquery = $options->resolveEdgeFilters($subquery);
|
||||||
|
|
||||||
if (!empty($options->parentFields)) {
|
if (!empty($options->parentFields)) {
|
||||||
$subquery->whereIn('field', $options->parentFields);
|
$subquery->whereIn('field', $options->parentFields);
|
||||||
}
|
}
|
||||||
@@ -57,7 +60,7 @@ class PgsqlDatabaseGraph implements DatabaseGraph
|
|||||||
->limit($options->parentsLimit)
|
->limit($options->parentsLimit)
|
||||||
->union(
|
->union(
|
||||||
DB::table(DB::raw("edges AS g, search_graph AS sg "))
|
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")
|
->whereRaw("g.target = sg.source")
|
||||||
->where("depth", "<", $options->parentsDepth)
|
->where("depth", "<", $options->parentsDepth)
|
||||||
->orderBy("rank")
|
->orderBy("rank")
|
||||||
@@ -66,6 +69,6 @@ class PgsqlDatabaseGraph implements DatabaseGraph
|
|||||||
return new Collection(DB::table('search_graph')
|
return new Collection(DB::table('search_graph')
|
||||||
// ->select(DB::raw('sg.source,sg.target,sg.rank,sg."sourceSchema",sg."targetSchema",sg.field,sg.depth'))
|
// ->select(DB::raw('sg.source,sg.target,sg.rank,sg."sourceSchema",sg."targetSchema",sg.field,sg.depth'))
|
||||||
->withRecursiveExpression('search_graph', $subquery)
|
->withRecursiveExpression('search_graph', $subquery)
|
||||||
->get()->map([Edge::class, 'fromDB']));
|
->get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3,22 +3,26 @@
|
|||||||
namespace Lucent\Query\DatabaseGraph;
|
namespace Lucent\Query\DatabaseGraph;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Lucent\Edge\Edge;
|
use Lucent\Query\Builder;
|
||||||
use Lucent\Query\QueryOptions;
|
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
|
use stdClass;
|
||||||
|
|
||||||
class SqliteDatabaseGraph implements DatabaseGraph
|
class SqliteDatabaseGraph implements DatabaseGraph
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string> $ids
|
* @param array<string> $ids
|
||||||
* @return Collection<Edge>
|
* @return Collection<stdClass>
|
||||||
*/
|
*/
|
||||||
public function getChildren(array $ids, QueryOptions $options): Collection
|
public function getChildren(array $ids, Builder $options):Collection
|
||||||
{
|
{
|
||||||
$subquery = DB::table('edges AS g')
|
$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);
|
->whereIn('source', $ids);
|
||||||
|
|
||||||
|
$subquery = $options->resolveEdgeFilters($subquery);
|
||||||
|
|
||||||
if (!empty($options->childrenFields)) {
|
if (!empty($options->childrenFields)) {
|
||||||
$subquery->whereIn('field', $options->childrenFields);
|
$subquery->whereIn('field', $options->childrenFields);
|
||||||
}
|
}
|
||||||
@@ -26,7 +30,7 @@ class SqliteDatabaseGraph implements DatabaseGraph
|
|||||||
$subquery->limit($options->childrenLimit)
|
$subquery->limit($options->childrenLimit)
|
||||||
->union(
|
->union(
|
||||||
DB::table(DB::raw("edges AS g, search_graph AS sg "))
|
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")
|
->whereRaw("g.source = sg.target")
|
||||||
->where("depth", "<", $options->childrenDepth)
|
->where("depth", "<", $options->childrenDepth)
|
||||||
->orderBy("rank")
|
->orderBy("rank")
|
||||||
@@ -35,19 +39,20 @@ class SqliteDatabaseGraph implements DatabaseGraph
|
|||||||
return new Collection(DB::table('search_graph')
|
return new Collection(DB::table('search_graph')
|
||||||
// ->select(DB::raw("*, 1 as depth "))
|
// ->select(DB::raw("*, 1 as depth "))
|
||||||
->withRecursiveExpression('search_graph', $subquery)
|
->withRecursiveExpression('search_graph', $subquery)
|
||||||
->get()->map([Edge::class, 'fromDB']));
|
->get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string> $ids
|
* @param array<string> $ids
|
||||||
* @return Collection<Edge>
|
* @return Collection<stdClass>
|
||||||
*/
|
*/
|
||||||
public function getParents(array $ids, QueryOptions $options): Collection
|
public function getParents(array $ids, Builder $options):Collection
|
||||||
{
|
{
|
||||||
$subquery = DB::table('edges AS g')
|
$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);
|
->whereIn('g.target', $ids);
|
||||||
|
|
||||||
|
$subquery = $options->resolveEdgeFilters($subquery);
|
||||||
if (!empty($options->parentFields)) {
|
if (!empty($options->parentFields)) {
|
||||||
$subquery->whereIn('field', $options->parentFields);
|
$subquery->whereIn('field', $options->parentFields);
|
||||||
}
|
}
|
||||||
@@ -56,7 +61,7 @@ class SqliteDatabaseGraph implements DatabaseGraph
|
|||||||
->limit($options->parentsLimit)
|
->limit($options->parentsLimit)
|
||||||
->union(
|
->union(
|
||||||
DB::table(DB::raw("edges AS g, search_graph AS sg "))
|
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")
|
->whereRaw("g.target = sg.source")
|
||||||
->where("depth", "<", $options->parentsDepth)
|
->where("depth", "<", $options->parentsDepth)
|
||||||
->orderBy("rank")
|
->orderBy("rank")
|
||||||
@@ -65,6 +70,6 @@ class SqliteDatabaseGraph implements DatabaseGraph
|
|||||||
return new Collection(DB::table('search_graph')
|
return new Collection(DB::table('search_graph')
|
||||||
// ->select(DB::raw('sg.source,sg.target,sg.rank,sg."sourceSchema",sg."targetSchema",sg.field,sg.depth'))
|
// ->select(DB::raw('sg.source,sg.target,sg.rank,sg."sourceSchema",sg."targetSchema",sg.field,sg.depth'))
|
||||||
->withRecursiveExpression('search_graph', $subquery)
|
->withRecursiveExpression('search_graph', $subquery)
|
||||||
->get()->map([Edge::class, 'fromDB']));
|
->get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+51
-118
@@ -2,29 +2,24 @@
|
|||||||
|
|
||||||
namespace Lucent\Query;
|
namespace Lucent\Query;
|
||||||
|
|
||||||
use Illuminate\Contracts\Foundation\Application;
|
|
||||||
use Illuminate\Database\Query\Builder;
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Lucent\Query\Filter\AndFilter;
|
use Lucent\Query\Data\Argument;
|
||||||
use Lucent\Query\Filter\Argument;
|
|
||||||
use Lucent\Query\Filter\Filter;
|
|
||||||
use Lucent\Query\Filter\OrFilter;
|
|
||||||
|
|
||||||
final class FilterParser
|
final class FilterParser
|
||||||
{
|
{
|
||||||
|
|
||||||
public function __construct(public Application $app)
|
public function __construct()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $arguments
|
* @param array $arguments
|
||||||
* @return array<Argument>
|
* @return array<Argument>
|
||||||
*/
|
*/
|
||||||
private function formatArguments(array $arguments): array
|
public function formatArguments(array $arguments): array
|
||||||
{
|
{
|
||||||
return collect($arguments)->reduce(function ($c, $v, $k) {
|
return collect($arguments)->reduce(function ($c, $v, $k) {
|
||||||
|
|
||||||
$c[] = $this->formatArgument($v, $k);
|
$c[] = $this->formatArgument($v, $k);
|
||||||
return $c;
|
return $c;
|
||||||
}, []);
|
}, []);
|
||||||
@@ -32,7 +27,6 @@ final class FilterParser
|
|||||||
|
|
||||||
private function formatArgument(mixed $value, string $filter): Argument
|
private function formatArgument(mixed $value, string $filter): Argument
|
||||||
{
|
{
|
||||||
|
|
||||||
$operator = $this->detectOperator($filter);
|
$operator = $this->detectOperator($filter);
|
||||||
|
|
||||||
$field = $this->detectField($filter, $operator);
|
$field = $this->detectField($filter, $operator);
|
||||||
@@ -92,21 +86,21 @@ final class FilterParser
|
|||||||
|
|
||||||
private function formatListNum(mixed $value): array
|
private function formatListNum(mixed $value): array
|
||||||
{
|
{
|
||||||
if (\is_string($value)) {
|
if (is_string($value)) {
|
||||||
$value = explode(",", $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
|
private function detectOperator(string $filter): string
|
||||||
{
|
{
|
||||||
$exploded = \explode("_", $filter);
|
$exploded = explode("_", $filter);
|
||||||
$candidate = end($exploded);
|
$candidate = end($exploded);
|
||||||
$operatorsListNames = collect(Operator::list())->map(fn($o) => $o->name)->toArray();
|
$operatorsListNames = collect(Operator::list())->map(fn($o) => $o->name)->toArray();
|
||||||
|
|
||||||
if (\in_array($candidate, $operatorsListNames)) {
|
if (in_array($candidate, $operatorsListNames)) {
|
||||||
return $candidate;
|
return $candidate;
|
||||||
}
|
}
|
||||||
return 'eq';
|
return 'eq';
|
||||||
@@ -123,29 +117,22 @@ final class FilterParser
|
|||||||
return $filter;
|
return $filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function formatEdgesArguments(array $edgesArguments): Argument
|
||||||
private function formatReferences(array $referenceArguments): Argument
|
|
||||||
{
|
{
|
||||||
$subqueries = collect($referenceArguments)->reduce(function ($c, $v, $k) {
|
$subqueries = collect($edgesArguments)->reduce(function ($c, $v, $k) {
|
||||||
$keyWithoutRef = str_replace("children.", "", $k);
|
$keyWithoutRef = str_replace("edges.", "", $k);
|
||||||
[$field] = explode(".", $keyWithoutRef);
|
[$field] = explode(".", $keyWithoutRef);
|
||||||
$referenceField = str_replace($field . ".", "", $keyWithoutRef);
|
$referenceField = str_replace($field . ".", "", $keyWithoutRef);
|
||||||
$c[$field][$referenceField] = $v;
|
$c[$field][$referenceField] = $v;
|
||||||
return $c;
|
return $c;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
||||||
$sourceIds = collect($subqueries)->reduce(function ($c, $subquery, $k) {
|
$sourceIds = collect($subqueries)->reduce(function ($c, $subquery, $k) {
|
||||||
|
$laravelBuilder = DB::table("edges");
|
||||||
$query = $this->app->make(Query::class);
|
$queryBuilder = new Builder();
|
||||||
$graph = $query->filter($subquery)->run();
|
$queryBuilder->filter($subquery);
|
||||||
|
$laravelBuilder = $queryBuilder->resolveRecordFilters($laravelBuilder);
|
||||||
if (!$graph->hasResults()) {
|
$sourceIds = $laravelBuilder->where("field", $k)->get()->pluck("source");
|
||||||
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 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) {
|
$subqueries = collect($referenceArguments)->reduce(function ($c, $v, $k) {
|
||||||
if (!str_starts_with($k, "children.")) {
|
$keyWithoutRef = str_replace("children.", "", $k);
|
||||||
return true;
|
[$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<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
|
|
||||||
{
|
|
||||||
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<Argument> $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;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-9
@@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
namespace Lucent\Query;
|
namespace Lucent\Query;
|
||||||
|
|
||||||
use Lucent\Edge\Edge;
|
use Lucent\Graph\Edge\Edge;
|
||||||
use Lucent\Record\QueryRecord;
|
use Lucent\Graph\Record\QueryRecord;
|
||||||
use Lucent\Record\Record;
|
use Lucent\Graph\Record\Record;
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
use Lucent\Support\Option\Option;
|
use Lucent\Support\Option\Option;
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ final class Graph
|
|||||||
public Collection $records,
|
public Collection $records,
|
||||||
public Collection $edges,
|
public Collection $edges,
|
||||||
public Collection $parentEdges,
|
public Collection $parentEdges,
|
||||||
public QueryOptions $queryOptions,
|
public Builder $queryBuilder,
|
||||||
public ?int $total = null,
|
public ?int $total = null,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -40,7 +40,7 @@ final class Graph
|
|||||||
|
|
||||||
public function hasResults(): bool
|
public function hasResults(): bool
|
||||||
{
|
{
|
||||||
return !empty($this->records);
|
return $this->rootRecords->isNotEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function tree(): Collection
|
public function tree(): Collection
|
||||||
@@ -54,16 +54,16 @@ final class Graph
|
|||||||
|
|
||||||
public function findChildren(QueryRecord $record, int $depth = 1): QueryRecord
|
public function findChildren(QueryRecord $record, int $depth = 1): QueryRecord
|
||||||
{
|
{
|
||||||
if ($this->queryOptions->childrenDepth < $depth) {
|
if ($this->queryBuilder->childrenDepth < $depth) {
|
||||||
return $record;
|
return $record;
|
||||||
}
|
}
|
||||||
$record->_children = $this->edges
|
$record->_children = $this->edges
|
||||||
->filter(fn(Edge $ed) => $ed->source === $record->record->id)
|
->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)
|
->sort(fn($a, $b) => $a->rank <=> $b->rank)
|
||||||
->values()
|
->values()
|
||||||
->map(function (Edge $edge): Option {
|
->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()) {
|
if ($records->isEmpty()) {
|
||||||
return none();
|
return none();
|
||||||
}
|
}
|
||||||
@@ -82,7 +82,7 @@ final class Graph
|
|||||||
public function findParents(QueryRecord $record, int $depth = 1): QueryRecord
|
public function findParents(QueryRecord $record, int $depth = 1): QueryRecord
|
||||||
{
|
{
|
||||||
|
|
||||||
if ($this->queryOptions->parentsDepth < $depth) {
|
if ($this->queryBuilder->parentsDepth < $depth) {
|
||||||
return $record;
|
return $record;
|
||||||
}
|
}
|
||||||
$record->_parents = $this->parentEdges
|
$record->_parents = $this->parentEdges
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Lucent\Query;
|
|||||||
final class Operator
|
final class Operator
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* @psalm-param string[] $uis
|
* @param string[] $uis
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public string $name,
|
public string $name,
|
||||||
|
|||||||
+39
-145
@@ -2,63 +2,41 @@
|
|||||||
|
|
||||||
namespace Lucent\Query;
|
namespace Lucent\Query;
|
||||||
|
|
||||||
use Illuminate\Database\Query\Builder;
|
use Illuminate\Database\Query\Builder as LaravelBuilder;
|
||||||
use Illuminate\Support\Facades\DB;
|
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\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;
|
use Lucent\Support\Collection;
|
||||||
|
|
||||||
final class Query
|
final class Query
|
||||||
{
|
{
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array<AndFilter> $filters
|
|
||||||
*/
|
|
||||||
public array $filters;
|
|
||||||
public QueryOptions $options;
|
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public readonly FilterParser $filterParser,
|
public readonly FilterParser $filterParser,
|
||||||
public readonly InputFormatter $inputFormatter,
|
public readonly DatabaseGraph $databaseGraph,
|
||||||
public readonly DatabaseGraph $databaseGraph,
|
public readonly Mapper $recordMapper,
|
||||||
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);
|
$builder = $builderFunc(new Builder());
|
||||||
return $this;
|
[$rootRecords, $total] = $this->mainQuery($builder);
|
||||||
}
|
|
||||||
|
|
||||||
public function orFilter(array $filterArguments): Query
|
|
||||||
{
|
|
||||||
$this->filters[] = new OrFilter($filterArguments);
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public function run(): Graph
|
|
||||||
{
|
|
||||||
$rootRecords = $this->mainQuery();
|
|
||||||
$ids = $rootRecords->pluck("id");
|
$ids = $rootRecords->pluck("id");
|
||||||
|
|
||||||
$resultChildrenEdgesTargetIds = [];
|
$resultChildrenEdgesTargetIds = [];
|
||||||
$resultChildrenEdges = new Collection();
|
$resultChildrenEdges = new Collection();
|
||||||
if ($this->options->childrenDepth > 0 && $ids->isNotEmpty()) {
|
if ($builder->childrenDepth > 0 && $ids->isNotEmpty()) {
|
||||||
$resultChildrenEdges = $this->databaseGraph->getChildren($ids->toArray(), $this->options);
|
$resultChildrenEdges = $this->databaseGraph->getChildren($ids->toArray(), $builder)->map([$this->edgeMapper, 'fromDB']);
|
||||||
$resultChildrenEdgesTargetIds = $resultChildrenEdges->pluck("target");
|
$resultChildrenEdgesTargetIds = $resultChildrenEdges->pluck("target");
|
||||||
}
|
}
|
||||||
$resultParentSourceTargetIds = [];
|
$resultParentSourceTargetIds = [];
|
||||||
$resultParentEdges = new Collection();
|
$resultParentEdges = new Collection();
|
||||||
if ($this->options->parentsDepth > 0 && $ids->isNotEmpty()) {
|
if ($builder->parentsDepth > 0 && $ids->isNotEmpty()) {
|
||||||
$resultParentEdges = $this->databaseGraph->getParents($ids->toArray(), $this->options);
|
$resultParentEdges = $this->databaseGraph->getParents($ids->toArray(), $builder)->map([$this->edgeMapper, 'fromDB']);
|
||||||
$resultParentSourceTargetIds = $resultParentEdges->pluck("source");
|
$resultParentSourceTargetIds = $resultParentEdges->pluck("source");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +45,7 @@ final class Query
|
|||||||
if (!empty($edgesIds)) {
|
if (!empty($edgesIds)) {
|
||||||
$edgeRecords = new Collection(DB::table('records')
|
$edgeRecords = new Collection(DB::table('records')
|
||||||
->whereIn("id", $edgesIds)
|
->whereIn("id", $edgesIds)
|
||||||
->whereIn("status", $this->options->status)
|
->whereIn("status", $builder->status)
|
||||||
->get()->map([$this->recordMapper, 'fromDB']));
|
->get()->map([$this->recordMapper, 'fromDB']));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,127 +54,43 @@ final class Query
|
|||||||
$edgeRecords,
|
$edgeRecords,
|
||||||
$resultChildrenEdges,
|
$resultChildrenEdges,
|
||||||
$resultParentEdges,
|
$resultParentEdges,
|
||||||
$this->options
|
$builder,
|
||||||
|
$total
|
||||||
);
|
);
|
||||||
$this->reset();
|
|
||||||
return $graph;
|
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<Record>
|
* @return array[Collection<Record>,?int]
|
||||||
*/
|
*/
|
||||||
private function mainQuery(): Collection
|
private function mainQuery(Builder $builder): array
|
||||||
{
|
{
|
||||||
$query = DB::table("records");
|
$query = DB::table("records");
|
||||||
$query = $this->parseFilters($query);
|
$query = $builder->resolveRecordFilters($query);
|
||||||
if ($this->options->limit > 0) {
|
$query = $builder->resolveReferenceFilters($query);
|
||||||
$query->limit($this->options->limit);
|
$query = $builder->resolveEdgeFilters($query);
|
||||||
$query->offset($this->options->skip);
|
$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 orderByQuery(LaravelBuilder $query, Builder $builder): LaravelBuilder
|
||||||
public
|
|
||||||
function runWithCount(): Graph
|
|
||||||
{
|
{
|
||||||
|
foreach ($builder->sort as $item) {
|
||||||
$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) {
|
|
||||||
$field = str_replace(".", "->", ltrim($item, '-'));
|
$field = str_replace(".", "->", ltrim($item, '-'));
|
||||||
$dir = str_starts_with($item, '-') ? "desc" : "asc";
|
$dir = str_starts_with($item, '-') ? "desc" : "asc";
|
||||||
if ($field) {
|
if ($field) {
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Lucent\Query;
|
|
||||||
|
|
||||||
final class QueryOptions
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
public function __construct(
|
|
||||||
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"]
|
|
||||||
)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
+1
-1
@@ -14,7 +14,7 @@ use Throwable;
|
|||||||
function result(Result $result, ?int $successCode = null, ?int $errorCode = null): Response
|
function result(Result $result, ?int $successCode = null, ?int $errorCode = null): Response
|
||||||
{
|
{
|
||||||
return match (get_class($result)) {
|
return match (get_class($result)) {
|
||||||
Success::class => response($result->success()->get(), $successCode ?? 200),
|
Success::class => response(toArray($result->success()->get()), $successCode ?? 200),
|
||||||
Error::class => response([
|
Error::class => response([
|
||||||
"error" => $result->error()->get()
|
"error" => $result->error()->get()
|
||||||
], $errorCode ?? 400)
|
], $errorCode ?? 400)
|
||||||
|
|||||||
+10
-18
@@ -3,12 +3,10 @@
|
|||||||
namespace Lucent\Revision;
|
namespace Lucent\Revision;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Lucent\Edge\EdgeCollection;
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\Record\FileInfo;
|
use Lucent\Graph\Edge\EdgeCollection;
|
||||||
use Lucent\Record\Record;
|
use Lucent\Graph\Record\Record;
|
||||||
use Lucent\Record\RecordData;
|
use Lucent\Graph\Record\System;
|
||||||
use Lucent\Record\System;
|
|
||||||
use PhpOption\Option;
|
|
||||||
|
|
||||||
readonly class Revision
|
readonly class Revision
|
||||||
{
|
{
|
||||||
@@ -16,20 +14,16 @@ readonly class Revision
|
|||||||
/**
|
/**
|
||||||
* @param string $id
|
* @param string $id
|
||||||
* @param string $recordId
|
* @param string $recordId
|
||||||
* @param string $schema
|
|
||||||
* @param System $_sys
|
* @param System $_sys
|
||||||
* @param RecordData $data
|
* @param FieldData $data
|
||||||
* @param EdgeCollection $_edges
|
* @param EdgeCollection $_edges
|
||||||
* @param Option<FileInfo> $_file
|
|
||||||
*/
|
*/
|
||||||
function __construct(
|
function __construct(
|
||||||
public string $id,
|
public string $id,
|
||||||
public string $recordId,
|
public string $recordId,
|
||||||
public string $schema,
|
public System $_sys,
|
||||||
public System $_sys,
|
public FieldData $data,
|
||||||
public RecordData $data,
|
public EdgeCollection $_edges,
|
||||||
public EdgeCollection $_edges,
|
|
||||||
public Option $_file,
|
|
||||||
|
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
@@ -45,11 +39,9 @@ readonly class Revision
|
|||||||
return new Revision(
|
return new Revision(
|
||||||
id: (string)Str::uuid(),
|
id: (string)Str::uuid(),
|
||||||
recordId: $record->id,
|
recordId: $record->id,
|
||||||
schema: $record->schema,
|
|
||||||
_sys: $record->_sys,
|
_sys: $record->_sys,
|
||||||
data: $record->data,
|
data: $record->data,
|
||||||
_edges: $edges,
|
_edges: $edges,
|
||||||
_file: empty($record->_file) ? none() : some($record->_file)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,10 +3,8 @@
|
|||||||
namespace Lucent\Revision;
|
namespace Lucent\Revision;
|
||||||
|
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
use Lucent\Edge\EdgeCollection;
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\Record\FileInfo;
|
use Lucent\Graph\Record\System;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Record\System;
|
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
use PhpOption\Option;
|
use PhpOption\Option;
|
||||||
use stdClass;
|
use stdClass;
|
||||||
@@ -77,11 +75,9 @@ class RevisionRepo
|
|||||||
return [
|
return [
|
||||||
"id" => $revision->id,
|
"id" => $revision->id,
|
||||||
"recordId" => $revision->recordId,
|
"recordId" => $revision->recordId,
|
||||||
"schema" => $revision->schema,
|
|
||||||
"_sys" => json_encode($revision->_sys),
|
"_sys" => json_encode($revision->_sys),
|
||||||
"_file" => $revision->_file->map(fn($v) => json_encode($v))->getOrElse(null),
|
|
||||||
"data" => json_encode($revision->data),
|
"data" => json_encode($revision->data),
|
||||||
"_edges" => $revision->_edges->getOrElse(null)->toJson(),
|
"_edges" => $revision->_edges->toJson(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,11 +88,9 @@ class RevisionRepo
|
|||||||
return new Revision(
|
return new Revision(
|
||||||
id: $data->id,
|
id: $data->id,
|
||||||
recordId: $data->recordId,
|
recordId: $data->recordId,
|
||||||
schema: $data->schema,
|
|
||||||
_sys: System::fromArray(json_decode($data->_sys, true)),
|
_sys: System::fromArray(json_decode($data->_sys, true)),
|
||||||
data: new RecordData(json_decode($data->data, true)),
|
data: new FieldData(json_decode($data->data, true)),
|
||||||
_edges: Option::fromValue($data->_edges)->map([EdgeCollection::class,'fromJson']),
|
_edges: $data->_edges->fromJson($data->_edges),
|
||||||
_file: Option::fromValue($data->_file)->map([FileInfo::class,'fromJSON'])
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
namespace Lucent\Revision;
|
namespace Lucent\Revision;
|
||||||
|
|
||||||
use Lucent\Channel\ChannelService;
|
use Lucent\Channel\ChannelService;
|
||||||
use Lucent\Edge\EdgeCollection;
|
use Lucent\Graph\Edge\EdgeCollection;
|
||||||
use Lucent\Record\Record;
|
use Lucent\Graph\Record\Record;
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
use PhpOption\Option;
|
use PhpOption\Option;
|
||||||
|
|
||||||
@@ -13,7 +13,7 @@ readonly class RevisionService
|
|||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private ChannelService $channelService,
|
private ChannelService $channelService,
|
||||||
private RevisionRepo $revisionRepo,
|
private RevisionRepo $revisionRepo,
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -42,15 +42,15 @@ readonly class RevisionService
|
|||||||
* @param EdgeCollection $edges
|
* @param EdgeCollection $edges
|
||||||
* @return void
|
* @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();
|
$schema = $this->channelService->getSchema($record->schema)->get();
|
||||||
if($schema->revisions <= 0){
|
if ($schema->revisions <= 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$revision = Revision::fromRecord($record, $edges);
|
$revision = Revision::fromRecord($record, $edges);
|
||||||
$this->revisionRepo->create($revision);
|
$this->revisionRepo->create($revision);
|
||||||
$this->revisionRepo->cleanupRecord($record->id,$schema->revisions);
|
$this->revisionRepo->cleanupRecord($record->id, $schema->revisions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\BlockUi;
|
namespace Lucent\Schema\BlockUi;
|
||||||
|
|
||||||
use Lucent\Record\RecordData;
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -23,7 +23,7 @@ class Heading implements FieldInterface,FieldDataInterface
|
|||||||
$this->info = new FieldInfo("heading", "Heading", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
$output->set($this->name,$value);
|
$output->set($this->name,$value);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\BlockUi;
|
namespace Lucent\Schema\BlockUi;
|
||||||
|
|
||||||
use Lucent\Record\RecordData;
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -23,7 +23,7 @@ class Markdown implements FieldInterface,FieldDataInterface
|
|||||||
$this->info = new FieldInfo("markdown", "Markdown Editor", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
$output->set($this->name,$value);
|
$output->set($this->name,$value);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\BlockUi;
|
namespace Lucent\Schema\BlockUi;
|
||||||
|
|
||||||
use Lucent\Record\RecordData;
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -23,7 +23,7 @@ class Rich implements FieldInterface,FieldDataInterface
|
|||||||
$this->info = new FieldInfo("rich", "Rich Editor", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
$output->set($this->name,$value);
|
$output->set($this->name,$value);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\BlockUi;
|
namespace Lucent\Schema\BlockUi;
|
||||||
|
|
||||||
use Lucent\Record\RecordData;
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -23,7 +23,7 @@ class Textarea implements FieldInterface,FieldDataInterface
|
|||||||
$this->info = new FieldInfo("textarea", "Textarea", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
$output->set($this->name,$value);
|
$output->set($this->name,$value);
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
namespace Lucent\Schema\Field;
|
namespace Lucent\Schema\Field;
|
||||||
|
|
||||||
|
|
||||||
use Lucent\Record\RecordData;
|
use Lucent\Graph\Data\FieldData;
|
||||||
|
|
||||||
interface FieldDataInterface
|
interface FieldDataInterface
|
||||||
{
|
{
|
||||||
public function format(RecordData $input, RecordData $output): RecordData;
|
public function format(FieldData $input, FieldData $output): FieldData;
|
||||||
|
|
||||||
public function isRequired(): bool;
|
public function isRequired(): bool;
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -31,7 +31,7 @@ class Block implements FieldInterface, FieldDataInterface, RequiredInterface
|
|||||||
$this->info = new FieldInfo("block", "Block editor", FieldType::JSON);
|
$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);
|
$value = $input->get($this->name);
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -33,7 +33,7 @@ class Checkbox implements FieldInterface,FieldDataInterface, RequiredInterface
|
|||||||
$this->info = new FieldInfo("checkbox", "Block Checkbox", FieldType::BOOLEAN);
|
$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);
|
$value = $input->get($this->name);
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -34,7 +34,7 @@ class Color implements FieldInterface,FieldDataInterface, RequiredInterface
|
|||||||
$this->info = new FieldInfo("color", "Color", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
$output->set($this->name,$value);
|
$output->set($this->name,$value);
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -37,7 +37,7 @@ class Date implements FieldInterface,FieldDataInterface, RequiredInterface, MinM
|
|||||||
$this->info = new FieldInfo("date", "Date", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
if (empty($value)) {
|
if (empty($value)) {
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -37,7 +37,7 @@ class Datetime implements FieldInterface,FieldDataInterface, RequiredInterface,
|
|||||||
$this->info = new FieldInfo("datetime", "Datetime", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
if (empty($value)) {
|
if (empty($value)) {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -32,7 +32,7 @@ class Json implements FieldInterface,FieldDataInterface, RequiredInterface
|
|||||||
$this->info = new FieldInfo("json", "JSON", FieldType::JSON);
|
$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);
|
$value = $input->get($this->name);
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -32,7 +32,7 @@ class Markdown implements FieldInterface,FieldDataInterface, RequiredInterface
|
|||||||
$this->info = new FieldInfo("markdown", "Markdown editor", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
$output->set($this->name,$value);
|
$output->set($this->name,$value);
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -37,7 +37,7 @@ class Number implements FieldInterface, RequiredInterface,FieldDataInterface, Mi
|
|||||||
$this->info = new FieldInfo("number", "Number", FieldType::NUMBER);
|
$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);
|
$value = $input->get($this->name);
|
||||||
if (!is_numeric($value)) {
|
if (!is_numeric($value)) {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -32,7 +32,7 @@ class Rich implements FieldInterface,FieldDataInterface, RequiredInterface
|
|||||||
$this->info = new FieldInfo("rich", "Rich editor", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
$output->set($this->name,$value);
|
$output->set($this->name,$value);
|
||||||
|
|||||||
@@ -3,10 +3,10 @@
|
|||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -34,7 +34,7 @@ class Slug implements FieldInterface,FieldDataInterface, RequiredInterface
|
|||||||
$this->info = new FieldInfo("slug", "Slug", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
if (empty($value)) {
|
if (empty($value)) {
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -36,7 +36,7 @@ class Text implements FieldInterface,FieldDataInterface, RequiredInterface
|
|||||||
$this->info = new FieldInfo("text", "Text", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
$output->set($this->name,$value);
|
$output->set($this->name,$value);
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -33,7 +33,7 @@ class Textarea implements FieldInterface,FieldDataInterface, RequiredInterface
|
|||||||
$this->info = new FieldInfo("textarea", "Textarea", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
$output->set($this->name,$value);
|
$output->set($this->name,$value);
|
||||||
|
|||||||
@@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
namespace Lucent\Schema\Ui;
|
namespace Lucent\Schema\Ui;
|
||||||
|
|
||||||
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\JsonSchema\Property\Property;
|
use Lucent\JsonSchema\Property\Property;
|
||||||
use Lucent\JsonSchema\Property\PropertyType;
|
use Lucent\JsonSchema\Property\PropertyType;
|
||||||
use Lucent\JsonSchema\Property\TypeProperty;
|
use Lucent\JsonSchema\Property\TypeProperty;
|
||||||
use Lucent\Record\RecordData;
|
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Schema\Field\FieldInfo;
|
use Lucent\Schema\Field\FieldInfo;
|
||||||
use Lucent\Schema\Field\FieldInterface;
|
use Lucent\Schema\Field\FieldInterface;
|
||||||
@@ -30,7 +30,7 @@ class Uuid implements FieldInterface,FieldDataInterface, RequiredInterface
|
|||||||
$this->info = new FieldInfo("uuid", "FieldType", FieldType::STRING);
|
$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);
|
$value = $input->get($this->name);
|
||||||
$output->set($this->name,$value);
|
$output->set($this->name,$value);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
namespace Lucent\Schema\Validator;
|
namespace Lucent\Schema\Validator;
|
||||||
|
|
||||||
use Lucent\Channel\ChannelService;
|
use Lucent\Channel\ChannelService;
|
||||||
use Lucent\Record\RecordData;
|
use Lucent\Graph\Data\FieldData;
|
||||||
use Lucent\Schema\Field\FieldDataInterface;
|
use Lucent\Schema\Field\FieldDataInterface;
|
||||||
use Lucent\Support\Collection;
|
use Lucent\Support\Collection;
|
||||||
use Lucent\Support\Option\Option;
|
use Lucent\Support\Option\Option;
|
||||||
@@ -23,8 +23,8 @@ class Validator
|
|||||||
* @return Collection<ValidatorError>
|
* @return Collection<ValidatorError>
|
||||||
*/
|
*/
|
||||||
public function check(
|
public function check(
|
||||||
string $schemaName,
|
string $schemaName,
|
||||||
RecordData $data,
|
FieldData $data,
|
||||||
): Collection
|
): Collection
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -39,10 +39,10 @@ class Validator
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param FieldDataInterface $field
|
* @param FieldDataInterface $field
|
||||||
* @param RecordData $recordData
|
* @param FieldData $recordData
|
||||||
* @return Option<ValidatorError>
|
* @return Option<ValidatorError>
|
||||||
*/
|
*/
|
||||||
public function validate(FieldDataInterface $field, RecordData $recordData): Option
|
public function validate(FieldDataInterface $field, FieldData $recordData): Option
|
||||||
{
|
{
|
||||||
$value = $recordData->get($field->name);
|
$value = $recordData->get($field->name);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user