Skip to content

Commit

Permalink
Use Model for Join write operations
Browse files Browse the repository at this point in the history
  • Loading branch information
mvorisek committed Jan 16, 2022
1 parent c35a2f5 commit ec9b725
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 41 deletions.
27 changes: 27 additions & 0 deletions src/Model/Join.php
Original file line number Diff line number Diff line change
Expand Up @@ -134,9 +134,36 @@ public function __construct($foreignTable = null)
}
}

/**
* Create fake foreign model, in the future, this method should be removed
* in favor of always requiring an object model.
*/
protected function createFakeForeignModel(): Model
{
$fakeModel = new Model($this->getOwner()->persistence, [
'table' => $this->foreign_table,
'id_field' => $this->foreign_field,
]);
foreach ($this->getOwner()->getFields() as $ownerField) {
if ($ownerField->hasJoin() && $ownerField->getJoin()->short_name === $this->short_name) {
$fakeModel->addField($ownerField->short_name, [
'actual' => $ownerField->actual,
'type' => $ownerField->type,
]);
}
}

return $fakeModel;
}

public function getForeignModel(): Model
{
if (is_string($this->foreign_table)) {
// TODO this should be removed in the future
if (!isset($this->getOwner()->with[$this->foreign_table])) {
return $this->createFakeForeignModel();
}

return $this->getOwner()->with[$this->foreign_table]['model'];
}

Expand Down
74 changes: 33 additions & 41 deletions src/Persistence/Sql/Join.php
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,6 @@ protected function init(): void
}
}

/**
* Returns DSQL query.
*/
public function dsql(): Query
{
$dsql = $this->getOwner()->persistence->initQuery($this->getOwner());

return $dsql->reset('table')->table($this->foreign_table, $this->foreign_alias);
}

/**
* Before query is executed, this method will be called.
*/
Expand Down Expand Up @@ -137,17 +127,18 @@ public function beforeInsert(Model $entity, array &$data): void

$model = $this->getOwner();

// The value for the master_field is set, so we are going to use existing record anyway
if ($model->hasField($this->master_field) && $entity->get($this->master_field)) {
// the value for the master_field is set, so we are going to use existing record anyway
if ($model->hasField($this->master_field) && $entity->get($this->master_field) !== null) {
return;
}

$query = $this->dsql();
$query->mode('insert');
$query->setMulti($model->persistence->typecastSaveRow($model, $this->getAndUnsetSaveBuffer($entity)));
// $query->set($this->foreign_field, null);
$query->mode('insert')->execute(); // TODO IMPORTANT migrate to Model insert
$this->setId($entity, $model->persistence->lastInsertId(new Model($model->persistence, ['table' => $this->foreign_table])));
$foreignModel = $this->getForeignModel();
$foreignEntity = $foreignModel->createEntity()
->setMulti($this->getAndUnsetSaveBuffer($entity))
/*->set($this->foreign_field, null)*/;
$foreignEntity->save();

$this->setId($entity, $foreignEntity->getId());

if ($this->hasJoin()) {
$this->getJoin()->setSaveBufferValue($entity, $this->master_field, $this->getId($entity));
Expand All @@ -162,18 +153,13 @@ public function afterInsert(Model $entity): void
return;
}

$model = $this->getOwner();
$foreignModel = $this->getForeignModel();
$foreignEntity = $foreignModel->createEntity()
->setMulti($this->getAndUnsetSaveBuffer($entity))
->set($this->foreign_field, $this->hasJoin() ? $this->getJoin()->getId($entity) : $entity->getId());
$foreignEntity->save();

$query = $this->dsql();
$query->setMulti($model->persistence->typecastSaveRow($model, $this->getAndUnsetSaveBuffer($entity)));
$query->set($this->foreign_field, $this->hasJoin() ? $this->getJoin()->getId($entity) : $entity->getId());
$query->mode('insert')->execute(); // TODO IMPORTANT migrate to Model insert
$modelForLastInsertId = $model;
while (is_object($modelForLastInsertId->table)) {
$modelForLastInsertId = $modelForLastInsertId->table;
}
// assumes same ID field across all nested models (not needed once migrated to Model insert)
$this->setId($entity, $model->persistence->lastInsertId($modelForLastInsertId));
$this->setId($entity, $entity->getId()); // TODO why is this here? it seems to be not needed
}

public function beforeUpdate(Model $entity, array &$data): void
Expand All @@ -186,14 +172,16 @@ public function beforeUpdate(Model $entity, array &$data): void
return;
}

$model = $this->getOwner();

$query = $this->dsql();
$query->setMulti($model->persistence->typecastSaveRow($model, $this->getAndUnsetSaveBuffer($entity)));

$id = $this->reverse ? $entity->getId() : $entity->get($this->master_field);

$query->where($this->foreign_field, $id)->mode('update')->execute(); // TODO IMPORTANT migrate to Model update
$foreignModel = $this->getForeignModel();
$foreignId = $this->reverse ? $entity->getId() : $entity->get($this->master_field);
$saveBuffer = $this->getAndUnsetSaveBuffer($entity);
$foreignModel->atomic(function () use ($foreignModel, $foreignId, $saveBuffer) {
$foreignModel = (clone $foreignModel)->addCondition($this->foreign_field, $foreignId);
foreach ($foreignModel as $foreignEntity) {
$foreignEntity->setMulti($saveBuffer);
$foreignEntity->save();
}
});
}

public function doDelete(Model $entity): void
Expand All @@ -202,9 +190,13 @@ public function doDelete(Model $entity): void
return;
}

$query = $this->dsql();
$id = $this->reverse ? $entity->getId() : $entity->get($this->master_field);

$query->where($this->foreign_field, $id)->mode('delete')->execute(); // TODO IMPORTANT migrate to Model delete
$foreignModel = $this->getForeignModel();
$foreignId = $this->reverse ? $entity->getId() : $entity->get($this->master_field);
$foreignModel->atomic(function () use ($foreignModel, $foreignId) {
$foreignModel = (clone $foreignModel)->addCondition($this->foreign_field, $foreignId);
foreach ($foreignModel as $foreignEntity) {
$foreignEntity->delete();
}
});
}
}

0 comments on commit ec9b725

Please sign in to comment.