Skip to content

Commit

Permalink
Add Pagination (#50)
Browse files Browse the repository at this point in the history
Here is the things I've done for pagination:

I edited the database query to support pagination
Then I saw home handler use GetPosts so i modified that handler in
app.go
and at the end I Changed SetupRoutes in app.go
  • Loading branch information
ali-assar authored Mar 16, 2024
1 parent 79e6602 commit 9efb940
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 11 deletions.
20 changes: 18 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package app
import (
"bytes"
"net/http"
"strconv"
"time"

"github.com/gin-gonic/gin"
Expand All @@ -26,6 +27,9 @@ func SetupRoutes(app_settings common.AppSettings, database database.Database) *g
addCachableHandler(r, "GET", "/contact", contactHandler, &cache, app_settings, database)
addCachableHandler(r, "GET", "/post/:id", postHandler, &cache, app_settings, database)

// Add the pagination route as a cacheable endpoint
addCachableHandler(r, "GET", "/page/:num", homeHandler, &cache, app_settings, database)

// DO not cache as it needs to handlenew form values
r.POST("/contact-send", makeContactFormHandler())

Expand Down Expand Up @@ -81,7 +85,19 @@ func addCachableHandler(e *gin.Engine, method string, endpoint string, generator
// / This function will act as the handler for
// / the home page
func homeHandler(c *gin.Context, settings common.AppSettings, db database.Database) ([]byte, error) {
posts, err := db.GetPosts()
pageNum := 0 // Default to page 0
if pageNumQuery := c.Param("num"); pageNumQuery != "" {
num, err := strconv.Atoi(pageNumQuery)
if err == nil && num > 0 {
pageNum = num
} else {
log.Error().Msgf("Invalid page number: %s", pageNumQuery)
}
}
limit := 10 // or whatever limit you want
offset := max((pageNum-1)*limit, 0)

posts, err := db.GetPosts(limit, offset)
if err != nil {
return nil, err
}
Expand All @@ -92,7 +108,7 @@ func homeHandler(c *gin.Context, settings common.AppSettings, db database.Databa

err = index_view.Render(c, html_buffer)
if err != nil {
log.Error().Msgf("could not render index: %v", err)
log.Error().Msgf("Could not render index: %v", err)
return []byte{}, err
}

Expand Down
7 changes: 4 additions & 3 deletions database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

type Database interface {
GetPosts() ([]common.Post, error)
GetPosts(int, int) ([]common.Post, error)
GetPost(post_id int) (common.Post, error)
AddPost(title string, excerpt string, content string) (int, error)
ChangePost(id int, title string, excerpt string, content string) error
Expand All @@ -28,8 +28,9 @@ type SqlDatabase struct {

// / This function gets all the posts from the current
// / database connection.
func (db SqlDatabase) GetPosts() (all_posts []common.Post, err error) {
rows, err := db.Connection.Query("SELECT title, excerpt, id FROM posts;")
func (db SqlDatabase) GetPosts(limit int, offset int) (all_posts []common.Post, err error) {
query := "SELECT title, excerpt, id FROM posts LIMIT ? OFFSET ?;"
rows, err := db.Connection.Query(query, limit, offset)
if err != nil {
return make([]common.Post, 0), err
}
Expand Down
6 changes: 3 additions & 3 deletions tests/app_tests/endpoint_tests/index_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ func TestIndexSuccess(t *testing.T) {
}

database_mock := mocks.DatabaseMock{
GetPostsHandler: func() ([]common.Post, error) {
GetPostsHandler: func(limit int, offset int) ([]common.Post, error) {
return []common.Post{
{
Title: "TestPost",
Expand All @@ -38,7 +38,7 @@ func TestIndexSuccess(t *testing.T) {

r := app.SetupRoutes(app_settings, database_mock)
w := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/", nil)
req, _ := http.NewRequest("GET", "/page/0", nil)
r.ServeHTTP(w, req)

assert.Equal(t, http.StatusOK, w.Code)
Expand All @@ -57,7 +57,7 @@ func TestIndexFailToGetPosts(t *testing.T) {
}

database_mock := mocks.DatabaseMock{
GetPostsHandler: func() ([]common.Post, error) {
GetPostsHandler: func(limit int, offset int) ([]common.Post, error) {
return []common.Post{}, fmt.Errorf("invalid")
},
}
Expand Down
6 changes: 3 additions & 3 deletions tests/mocks/mocks.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ import (

type DatabaseMock struct {
GetPostHandler func(int) (common.Post, error)
GetPostsHandler func() ([]common.Post, error)
GetPostsHandler func(int, int) ([]common.Post, error)
}

func (db DatabaseMock) GetPosts() ([]common.Post, error) {
return db.GetPostsHandler()
func (db DatabaseMock) GetPosts(limit int, offset int) ([]common.Post, error) {
return db.GetPostsHandler(limit, offset)
}

func (db DatabaseMock) GetPost(post_id int) (common.Post, error) {
Expand Down

0 comments on commit 9efb940

Please sign in to comment.