diff --git a/api/post.go b/api/post.go index 46e1c51..ce2c3b1 100644 --- a/api/post.go +++ b/api/post.go @@ -1,23 +1,24 @@ package api import ( + "fmt" "net/http" "strconv" "github.com/gin-gonic/gin" db "github.com/mustafayilmazdev/musarchive/db/sqlc" localization "github.com/mustafayilmazdev/musarchive/locales" + "github.com/mustafayilmazdev/musarchive/token" "github.com/mustafayilmazdev/musarchive/util" - "github.com/rs/zerolog/log" ) -func (server *Server) GetBlogs(ctx *gin.Context) { +func (server *Server) GetPosts(ctx *gin.Context) { localeValue := ctx.Query(util.Locale) pageStr := ctx.Query(util.Page) sizeStr := ctx.Query(util.Size) page := util.PageCount size := util.SizeCount - log.Info().Msg(pageStr + " " + sizeStr) + if pageStr != "" { var err error page, err = strconv.Atoi(pageStr) @@ -72,3 +73,67 @@ func (server *Server) GetBlogs(ctx *gin.Context) { Data: blogs, }) } + +func (server *Server) GetFollowedPosts(ctx *gin.Context) { + localeValue := ctx.Query(util.Locale) + pageStr := ctx.Query(util.Page) + sizeStr := ctx.Query(util.Size) + page := util.PageCount + size := util.SizeCount + + if pageStr != "" { + var err error + page, err = strconv.Atoi(pageStr) + if err != nil { + BuildResponse(ctx, BaseResponse{ + Code: http.StatusBadRequest, + Message: ResponseMessage{ + Type: ERROR, + Content: server.lm.Translate(localeValue, localization.Pagination_pageError, pageStr), + }, + }) + return + } + + } + + if sizeStr != "" { + var err error + size, err = strconv.Atoi(sizeStr) + if err != nil { + BuildResponse(ctx, BaseResponse{ + Code: http.StatusBadRequest, + Message: ResponseMessage{ + Type: ERROR, + Content: server.lm.Translate(localeValue, localization.Pagination_sizeError, sizeStr), + }, + }) + return + } + + } + authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) + fmt.Println(authPayload.UserID) + arg := db.GetFollowedPostsParams{ + FollowerID: int32(authPayload.UserID), + Limit: int32(size), + Offset: int32((page - 1) * size), + } + + blogs, err := server.store.GetFollowedPosts(ctx, arg) + if err != nil { + BuildResponse(ctx, BaseResponse{ + Code: http.StatusInternalServerError, + Message: ResponseMessage{ + Type: ERROR, + Content: server.lm.Translate(localeValue, localization.Errors_InternalError, err.Error()), + }, + }) + return + } + + BuildResponse(ctx, BaseResponse{ + Code: http.StatusOK, + Data: blogs, + }) +} diff --git a/api/server.go b/api/server.go index f799b83..9129967 100644 --- a/api/server.go +++ b/api/server.go @@ -49,7 +49,8 @@ func (server *Server) setupRouter() { } authRoutes := router.Group("/v1").Use(authMiddleware(server.tokenMaker)) { - authRoutes.GET("/blogs", server.GetBlogs) + authRoutes.GET("/posts", server.GetPosts) + authRoutes.GET("/followed_posts", server.GetFollowedPosts) } // Serve the bundled static files diff --git a/db/mock/store.go b/db/mock/store.go index 298560a..8885717 100644 --- a/db/mock/store.go +++ b/db/mock/store.go @@ -264,6 +264,21 @@ func (mr *MockStoreMockRecorder) GetFeaturedStory(arg0, arg1 interface{}) *gomoc return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFeaturedStory", reflect.TypeOf((*MockStore)(nil).GetFeaturedStory), arg0, arg1) } +// GetFollowedPosts mocks base method. +func (m *MockStore) GetFollowedPosts(arg0 context.Context, arg1 db.GetFollowedPostsParams) ([]db.Post, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetFollowedPosts", arg0, arg1) + ret0, _ := ret[0].([]db.Post) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// GetFollowedPosts indicates an expected call of GetFollowedPosts. +func (mr *MockStoreMockRecorder) GetFollowedPosts(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetFollowedPosts", reflect.TypeOf((*MockStore)(nil).GetFollowedPosts), arg0, arg1) +} + // GetFollowersOfUser mocks base method. func (m *MockStore) GetFollowersOfUser(arg0 context.Context, arg1 int32) ([]db.GetFollowersOfUserRow, error) { m.ctrl.T.Helper() diff --git a/db/query/posts.sql b/db/query/posts.sql index 214e9b6..9d250bb 100644 --- a/db/query/posts.sql +++ b/db/query/posts.sql @@ -24,6 +24,13 @@ UPDATE posts WHERE id = sqlc.arg(id) RETURNING *; +-- name: GetFollowedPosts :many +SELECT p.id, p.user_id, p.title, p.summary, p.content, p.cover_image, p.created_at, p.updated_at, p.likes +FROM posts p +JOIN user_followers f ON p.user_id = f.user_id +WHERE f.follower_id = $1 +ORDER BY p.id LIMIT $2 OFFSET $3; + -- name: DeletePost :exec DELETE FROM posts WHERE id = $1; \ No newline at end of file diff --git a/db/sqlc/posts.sql.go b/db/sqlc/posts.sql.go index d7a72ef..a62ac47 100644 --- a/db/sqlc/posts.sql.go +++ b/db/sqlc/posts.sql.go @@ -21,6 +21,50 @@ func (q *Queries) DeletePost(ctx context.Context, id int32) error { return err } +const getFollowedPosts = `-- name: GetFollowedPosts :many +SELECT p.id, p.user_id, p.title, p.summary, p.content, p.cover_image, p.created_at, p.updated_at, p.likes +FROM posts p +JOIN user_followers f ON p.user_id = f.user_id +WHERE f.follower_id = $1 +ORDER BY p.id LIMIT $2 OFFSET $3 +` + +type GetFollowedPostsParams struct { + FollowerID int32 `json:"follower_id"` + Limit int32 `json:"limit"` + Offset int32 `json:"offset"` +} + +func (q *Queries) GetFollowedPosts(ctx context.Context, arg GetFollowedPostsParams) ([]Post, error) { + rows, err := q.db.Query(ctx, getFollowedPosts, arg.FollowerID, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + items := []Post{} + for rows.Next() { + var i Post + if err := rows.Scan( + &i.ID, + &i.UserID, + &i.Title, + &i.Summary, + &i.Content, + &i.CoverImage, + &i.CreatedAt, + &i.UpdatedAt, + &i.Likes, + ); err != nil { + return nil, err + } + items = append(items, i) + } + if err := rows.Err(); err != nil { + return nil, err + } + return items, nil +} + const getPost = `-- name: GetPost :one SELECT id, user_id, title, summary, content, cover_image, created_at, updated_at, likes FROM posts diff --git a/db/sqlc/querier.go b/db/sqlc/querier.go index 44e3824..e610b06 100644 --- a/db/sqlc/querier.go +++ b/db/sqlc/querier.go @@ -27,6 +27,7 @@ type Querier interface { GetCategory(ctx context.Context, id int32) (Category, error) GetCommentsForPost(ctx context.Context, postID int32) ([]Comment, error) GetFeaturedStory(ctx context.Context, id int32) (FeaturedStory, error) + GetFollowedPosts(ctx context.Context, arg GetFollowedPostsParams) ([]Post, error) GetFollowersOfUser(ctx context.Context, userID int32) ([]GetFollowersOfUserRow, error) GetFollowingUsers(ctx context.Context, followerID int32) ([]GetFollowingUsersRow, error) GetOnboarding(ctx context.Context, id int32) (Onboarding, error)