From 31adf0755edf5445ee979f8416c5e0e23aa5a1df Mon Sep 17 00:00:00 2001 From: Tigor Hutasuhut Date: Mon, 8 Apr 2024 23:18:09 +0700 Subject: [PATCH] api: implemented list subreddit api --- .air.toml | 2 +- api/api.go | 12 +++++++ api/subreddits/list_subreddits.go | 1 - api/subreddits/subreddits.go | 9 ----- api/subreddits_list.go | 54 ++++++++++++++++++++++++++++ db/queries/subreddits.sql | 21 +++++++++-- server/routes/api/subreddits_list.go | 18 +++++++++- server/routes/www/www.go | 1 + sqlc.yaml | 6 ++-- 9 files changed, 106 insertions(+), 18 deletions(-) create mode 100644 api/api.go delete mode 100644 api/subreddits/list_subreddits.go delete mode 100644 api/subreddits/subreddits.go create mode 100644 api/subreddits_list.go diff --git a/.air.toml b/.air.toml index ca4ce5d..5ec7789 100644 --- a/.air.toml +++ b/.air.toml @@ -7,7 +7,7 @@ args_bin = ["serve"] bin = "./tmp/main" cmd = "go build -o ./tmp/main ." delay = 1000 -exclude_dir = ["assets", "tmp", "vendor", "testdata"] +exclude_dir = ["assets", "tmp", "vendor", "testdata", "node_modules"] exclude_file = [] exclude_regex = ["_test.go", "db/queries/.*\\.go", "_templ.go"] exclude_unchanged = false diff --git a/api/api.go b/api/api.go new file mode 100644 index 0000000..a845bef --- /dev/null +++ b/api/api.go @@ -0,0 +1,12 @@ +package api + +import ( + "database/sql" + + "github.com/tigorlazuardi/redmage/db/queries" +) + +type API struct { + Queries *queries.Queries + DB *sql.DB +} diff --git a/api/subreddits/list_subreddits.go b/api/subreddits/list_subreddits.go deleted file mode 100644 index 4b26cea..0000000 --- a/api/subreddits/list_subreddits.go +++ /dev/null @@ -1 +0,0 @@ -package subreddits diff --git a/api/subreddits/subreddits.go b/api/subreddits/subreddits.go deleted file mode 100644 index 97d8ded..0000000 --- a/api/subreddits/subreddits.go +++ /dev/null @@ -1,9 +0,0 @@ -package subreddits - -import ( - subredditsDB "github.com/tigorlazuardi/redmage/db/queries/subreddits" -) - -type API struct { - SubredditDB *subredditsDB.Queries -} diff --git a/api/subreddits_list.go b/api/subreddits_list.go new file mode 100644 index 0000000..73dd453 --- /dev/null +++ b/api/subreddits_list.go @@ -0,0 +1,54 @@ +package api + +import ( + "context" + + "github.com/tigorlazuardi/redmage/db/queries" + "github.com/tigorlazuardi/redmage/pkg/errs" +) + +type ListSubredditsParams struct { + Name string `json:"name"` + Limit int64 `json:"limit"` + Offset int64 `json:"offset"` +} + +type ListSubredditsResult struct { + Total int64 + Data []queries.Subreddit +} + +func (api *API) ListSubreddits(ctx context.Context, arg ListSubredditsParams) (result ListSubredditsResult, err error) { + if arg.Name != "" { + result.Data, err = api.Queries.SubredditsSearch(ctx, queries.SubredditsSearchParams{ + Name: "%" + arg.Name + "%", + Limit: arg.Limit, + Offset: arg.Offset, + }) + if err != nil { + return result, errs.Wrapw(err, "failed to search subreddit", "query", arg) + } + result.Total, err = api.Queries.SubredditsSearchCount(ctx, queries.SubredditsSearchCountParams{ + Name: "%" + arg.Name + "%", + Limit: arg.Limit, + Offset: arg.Offset, + }) + if err != nil { + return result, errs.Wrapw(err, "failed to count subreddit search", "query", arg) + } + return result, err + } + + result.Data, err = api.Queries.SubredditsList(ctx, queries.SubredditsListParams{ + Limit: arg.Limit, + Offset: arg.Offset, + }) + if err != nil { + return result, errs.Wrapw(err, "failed to list subreddit", "query", arg) + } + result.Total, err = api.Queries.SubredditsListCount(ctx) + if err != nil { + return result, errs.Wrapw(err, "failed to count subreddit list", "query", arg) + } + return result, err +} diff --git a/db/queries/subreddits.sql b/db/queries/subreddits.sql index d00d79a..6151b78 100644 --- a/db/queries/subreddits.sql +++ b/db/queries/subreddits.sql @@ -1,9 +1,24 @@ --- name: ListSubreddits :many +-- name: SubredditsList :many SELECT * FROM subreddits ORDER BY name -LIMIT ?; +LIMIT ? OFFSET ?; --- name: CreateSubreddit :one +-- name: SubredditsListCount :one +SELECT COUNT(*) From subreddits; + +-- name: SubredditsSearch :many +SELECT * FROM subreddits +WHERE name LIKE ? +ORDER BY name +LIMIT ? OFFSET ?; + +-- name: SubredditsSearchCount :one +SELECT COUNT(*) FROM subreddits +WHERE name LIKE ? +ORDER BY name +LIMIT ? OFFSET ?; + +-- name: SubredditCreate :one INSERT INTO subreddits (name, subtype, schedule) VALUES (?, ?, ?) RETURNING *; diff --git a/server/routes/api/subreddits_list.go b/server/routes/api/subreddits_list.go index 2cac82e..f84a960 100644 --- a/server/routes/api/subreddits_list.go +++ b/server/routes/api/subreddits_list.go @@ -4,13 +4,15 @@ import ( "encoding/json" "fmt" "net/http" + "strconv" + "github.com/tigorlazuardi/redmage/db/queries/subreddits" "github.com/tigorlazuardi/redmage/pkg/log" ) func (api *API) ListSubreddits(rw http.ResponseWriter, r *http.Request) { rw.Header().Add("Content-Type", "application/json") - subs, err := api.Subreddits.ListSubreddits(r.Context(), 10) + subs, err := api.Subreddits.ListSubreddits(r.Context(), parseListSubredditsQuery(r)) if err != nil { rw.WriteHeader(http.StatusInternalServerError) msg := fmt.Sprintf("failed to list subreddits: %s", err) @@ -22,3 +24,17 @@ func (api *API) ListSubreddits(rw http.ResponseWriter, r *http.Request) { log.New(r.Context()).Err(err).Error("failed to list subreddits") } } + +func parseListSubredditsQuery(r *http.Request) subreddits.ListSubredditsParams { + params := subreddits.ListSubredditsParams{} + params.Limit, _ = strconv.ParseInt(r.URL.Query().Get("limit"), 10, 64) + params.Offset, _ = strconv.ParseInt(r.URL.Query().Get("offset"), 10, 64) + + if params.Limit < 1 { + params.Limit = 10 + } else if params.Limit > 100 { + params.Limit = 100 + } + + return params +} diff --git a/server/routes/www/www.go b/server/routes/www/www.go index d318863..305936f 100644 --- a/server/routes/www/www.go +++ b/server/routes/www/www.go @@ -36,6 +36,7 @@ func (www *WWW) Register(router chi.Router) { router.Group(func(r chi.Router) { r.Use(chimiddleware.RequestLogger(middleware.ChiLogger{})) + r.Use(chimiddleware.SetHeader("Content-Type", "text/html; utf-8")) r.Get("/", www.Home) }) } diff --git a/sqlc.yaml b/sqlc.yaml index 3bff068..258e13d 100644 --- a/sqlc.yaml +++ b/sqlc.yaml @@ -2,12 +2,12 @@ version: "2" sql: - engine: sqlite - queries: "db/queries/subreddits.sql" + queries: "db/queries" schema: "db/migrations" gen: go: - package: subreddits - out: "db/queries/subreddits" + package: queries + out: "db/queries" emit_empty_slices: true emit_sql_as_comment: true emit_json_tags: true