Task
Create gleam-bookshelf/src/db.gleam with all 5 CRUD database functions.
Functions to implement
insert_book(conn, title, author, status) -> Result(Book, AppError)
get_all_books(conn) -> Result(List(Book), AppError)
get_book_by_id(conn, id) -> Result(Book, AppError)
update_book(conn, id, title, author, status) -> Result(Book, AppError)
delete_book(conn, id) -> Result(Nil, AppError)
Key differences from Go/TS
- No global mutable state —
conn (pgo.Connection) is passed as an argument, not stored in a module-level variable
- Row decoder — must build a
dynamic.decode4(...) decoder to map SQL columns to Book fields
use keyword — replaces Go's if err != nil pattern for chaining fallible operations
- SQL is identical — same
$1, $2 parameterized queries, same RETURNING clauses
Acceptance criteria
Task
Create
gleam-bookshelf/src/db.gleamwith all 5 CRUD database functions.Functions to implement
insert_book(conn, title, author, status) -> Result(Book, AppError)get_all_books(conn) -> Result(List(Book), AppError)get_book_by_id(conn, id) -> Result(Book, AppError)update_book(conn, id, title, author, status) -> Result(Book, AppError)delete_book(conn, id) -> Result(Nil, AppError)Key differences from Go/TS
conn(pgo.Connection) is passed as an argument, not stored in a module-level variabledynamic.decode4(...)decoder to map SQL columns to Book fieldsusekeyword — replaces Go'sif err != nilpattern for chaining fallible operations$1, $2parameterized queries, sameRETURNINGclausesAcceptance criteria
Resultreturn types(id, title, author, status)columnsdelete_bookreturnsError(NotFound)when 0 rows affectedgleam buildpasses