api: implemented list subreddit api

This commit is contained in:
Tigor Hutasuhut 2024-04-08 23:18:09 +07:00
parent c1841eb88a
commit 31adf0755e
9 changed files with 106 additions and 18 deletions

View file

@ -7,7 +7,7 @@ args_bin = ["serve"]
bin = "./tmp/main" bin = "./tmp/main"
cmd = "go build -o ./tmp/main ." cmd = "go build -o ./tmp/main ."
delay = 1000 delay = 1000
exclude_dir = ["assets", "tmp", "vendor", "testdata"] exclude_dir = ["assets", "tmp", "vendor", "testdata", "node_modules"]
exclude_file = [] exclude_file = []
exclude_regex = ["_test.go", "db/queries/.*\\.go", "_templ.go"] exclude_regex = ["_test.go", "db/queries/.*\\.go", "_templ.go"]
exclude_unchanged = false exclude_unchanged = false

12
api/api.go Normal file
View file

@ -0,0 +1,12 @@
package api
import (
"database/sql"
"github.com/tigorlazuardi/redmage/db/queries"
)
type API struct {
Queries *queries.Queries
DB *sql.DB
}

View file

@ -1 +0,0 @@
package subreddits

View file

@ -1,9 +0,0 @@
package subreddits
import (
subredditsDB "github.com/tigorlazuardi/redmage/db/queries/subreddits"
)
type API struct {
SubredditDB *subredditsDB.Queries
}

54
api/subreddits_list.go Normal file
View file

@ -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
}

View file

@ -1,9 +1,24 @@
-- name: ListSubreddits :many -- name: SubredditsList :many
SELECT * FROM subreddits SELECT * FROM subreddits
ORDER BY name 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) INSERT INTO subreddits (name, subtype, schedule)
VALUES (?, ?, ?) VALUES (?, ?, ?)
RETURNING *; RETURNING *;

View file

@ -4,13 +4,15 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"net/http" "net/http"
"strconv"
"github.com/tigorlazuardi/redmage/db/queries/subreddits"
"github.com/tigorlazuardi/redmage/pkg/log" "github.com/tigorlazuardi/redmage/pkg/log"
) )
func (api *API) ListSubreddits(rw http.ResponseWriter, r *http.Request) { func (api *API) ListSubreddits(rw http.ResponseWriter, r *http.Request) {
rw.Header().Add("Content-Type", "application/json") 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 { if err != nil {
rw.WriteHeader(http.StatusInternalServerError) rw.WriteHeader(http.StatusInternalServerError)
msg := fmt.Sprintf("failed to list subreddits: %s", err) 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") 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
}

View file

@ -36,6 +36,7 @@ func (www *WWW) Register(router chi.Router) {
router.Group(func(r chi.Router) { router.Group(func(r chi.Router) {
r.Use(chimiddleware.RequestLogger(middleware.ChiLogger{})) r.Use(chimiddleware.RequestLogger(middleware.ChiLogger{}))
r.Use(chimiddleware.SetHeader("Content-Type", "text/html; utf-8"))
r.Get("/", www.Home) r.Get("/", www.Home)
}) })
} }

View file

@ -2,12 +2,12 @@ version: "2"
sql: sql:
- engine: sqlite - engine: sqlite
queries: "db/queries/subreddits.sql" queries: "db/queries"
schema: "db/migrations" schema: "db/migrations"
gen: gen:
go: go:
package: subreddits package: queries
out: "db/queries/subreddits" out: "db/queries"
emit_empty_slices: true emit_empty_slices: true
emit_sql_as_comment: true emit_sql_as_comment: true
emit_json_tags: true emit_json_tags: true