revisions complete
This commit is contained in:
@@ -341,20 +341,19 @@ class RecordController extends Controller
|
||||
}
|
||||
return ok();
|
||||
}
|
||||
//
|
||||
// public function rollback(Request $request)
|
||||
// {
|
||||
// try {
|
||||
// $this->recordService->rollback(
|
||||
// userId: AuthService::currentUserId($request),
|
||||
// recordId: $request->route("rid"),
|
||||
// version: (int)$request->route("version")
|
||||
// );
|
||||
// } catch (ValidatorException $th) {
|
||||
// return fail($th->getFirstValidatorError());
|
||||
// } catch (LucentException|Throwable $th) {
|
||||
// return fail($th);
|
||||
// }
|
||||
// return ok();
|
||||
// }
|
||||
|
||||
public function rollback(Request $request)
|
||||
{
|
||||
try {
|
||||
$this->recordService->rollback(
|
||||
recordId: $request->route("rid"),
|
||||
version: (int)$request->route("version")
|
||||
);
|
||||
} catch (ValidatorException $th) {
|
||||
return fail($th->getFirstValidatorError());
|
||||
} catch (LucentException|Throwable $th) {
|
||||
return fail($th);
|
||||
}
|
||||
return ok();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,38 +4,22 @@ namespace Lucent\Http\Controller;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Lucent\Account\Auth;
|
||||
use Lucent\Channel\ChannelContext;
|
||||
use Lucent\Record\RecordRepo;
|
||||
use Lucent\Revision\RevisionRepo;
|
||||
use Lucent\Schema\SchemaRepo;
|
||||
use Lucent\Revision\RevisionService;
|
||||
use function Lucent\Response\fail;
|
||||
use function Lucent\Response\ok;
|
||||
|
||||
class RevisionController extends Controller
|
||||
{
|
||||
public function __construct(
|
||||
public RevisionService $revisionService
|
||||
){}
|
||||
|
||||
public function index(Request $request)
|
||||
{
|
||||
|
||||
$revisions = RevisionRepo::getByRecordId($request->route("rid"));
|
||||
return ok($revisions);
|
||||
$revisions = $this->revisionService->getByRecordId($request->route("rid"));
|
||||
return ok($revisions->toArray());
|
||||
}
|
||||
|
||||
public function rollback(Request $request)
|
||||
{
|
||||
$schemas = SchemaRepo::all();
|
||||
$revision = RevisionRepo::getByRecordIdAndVersion($request->route("rid"), (int)$request->route("version"));
|
||||
|
||||
try {
|
||||
RecordRepo::replaceMany($schemas, [$revision->toDB()], Auth::currentUserId());
|
||||
} catch (\Lucent\Schema\Validator\ValidatorException $th) {
|
||||
return fail($th->getFirstValidatorError());
|
||||
} catch (\Lucent\LucentException $th) {
|
||||
return fail($th);
|
||||
} catch (\Throwable $th) {
|
||||
return fail($th);
|
||||
}
|
||||
return ok();
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -8,7 +8,7 @@ use Lucent\Http\Controller\FileController;
|
||||
use Lucent\Http\Controller\HomeController;
|
||||
use Lucent\Http\Controller\MemberController;
|
||||
use Lucent\Http\Controller\RecordController;
|
||||
use Lucent\Revision\RevisionController;
|
||||
use Lucent\Http\Controller\RevisionController;
|
||||
|
||||
|
||||
Route::group([
|
||||
|
||||
@@ -43,8 +43,7 @@ class RecordRepo
|
||||
): void
|
||||
{
|
||||
|
||||
DB::table("records")
|
||||
->whereIn("id", $ids)->delete();
|
||||
DB::table("records")->whereIn("id", $ids)->delete();
|
||||
DB::table("edges")->whereIn("source", $ids)->delete();
|
||||
DB::table("edges")->whereIn("target", $ids)->delete();
|
||||
DB::table("revisions")->whereIn("recordId", $ids)->delete();
|
||||
|
||||
@@ -92,7 +92,7 @@ readonly class RecordService
|
||||
|
||||
RecordRepo::create($record);
|
||||
EdgeRepo::update($record->id, $uniqueEdgesCollection);
|
||||
$this->revisionService->create($record);
|
||||
$this->revisionService->create($record,$uniqueEdgesCollection);
|
||||
return $record->id;
|
||||
|
||||
}
|
||||
@@ -119,7 +119,7 @@ readonly class RecordService
|
||||
}
|
||||
$formattedData = $this->inputFormatter->fill($record->schema, new RecordData($data));
|
||||
|
||||
$uniqueEdgesCollection = null;
|
||||
$uniqueEdgesCollection = new EdgeCollection();
|
||||
if ($updateEdges) {
|
||||
$uniqueEdges = collect($edges)
|
||||
->map(function ($edge, $index) {
|
||||
@@ -161,7 +161,7 @@ readonly class RecordService
|
||||
EdgeRepo::update($newRecord->id, $uniqueEdgesCollection);
|
||||
}
|
||||
|
||||
$this->revisionService->create($newRecord);
|
||||
$this->revisionService->create($newRecord,$uniqueEdgesCollection);
|
||||
|
||||
}
|
||||
|
||||
@@ -240,6 +240,8 @@ readonly class RecordService
|
||||
$this->update(
|
||||
id: $revision->recordId,
|
||||
data: $revision->data->toArray(),
|
||||
edges: toArray($revision->_edges),
|
||||
updateEdges: true
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
+14
-41
@@ -3,6 +3,9 @@
|
||||
namespace Lucent\Revision;
|
||||
|
||||
use Illuminate\Support\Str;
|
||||
use Lucent\Edge\Edge;
|
||||
use Lucent\Edge\EdgeCollection;
|
||||
use Lucent\Primitive\Collection;
|
||||
use Lucent\Record\File;
|
||||
use Lucent\Record\Record;
|
||||
use Lucent\Record\RecordData;
|
||||
@@ -13,51 +16,20 @@ readonly class Revision
|
||||
{
|
||||
|
||||
function __construct(
|
||||
public string $id,
|
||||
public string $recordId,
|
||||
public string $schema,
|
||||
public System $_sys,
|
||||
public RecordData $data,
|
||||
public ?File $_file = null,
|
||||
public string $id,
|
||||
public string $recordId,
|
||||
public string $schema,
|
||||
public System $_sys,
|
||||
public RecordData $data,
|
||||
public EdgeCollection $_edges,
|
||||
public ?File $_file = null,
|
||||
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public static function fromDB(stdClass $data): Revision
|
||||
{
|
||||
|
||||
$file = json_decode($data->_file, true);
|
||||
if (!empty($file)) {
|
||||
|
||||
$file = new File(...$file);
|
||||
} else {
|
||||
$file = null;
|
||||
}
|
||||
|
||||
return new Revision(
|
||||
id: $data->id,
|
||||
recordId: $data->recordId,
|
||||
schema: $data->schema,
|
||||
_sys: System::fromArray(json_decode($data->_sys, true)),
|
||||
data: new RecordData(json_decode($data->data, true)),
|
||||
_file: $file,
|
||||
);
|
||||
}
|
||||
|
||||
public function toDB(): array
|
||||
{
|
||||
return [
|
||||
"id" => $this->id,
|
||||
"recordId" => $this->recordId,
|
||||
"schema" => $this->schema,
|
||||
"_sys" => json_encode($this->_sys),
|
||||
"_file" => json_encode($this->_file),
|
||||
"data" => json_encode($this->data),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
public static function fromRecord(Record $record): Revision
|
||||
public static function fromRecord(Record $record, EdgeCollection $edges): Revision
|
||||
{
|
||||
return new Revision(
|
||||
id: (string)Str::uuid(),
|
||||
@@ -65,7 +37,8 @@ readonly class Revision
|
||||
schema: $record->schema,
|
||||
_sys: $record->_sys,
|
||||
data: $record->data,
|
||||
_file: $record->_file,
|
||||
_edges: $edges,
|
||||
_file: $record->_file
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Lucent\Revision;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Http\Response;
|
||||
use function Lucent\Response\ok;
|
||||
|
||||
class RevisionController extends Controller
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private readonly RevisionRepo $revisionRepo,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
public function index(Request $request): Response
|
||||
{
|
||||
$revisions = $this->revisionRepo->getByRecordId($request->route("rid"));
|
||||
return ok($revisions->toArray());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -3,8 +3,14 @@
|
||||
namespace Lucent\Revision;
|
||||
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Lucent\Edge\Edge;
|
||||
use Lucent\Edge\EdgeCollection;
|
||||
use Lucent\Primitive\Collection;
|
||||
use Lucent\Record\File;
|
||||
use Lucent\Record\RecordData;
|
||||
use Lucent\Record\System;
|
||||
use PhpOption\Option;
|
||||
use stdClass;
|
||||
|
||||
class RevisionRepo
|
||||
{
|
||||
@@ -13,7 +19,7 @@ class RevisionRepo
|
||||
|
||||
public function create(Revision $revision): string
|
||||
{
|
||||
$revisionDB = $revision->toDB();
|
||||
$revisionDB = $this->toDB($revision);
|
||||
DB::table($this->table)->insert($revisionDB);
|
||||
return $revision->id;
|
||||
}
|
||||
@@ -27,13 +33,28 @@ class RevisionRepo
|
||||
$revisions = DB::table($this->table)
|
||||
->where("recordId", $rid)
|
||||
->get()
|
||||
->map([Revision::class, 'fromDB'])
|
||||
->map([$this, 'fromDB'])
|
||||
->sortByDesc("_sys.version")
|
||||
->toArray();
|
||||
|
||||
return new Collection($revisions);
|
||||
}
|
||||
|
||||
public function cleanupRecord(string $rid, int $numKeep): void
|
||||
{
|
||||
$revisionIds = DB::table($this->table)
|
||||
->where("recordId", $rid)
|
||||
->orderBy("_sys->version", "desc")
|
||||
->limit(100)
|
||||
->skip($numKeep)
|
||||
->get()
|
||||
->pluck("id");
|
||||
|
||||
DB::table($this->table)
|
||||
->whereIn("id", $revisionIds)
|
||||
->delete();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return Option<Revision>
|
||||
@@ -49,6 +70,42 @@ class RevisionRepo
|
||||
return none();
|
||||
}
|
||||
|
||||
return some(Revision::fromDB($res));
|
||||
return some($this->fromDB($res));
|
||||
}
|
||||
|
||||
public function toDB(Revision $revision): array
|
||||
{
|
||||
return [
|
||||
"id" => $revision->id,
|
||||
"recordId" => $revision->recordId,
|
||||
"schema" => $revision->schema,
|
||||
"_sys" => json_encode($revision->_sys),
|
||||
"_file" => json_encode($revision->_file),
|
||||
"data" => json_encode($revision->data),
|
||||
"_edges" => $revision->_edges->toJson(),
|
||||
];
|
||||
}
|
||||
|
||||
public function fromDB(stdClass $data): Revision
|
||||
{
|
||||
$file = json_decode($data->_file, true);
|
||||
if (!empty($file)) {
|
||||
|
||||
$file = new File(...$file);
|
||||
} else {
|
||||
$file = null;
|
||||
}
|
||||
|
||||
$edges = array_map(fn($e) => Edge::fromArray($e), json_decode($data->_edges ?? "[]", true));
|
||||
|
||||
return new Revision(
|
||||
id: $data->id,
|
||||
recordId: $data->recordId,
|
||||
schema: $data->schema,
|
||||
_sys: System::fromArray(json_decode($data->_sys, true)),
|
||||
data: new RecordData(json_decode($data->data, true)),
|
||||
_edges: new EdgeCollection(...$edges),
|
||||
_file: $file
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,10 @@
|
||||
|
||||
namespace Lucent\Revision;
|
||||
|
||||
use Lucent\Channel\ChannelService;
|
||||
use Lucent\Edge\Edge;
|
||||
use Lucent\Edge\EdgeCollection;
|
||||
use Lucent\Primitive\Collection;
|
||||
use Lucent\Record\Record;
|
||||
use PhpOption\Option;
|
||||
|
||||
@@ -9,11 +13,21 @@ readonly class RevisionService
|
||||
{
|
||||
|
||||
public function __construct(
|
||||
private ChannelService $channelService,
|
||||
private RevisionRepo $revisionRepo,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Collection<Revision>
|
||||
*/
|
||||
public function getByRecordId(string $recordId): Collection
|
||||
{
|
||||
|
||||
return $this->revisionRepo->getByRecordId($recordId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Option<Revision>
|
||||
*/
|
||||
@@ -23,10 +37,16 @@ readonly class RevisionService
|
||||
return $this->revisionRepo->getByRecordIdAndVersion($recordId, $version);
|
||||
}
|
||||
|
||||
public function create(Record $record): string
|
||||
|
||||
public function create(Record $record, EdgeCollection $edges): void
|
||||
{
|
||||
$revision = Revision::fromRecord($record);
|
||||
return $this->revisionRepo->create($revision);
|
||||
$schema = $this->channelService->getSchema($record->schema)->get();
|
||||
if($schema->revisions <= 0){
|
||||
return;
|
||||
}
|
||||
$revision = Revision::fromRecord($record, $edges);
|
||||
$this->revisionRepo->create($revision);
|
||||
$this->revisionRepo->cleanupRecord($record->id,$schema->revisions);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ class CollectionSchema implements Schema
|
||||
/**
|
||||
* @param Collection<FieldInterface> $fields
|
||||
* @param array<string> $visible
|
||||
* @param array<string> $fields
|
||||
*/
|
||||
function __construct(
|
||||
public string $name,
|
||||
@@ -22,6 +21,7 @@ class CollectionSchema implements Schema
|
||||
public bool $isEntry = false,
|
||||
public string $color = "",
|
||||
public string $titleTemplate = "",
|
||||
public int $revisions = 0,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ class FilesSchema implements Schema
|
||||
public bool $isEntry = false,
|
||||
public string $color = "",
|
||||
public string $titleTemplate = "",
|
||||
public int $revisions = 0,
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ class SchemaService
|
||||
isEntry: $schemaArr["isEntry"] ?? false,
|
||||
color: $schemaArr["color"] ?? "",
|
||||
titleTemplate: $schemaArr["titleTemplate"] ?? "",
|
||||
revisions: $schemaArr["revisions"] ?? 0,
|
||||
),
|
||||
"files" => new FilesSchema(
|
||||
name: $schemaArr["name"],
|
||||
@@ -35,6 +36,7 @@ class SchemaService
|
||||
isEntry: $schemaArr["isEntry"] ?? false,
|
||||
color: $schemaArr["color"] ?? "",
|
||||
titleTemplate: $schemaArr["titleTemplate"] ?? "",
|
||||
revisions: $schemaArr["revisions"] ?? 0,
|
||||
),
|
||||
"block" => new BlockSchema(
|
||||
name: $schemaArr["name"],
|
||||
|
||||
Reference in New Issue
Block a user