Skip to content

Commit

Permalink
refactor(thread-move): wip implement thread move db query function, c…
Browse files Browse the repository at this point in the history
…ontinued, add comments more queries in transaction
  • Loading branch information
akinsey committed Aug 6, 2024
1 parent df2a2f4 commit eaf5627
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 deletions lib/epochtalk_server/models/thread.ex
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ defmodule EpochtalkServer.Models.Thread do
{:ok, thread :: t()} | {:error, Ecto.Changeset.t()}
def move(thread_id, board_id) do
case Repo.transaction(fn ->
# query and lock thread for update
thread_lock_query =
from t in Thread,
join: mt in MetadataThread,
Expand All @@ -258,9 +259,13 @@ defmodule EpochtalkServer.Models.Thread do
select: {t, mt},
lock: "FOR UPDATE"

# locked thread, reference this when updating
{thread, _thread_meta} = Repo.one(thread_lock_query)

# prevent moving board to same board
if thread.board_id != board_id do

# query old board and lock for update
old_board_lock_query =
from b in Board,
join: mb in MetadataBoard,
Expand All @@ -269,8 +274,40 @@ defmodule EpochtalkServer.Models.Thread do
select: {b, mb},
lock: "FOR UPDATE"

# locked old_board, reference this when updating
{old_board, _old_board_meta} = Repo.one(old_board_lock_query)

# query new board and lock for update
new_board_lock_query =
from b in Board,
join: mb in MetadataBoard,
on: mb.board_id == b.id,
where: b.id == ^board_id,
select: {b, mb},
lock: "FOR UPDATE"

# locked new_board, reference this when updating
{new_board, _new_board_meta} = Repo.one(new_board_lock_query)

# update old_board, thread and post count
old_board_updated =
old_board
|> change([thread_count: old_board.thread_count-1, post_count: old_board.post_count-1])
|> Repo.update!()

# update new_board, thread and post count
new_board_updated =
new_board
|> change([thread_count: new_board.thread_count+1, post_count: new_board.post_count+1])
|> Repo.update!()

# update thread's original board_id with new_board's id
thread_updated =
thread
|> change(board_id: new_board.id)
|> Repo.update!()

%{old_board_name: old_board.name, old_board_id: old_board.id}
else
{:error, :invalid_board_id}
end
Expand Down

0 comments on commit eaf5627

Please sign in to comment.