From a7b74acaa0a5ecb57fa779f05bb1ba0c1db0630e Mon Sep 17 00:00:00 2001 From: paranarimasu <33796518+paranarimasu@users.noreply.github.com> Date: Sun, 12 Mar 2023 18:44:39 -0500 Subject: [PATCH] fix(api): use nested transactions for store track endpoint (#551) --- .../List/Playlist/Track/StoreTrackAction.php | 91 +++++++++++-------- .../List/Playlist/InsertTrackAction.php | 62 +++++++++---- 2 files changed, 96 insertions(+), 57 deletions(-) diff --git a/app/Actions/Http/Api/List/Playlist/Track/StoreTrackAction.php b/app/Actions/Http/Api/List/Playlist/Track/StoreTrackAction.php index 622b73528..13592dd2e 100644 --- a/app/Actions/Http/Api/List/Playlist/Track/StoreTrackAction.php +++ b/app/Actions/Http/Api/List/Playlist/Track/StoreTrackAction.php @@ -14,6 +14,7 @@ use Exception; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Arr; +use Illuminate\Support\Facades\DB; use Illuminate\Support\Facades\Log; /** @@ -42,49 +43,65 @@ class StoreTrackAction Log::debug('Track Parameters', $trackParameters); - $storeAction = new StoreAction(); + try { + DB::beginTransaction(); - /** @var PlaylistTrack $track */ - $track = $storeAction->store($builder, $trackParameters); + Log::debug('Begin Store Transaction'); - if (! empty($nextId) && empty($previousId)) { - /** @var PlaylistTrack $next */ - $next = PlaylistTrack::query() - ->with(PlaylistTrack::RELATION_PREVIOUS) - ->findOrFail($nextId); + $storeAction = new StoreAction(); - Log::debug('Next Track', $next->toArray()); + /** @var PlaylistTrack $track */ + $track = $storeAction->store($builder, $trackParameters); - $insertAction = new InsertTrackBeforeAction(); + if (! empty($nextId) && empty($previousId)) { + /** @var PlaylistTrack $next */ + $next = PlaylistTrack::query() + ->with(PlaylistTrack::RELATION_PREVIOUS) + ->findOrFail($nextId); - $insertAction->insertBefore($playlist, $track, $next); + Log::debug('Next Track', $next->toArray()); - Log::debug('Insert Before Completed'); + $insertAction = new InsertTrackBeforeAction(); + + $insertAction->insertBefore($playlist, $track, $next); + + Log::debug('Insert Before Completed'); + } + + if (! empty($previousId) && empty($nextId)) { + /** @var PlaylistTrack $previous */ + $previous = PlaylistTrack::query() + ->with(PlaylistTrack::RELATION_NEXT) + ->findOrFail($previousId); + + Log::debug('Previous Track', $previous->toArray()); + + $insertAction = new InsertTrackAfterAction(); + + $insertAction->insertAfter($playlist, $track, $previous); + + Log::debug('Insert After Completed'); + } + + if (empty($nextId) && empty($previousId)) { + $insertAction = new InsertTrackAction(); + + $insertAction->insert($playlist, $track); + + Log::debug('Insert Completed'); + } + + DB::commit(); + + Log::debug('End Store Transaction'); + + return $storeAction->cleanup($track); + } catch (Exception $e) { + Log::error($e->getMessage()); + + DB::rollBack(); + + throw $e; } - - if (! empty($previousId) && empty($nextId)) { - /** @var PlaylistTrack $previous */ - $previous = PlaylistTrack::query() - ->with(PlaylistTrack::RELATION_NEXT) - ->findOrFail($previousId); - - Log::debug('Previous Track', $previous->toArray()); - - $insertAction = new InsertTrackAfterAction(); - - $insertAction->insertAfter($playlist, $track, $previous); - - Log::debug('Insert After Completed'); - } - - if (empty($nextId) && empty($previousId)) { - $insertAction = new InsertTrackAction(); - - $insertAction->insert($playlist, $track); - - Log::debug('Insert Completed'); - } - - return $storeAction->cleanup($track); } } diff --git a/app/Actions/Models/List/Playlist/InsertTrackAction.php b/app/Actions/Models/List/Playlist/InsertTrackAction.php index 2b0b26773..cc781d274 100644 --- a/app/Actions/Models/List/Playlist/InsertTrackAction.php +++ b/app/Actions/Models/List/Playlist/InsertTrackAction.php @@ -29,23 +29,59 @@ class InsertTrackAction try { DB::beginTransaction(); - Log::debug('Begin Transaction'); + Log::debug('Begin Playlist Transaction'); if ($playlist->first()->doesntExist()) { $playlist->first()->associate($track); } - Log::debug('First Playlist Track'); + Log::debug('First Playlist Track Set'); + + $this->insertTrack($playlist, $track); + + Log::debug('Insert Track Completed'); + + $playlist->last()->associate($track)->save(); + + Log::debug('First Playlist Track Set'); + + DB::commit(); + + Log::debug('End Playlist Transaction'); + } catch (Exception $e) { + Log::error($e->getMessage()); + + DB::rollBack(); + + throw $e; + } + } + + /** + * Set Track Relation with nested transaction. + * + * @param Playlist $playlist + * @param PlaylistTrack $track + * @return void + * + * @throws Exception + */ + private function insertTrack(Playlist $playlist, PlaylistTrack $track): void + { + try { + DB::beginTransaction(); + + Log::debug('Begin Track Transaction'); $last = $playlist->last; $last?->next()?->associate($track)?->save(); $track->previous()->associate($last); - Log::debug('Track Last Relation'); + Log::debug('Set Previous Track Relation'); $track->next()->disassociate(); - Log::debug('Track Next Relation'); + Log::debug('Set Next Track Relation'); if ($track->isDirty()) { $track->save(); @@ -53,23 +89,9 @@ class InsertTrackAction Log::debug('Track Saved'); - $playlist->last()->dissociate(); - - Log::debug('Dissociate last track'); - - $lastBuilder = $playlist->last(); - - Log::debug('Last Track builder'); - - $modifiedPlaylist = $lastBuilder->associate($track); - - Log::debug('Associate last track'); - - $modifiedPlaylist->save(); - - Log::debug('Save Playlist'); - DB::commit(); + + Log::debug('End Track Transaction'); } catch (Exception $e) { Log::error($e->getMessage());