Skip to content

Commit

Permalink
Code for step 7
Browse files Browse the repository at this point in the history
  • Loading branch information
akoutmos committed Jul 29, 2020
1 parent bf57986 commit 843d645
Show file tree
Hide file tree
Showing 3 changed files with 145 additions and 0 deletions.
91 changes: 91 additions & 0 deletions lib/book_store/books.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
defmodule BookStore.Books do
import Ecto.Query, warn: false

alias BookStore.Books.Book
alias BookStore.{BookDynamicSupervisor, BookRegistry, Repo}

# All the OTP/actor model based calls
def actor_all do
BookDynamicSupervisor.all_book_pids()
|> Enum.reduce([], fn pid, acc ->
case actor_read(pid) do
%Book{} = book -> [book | acc]
_ -> acc
end
end)
end

def actor_read(book_pid) when is_pid(book_pid) do
book_pid
|> GenServer.call(:read)
|> case do
%Book{} = book -> book
_ -> {:error, :not_found}
end
end

def actor_read(book_id) do
book_id
|> BookRegistry.lookup_book()
|> case do
{:ok, pid} -> GenServer.call(pid, :read)
error -> error
end
end

def actor_order(book_id) do
book_id
|> BookRegistry.lookup_book()
|> case do
{:ok, pid} -> GenServer.call(pid, :order_copy)
error -> error
end
end

# Database only calls
def all do
Repo.all(Book)
end

def read(id) do
case Repo.get(Book, id) do
%Book{} = book ->
book

_ ->
{:error, :not_found}
end
end

def order(book_id) do
{_, result} =
Repo.transaction(fn ->
case Repo.get(Book, book_id) do
%Book{quantity: 0} ->
:no_copies_available

%Book{quantity: quantity} = book ->
update_book(book, %{quantity: quantity - 1})
:ok

thing ->
IO.inspect(thing)
{:error, :not_found}
end
end)

result
end

def update_book(%Book{} = book, attrs) do
book
|> Book.changeset(attrs)
|> Repo.update()
end

def create(attrs \\ %{}) do
%Book{}
|> Book.changeset(attrs)
|> Repo.insert()
end
end
50 changes: 50 additions & 0 deletions lib/book_store_web/controllers/book_controller.ex
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
defmodule BookStoreWeb.BookController do
use BookStoreWeb, :controller

alias BookStore.Books
alias BookStore.Books.Book

def index(conn, _params) do
# books = Books.actor_all()
books = Books.all()

conn
|> json(books)
end

def show(conn, %{"id" => book_id}) do
# book = Books.actor_read(book_id)
book = Books.read(book_id)

case book do
%Book{} = book ->
conn
|> json(book)

_ ->
conn
|> put_status(404)
|> json(%{error: "Not found"})
end
end

def order(conn, %{"book_id" => book_id}) do
# status = Books.actor_order(book_id)
status = Books.order(book_id)

case status do
:ok ->
conn
|> put_status(201)
|> json(%{status: "Order placed"})

:no_copies_available ->
json(conn, %{status: "Not enough copies on hand to complete order"})

{:error, :not_found} ->
conn
|> put_status(404)
|> json(%{error: "Not found"})
end
end
end
4 changes: 4 additions & 0 deletions lib/book_store_web/router.ex
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ defmodule BookStoreWeb.Router do

scope "/api", BookStoreWeb do
pipe_through :api

resources "/books", BookController, only: [:index, :show] do
post "/order", BookController, :order
end
end

# Enables LiveDashboard only for development
Expand Down

0 comments on commit 843d645

Please sign in to comment.