Working proposal apply code, fixed schema (need reset - artisan migrate:fresh)

This commit is contained in:
2018-08-11 18:42:12 +02:00
parent 8efc31d820
commit f2910f977f
12 changed files with 168 additions and 69 deletions
+109 -7
View File
@@ -4,6 +4,9 @@ namespace App\Models;
use App\Models\Concerns\Reportable;
use App\Tables\Changeset;
use App\Tables\Column;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Support\Facades\DB;
use MightyPork\Exceptions\NotApplicableException;
/**
@@ -16,7 +19,7 @@ use MightyPork\Exceptions\NotApplicableException;
* @property int $revision_id
* @property int $author_id
* @property string $note
* @property Proposal $changes - JSONB
* @property Changeset $changeset - JSONB
* @property-read User $author
* @property-read Table $table
* @property-read Revision $revision
@@ -46,17 +49,30 @@ class Proposal extends BaseModel
return $this->belongsTo(Table::class);
}
public function getChangesAttribute($value)
public function scopeUnmerged(Builder $query, Table $table)
{
$changeset = Changeset::fromObject(fromJSON($value));
return $query->whereRaw('
"id" NOT IN
(SELECT "proposal_id" FROM "revisions"
LEFT JOIN "table_revision_pivot"
ON "revisions"."id" = "table_revision_pivot"."revision_id"
WHERE "table_revision_pivot"."table_id" = ?)',
[
$table->getKey()
]);
}
public function getChangesetAttribute()
{
$changeset = Changeset::fromObject(fromJSON($this->attributes['changes'], true));
$changeset->revision = $this->revision;
$changeset->table = $this->table;
$changeset->table = $this->getAttribute('table');
$changeset->note = $this->note;
return $changeset;
}
public function setChangesAttribute($value)
public function setChangesetAttribute($value)
{
if ($value instanceof Changeset) {
$this->attributes['changes'] = toJSON($value->toObject());
@@ -98,10 +114,96 @@ class Proposal extends BaseModel
// relations
'table_id' => $changeset->table->getKey(),
'revision_id' => $changeset->revision->getKey(),
'author_id' => \Auth::user()->getKey(),
'author_id' => \user()->getKey(),
// the proposal info
'note' => $changeset->note,
'changes' => $changeset->toObject(),
'changeset' => $changeset, // this is without a note
]);
}
/**
* Accept the proposed changes: create a new revision based on the parent revision
* and changes described in this Proposal, and link it to the table.
*/
public function createRevision()
{
DB::transaction(function () {
$changeset = $this->changeset;
$columns = $changeset->fetchAndTransformColumns();
$newRevision = new Revision([
'ancestor_id' => $changeset->revision->getKey(),
'proposal_id' => $this->getKey(),
'note' => $changeset->note,
'row_count' => 0, // Will be set later when we are sure about the row count
'columns' => array_map(function(Column $c) {
return $c->toArray(false);
}, $columns),
]);
$newRevision->save(); // this gives it an ID, needed to associate rows
// --- Copy over rows that are left unchanged ---
// ...this directly works with the pivot
$removedRowIds = (array)($changeset->removedRows ?? []);
$changedRowIds = array_keys((array)($changeset->rowUpdates ?? []));
$excludedGRIDs = array_merge($removedRowIds, $changedRowIds);
$excluded_ids = [];
if ($excludedGRIDs) {
$questionmarks = str_repeat('?,', count($excludedGRIDs) - 1) . '?';
$excluded_ids = $changeset->revision->rows()->whereRaw("data->'_id' IN ($questionmarks)", $excludedGRIDs)
->get(['id'])->pluck('id')->toArray();
}
$query = '
INSERT INTO revision_row_pivot
SELECT ? as revision_id, row_id FROM revision_row_pivot
WHERE revision_id = ?';
$subs = [
$newRevision->getKey(),
$changeset->revision->getKey()
];
if ($excluded_ids) {
$questionmarks = str_repeat('?,', count($excluded_ids) - 1) . '?';
$query .= ' AND row_id NOT IN (' . $questionmarks . ')';
$subs = array_merge($subs, $excluded_ids);
}
DB::statement($query, $subs);
// --- Insert modified rows ---
if ($changeset->rowUpdates) {
$ids = array_keys($changeset->rowUpdates);
$questionmarks = str_repeat('?,', count($ids) - 1) . '?';
$toChange = $changeset->revision->rows()->whereRaw("data->'_id' IN ($questionmarks)", $ids)->get();
$updateData = [];
foreach ($toChange as $row) {
$updateData[] = new Row([
'data' => $changeset->transformRow($row->data, false),
]);
}
$newRevision->rows()->saveMany($updateData);
}
// --- Insert new rows ---
if ($changeset->newRows) {
$newRowData = [];
foreach ($changeset->newRows as $newRow) {
$newRowData[] = new Row(['data' => $newRow]);
}
$newRevision->rows()->saveMany($newRowData);
}
$newRevision->update(['row_count' => $newRevision->rows()->count()]);
// --- Attach this revision to the table ---
$changeset->table->revisions()->save($newRevision);
$changeset->table->update(['revision_id' => $newRevision->getKey()]);
});
}
}
+5 -4
View File
@@ -13,12 +13,13 @@ use Riesjart\Relaquent\Model\Concerns\HasRelaquentRelationships;
* @property \Carbon\Carbon $created_at
* @property \Carbon\Carbon $updated_at
* @property int $ancestor_id
* @property int $proposal_id
* @property string $note
* @property object $columns
* @property int $row_count - cached number of rows in the revision
* @property-read Revision|null $parentRevision
* @property-read Row[]|Collection $rows
* @property-read Proposal|null $sourceProposal - proposal that was used to create this revision
* @property-read Proposal|null $proposal - proposal that was used to create this revision
* @property-read Proposal[]|Collection $dependentProposals
*/
class Revision extends BaseModel
@@ -52,15 +53,15 @@ class Revision extends BaseModel
}
/** Proposal that lead to this revision */
public function sourceProposal()
public function proposal()
{
return $this->hasOneThrough(Proposal::class, 'revision_proposal_pivot');
return $this->belongsTo(Proposal::class, 'proposal_id');
}
/** Proposals that depend on this revision */
public function dependentProposals()
{
return $this->hasMany(Proposal::class);
return $this->hasMany(Proposal::class, 'revision_id');
}
/** Revision this orignates from */