perf(web): add pagination
and remove getting total quotes count
This commit is contained in:
parent
65152526b7
commit
8b417dc623
@ -162,17 +162,6 @@ func quotesGet(c *gin.Context) {
|
||||
c.JSON(http.StatusOK, quotes)
|
||||
}
|
||||
|
||||
func quotesCount(c *gin.Context) {
|
||||
user_id := c.GetString("user_id")
|
||||
count, err := db.QuotesCount(context.Background(), user_id)
|
||||
if err != nil {
|
||||
status, message := handleDBError(err)
|
||||
c.JSON(status, gin.H{"error": message})
|
||||
return
|
||||
}
|
||||
c.JSON(http.StatusOK, gin.H{"count": count})
|
||||
}
|
||||
|
||||
func quoteGet(c *gin.Context) {
|
||||
user_id := c.GetString("user_id")
|
||||
quote_id := c.Param("id")
|
||||
|
||||
@ -26,7 +26,6 @@ func RegisterRoutes(r *gin.Engine) {
|
||||
api.DELETE("/auth", userLogout)
|
||||
|
||||
api.GET("/quotes", MiddlewareAuth, quotesGet)
|
||||
api.GET("/quotes/count", MiddlewareAuth, quotesCount)
|
||||
api.POST("/quotes", MiddlewareAuth, quoteAdd)
|
||||
api.GET("/quotes/:id", MiddlewareAuth, quoteGet)
|
||||
api.PATCH("/quotes/:id", MiddlewareAuth, quoteUpdate)
|
||||
|
||||
41
web/db/db.go
41
web/db/db.go
@ -72,13 +72,13 @@ func UserUpdatePassword(ctx context.Context, user_id string, new_password string
|
||||
|
||||
//#region Quotes
|
||||
|
||||
func QuotesGet(ctx context.Context, user_id string, filter string, sort string, limit int, offset int) (quotes []models.Quote, err error) {
|
||||
query := "SELECT * FROM quotes_get($1) WHERE position($2 in lower(text))>0 OR position($2 in lower(author))>0"
|
||||
func QuotesGet(ctx context.Context, user_id string, filter string, sort string, limit int, offset int) (quotes models.Quotes, err error) {
|
||||
queryGet := "SELECT * FROM quotes_get($1) WHERE position($2 in lower(text))>0 OR position($2 in lower(author))>0"
|
||||
if sort == "random" {
|
||||
query += " ORDER BY random()"
|
||||
queryGet += " ORDER BY random()"
|
||||
} else if sort != "" {
|
||||
sort_options := strings.Split(sort, ",")
|
||||
query += " ORDER BY "
|
||||
queryGet += " ORDER BY "
|
||||
for i, sort_option := range sort_options {
|
||||
sort_order := sort_option[:1]
|
||||
sort_field := sort_option[1:]
|
||||
@ -105,23 +105,26 @@ func QuotesGet(ctx context.Context, user_id string, filter string, sort string,
|
||||
return
|
||||
}
|
||||
if i > 0 {
|
||||
query += ", "
|
||||
queryGet += ", "
|
||||
}
|
||||
query += fmt.Sprintf("%s %s", sort_field, sort_order)
|
||||
queryGet += fmt.Sprintf("%s %s", sort_field, sort_order)
|
||||
}
|
||||
}
|
||||
queryCount := queryGet
|
||||
if limit >= 0 {
|
||||
query += fmt.Sprintf(" LIMIT %d", limit)
|
||||
queryGet += fmt.Sprintf(" LIMIT %d", limit)
|
||||
}
|
||||
if offset > 0 {
|
||||
query += fmt.Sprintf(" OFFSET %d", offset)
|
||||
queryGet += fmt.Sprintf(" OFFSET %d", offset)
|
||||
}
|
||||
rows, err := ConnPool.Query(ctx, query, user_id, strings.ToLower(filter))
|
||||
filter = strings.ToLower(filter)
|
||||
rows, err := ConnPool.Query(ctx, queryGet, user_id, filter)
|
||||
if err != nil {
|
||||
err = fmt.Errorf("error while getting quotes: %w", err)
|
||||
return
|
||||
}
|
||||
quotes = []models.Quote{}
|
||||
quotes.Quotes = []models.Quote{}
|
||||
count := 0
|
||||
for rows.Next() {
|
||||
var quote models.Quote
|
||||
err = rows.Scan("e.ID, "e.Text, "e.Author, "e.Datetime, "e.Creator.ID, "e.Creator.Name, "e.Creator.Login, "e.Creator.Role, "e.Creator.TelegramID)
|
||||
@ -129,15 +132,19 @@ func QuotesGet(ctx context.Context, user_id string, filter string, sort string,
|
||||
err = fmt.Errorf("error while fetching quotes: %w", err)
|
||||
return
|
||||
}
|
||||
quotes = append(quotes, quote)
|
||||
quotes.Quotes = append(quotes.Quotes, quote)
|
||||
count++
|
||||
}
|
||||
err = rows.Err()
|
||||
return
|
||||
}
|
||||
|
||||
func QuotesCount(ctx context.Context, user_id string) (count int, err error) {
|
||||
row := ConnPool.QueryRow(ctx, "SELECT count(*) FROM quotes_get($1)", user_id)
|
||||
err = row.Scan(&count)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
quotes.Pagination.Limit = limit
|
||||
quotes.Pagination.Offset = offset
|
||||
quotes.Pagination.Count = count
|
||||
queryCount = fmt.Sprintf("SELECT count(*) FROM (%s) q", queryCount)
|
||||
row := ConnPool.QueryRow(ctx, queryCount, user_id, filter)
|
||||
err = row.Scan("es.Pagination.TotalCount)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
@ -27,3 +27,15 @@ type Quote struct {
|
||||
Datetime time.Time `json:"datetime"`
|
||||
Creator User `json:"creator"`
|
||||
}
|
||||
|
||||
type Pagination struct {
|
||||
TotalCount int `json:"totalCount"`
|
||||
Offset int `json:"offset"`
|
||||
Limit int `json:"limit"`
|
||||
Count int `json:"count"`
|
||||
}
|
||||
|
||||
type Quotes struct {
|
||||
Pagination Pagination `json:"pagination"`
|
||||
Quotes []Quote `json:"quotes"`
|
||||
}
|
||||
|
||||
@ -45,28 +45,33 @@ function renderBlockQuote(quote) {
|
||||
|
||||
function load() {
|
||||
var quotesCount;
|
||||
failed = false;
|
||||
$("#input-search").val(search);
|
||||
$("#input-sorting").val(sorting);
|
||||
container = $("#block-quotes");
|
||||
$.ajax({
|
||||
async: false,
|
||||
url: "/api/quotes/count",
|
||||
url: `/api/quotes?filter=${encodeURIComponent(search)}&sort=${encodeURIComponent(sorting)}&limit=${PAGE_SIZE}&offset=${(currPage - 1)*PAGE_SIZE}`,
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: function (resp) {
|
||||
quotesCount = resp.count;
|
||||
quotesCount = resp.pagination.totalCount
|
||||
if (resp.pagination.count == 0) {
|
||||
container.html("<p style='text-align: center;'><i>Чёт нету ничего...</i></p>");
|
||||
return;
|
||||
}
|
||||
resp.quotes.forEach((quote) => {
|
||||
container.append(renderBlockQuote(quote));
|
||||
});
|
||||
},
|
||||
error: function (err) {
|
||||
$("#error-message").text(err.responseJSON.error);
|
||||
$("#error").removeClass("hidden");
|
||||
failed = true;
|
||||
},
|
||||
complete: function () {
|
||||
$("#block-quotes-loader").addClass("hidden");
|
||||
},
|
||||
});
|
||||
if (failed) {
|
||||
return;
|
||||
}
|
||||
totalPages = Math.ceil(quotesCount / PAGE_SIZE);
|
||||
$("#input-search").val(search);
|
||||
$("#input-sorting").val(sorting);
|
||||
$("#btn-page-curr").text(currPage);
|
||||
if (currPage > 1) {
|
||||
$("#btn-page-first").removeClass("hidden");
|
||||
@ -89,28 +94,6 @@ function load() {
|
||||
}
|
||||
}
|
||||
}
|
||||
container = $("#block-quotes");
|
||||
$.ajax({
|
||||
url: `/api/quotes?filter=${encodeURIComponent(search)}&sort=${encodeURIComponent(sorting)}&limit=${PAGE_SIZE}&offset=${(currPage - 1)*PAGE_SIZE}`,
|
||||
type: "GET",
|
||||
dataType: "json",
|
||||
success: function (resp) {
|
||||
if (resp.length == 0) {
|
||||
container.html("<p style='text-align: center;'><i>Чёт нету ничего...</i></p>");
|
||||
return;
|
||||
}
|
||||
resp.forEach((quote) => {
|
||||
container.append(renderBlockQuote(quote));
|
||||
});
|
||||
},
|
||||
error: function (err) {
|
||||
$("#error-message").text(err.responseJSON.error);
|
||||
$("#error").removeClass("hidden");
|
||||
},
|
||||
complete: function () {
|
||||
$("#block-quotes-loader").addClass("hidden");
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
function reload() {
|
||||
@ -122,6 +105,7 @@ function reload() {
|
||||
$("#btn-page-first").addClass("hidden");
|
||||
$("#pages-prev").addClass("hidden");
|
||||
$("#btn-page-prev").addClass("hidden");
|
||||
$("#btn-page-curr").text(1);
|
||||
$("#btn-page-next").addClass("hidden");
|
||||
$("#pages-next").addClass("hidden");
|
||||
$("#btn-page-last").addClass("hidden");
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user