Skip to content

Commit 843d645

Browse files
committed
Code for step 7
1 parent bf57986 commit 843d645

File tree

3 files changed

+145
-0
lines changed

3 files changed

+145
-0
lines changed

lib/book_store/books.ex

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
defmodule BookStore.Books do
2+
import Ecto.Query, warn: false
3+
4+
alias BookStore.Books.Book
5+
alias BookStore.{BookDynamicSupervisor, BookRegistry, Repo}
6+
7+
# All the OTP/actor model based calls
8+
def actor_all do
9+
BookDynamicSupervisor.all_book_pids()
10+
|> Enum.reduce([], fn pid, acc ->
11+
case actor_read(pid) do
12+
%Book{} = book -> [book | acc]
13+
_ -> acc
14+
end
15+
end)
16+
end
17+
18+
def actor_read(book_pid) when is_pid(book_pid) do
19+
book_pid
20+
|> GenServer.call(:read)
21+
|> case do
22+
%Book{} = book -> book
23+
_ -> {:error, :not_found}
24+
end
25+
end
26+
27+
def actor_read(book_id) do
28+
book_id
29+
|> BookRegistry.lookup_book()
30+
|> case do
31+
{:ok, pid} -> GenServer.call(pid, :read)
32+
error -> error
33+
end
34+
end
35+
36+
def actor_order(book_id) do
37+
book_id
38+
|> BookRegistry.lookup_book()
39+
|> case do
40+
{:ok, pid} -> GenServer.call(pid, :order_copy)
41+
error -> error
42+
end
43+
end
44+
45+
# Database only calls
46+
def all do
47+
Repo.all(Book)
48+
end
49+
50+
def read(id) do
51+
case Repo.get(Book, id) do
52+
%Book{} = book ->
53+
book
54+
55+
_ ->
56+
{:error, :not_found}
57+
end
58+
end
59+
60+
def order(book_id) do
61+
{_, result} =
62+
Repo.transaction(fn ->
63+
case Repo.get(Book, book_id) do
64+
%Book{quantity: 0} ->
65+
:no_copies_available
66+
67+
%Book{quantity: quantity} = book ->
68+
update_book(book, %{quantity: quantity - 1})
69+
:ok
70+
71+
thing ->
72+
IO.inspect(thing)
73+
{:error, :not_found}
74+
end
75+
end)
76+
77+
result
78+
end
79+
80+
def update_book(%Book{} = book, attrs) do
81+
book
82+
|> Book.changeset(attrs)
83+
|> Repo.update()
84+
end
85+
86+
def create(attrs \\ %{}) do
87+
%Book{}
88+
|> Book.changeset(attrs)
89+
|> Repo.insert()
90+
end
91+
end
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
defmodule BookStoreWeb.BookController do
2+
use BookStoreWeb, :controller
3+
4+
alias BookStore.Books
5+
alias BookStore.Books.Book
6+
7+
def index(conn, _params) do
8+
# books = Books.actor_all()
9+
books = Books.all()
10+
11+
conn
12+
|> json(books)
13+
end
14+
15+
def show(conn, %{"id" => book_id}) do
16+
# book = Books.actor_read(book_id)
17+
book = Books.read(book_id)
18+
19+
case book do
20+
%Book{} = book ->
21+
conn
22+
|> json(book)
23+
24+
_ ->
25+
conn
26+
|> put_status(404)
27+
|> json(%{error: "Not found"})
28+
end
29+
end
30+
31+
def order(conn, %{"book_id" => book_id}) do
32+
# status = Books.actor_order(book_id)
33+
status = Books.order(book_id)
34+
35+
case status do
36+
:ok ->
37+
conn
38+
|> put_status(201)
39+
|> json(%{status: "Order placed"})
40+
41+
:no_copies_available ->
42+
json(conn, %{status: "Not enough copies on hand to complete order"})
43+
44+
{:error, :not_found} ->
45+
conn
46+
|> put_status(404)
47+
|> json(%{error: "Not found"})
48+
end
49+
end
50+
end

lib/book_store_web/router.ex

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ defmodule BookStoreWeb.Router do
77

88
scope "/api", BookStoreWeb do
99
pipe_through :api
10+
11+
resources "/books", BookController, only: [:index, :show] do
12+
post "/order", BookController, :order
13+
end
1014
end
1115

1216
# Enables LiveDashboard only for development

0 commit comments

Comments
 (0)