initial commit
This commit is contained in:
44
.gitlab-ci.yml
Normal file
44
.gitlab-ci.yml
Normal file
@@ -0,0 +1,44 @@
|
||||
image: docker:20.10.16
|
||||
|
||||
variables:
|
||||
# When using dind service, you must instruct Docker to talk with
|
||||
# the daemon started inside of the service. The daemon is available
|
||||
# with a network connection instead of the default
|
||||
# /var/run/docker.sock socket.
|
||||
DOCKER_HOST: tcp://docker:2376
|
||||
#
|
||||
# The 'docker' hostname is the alias of the service container as described at
|
||||
# https://docs.gitlab.com/ee/ci/services/#accessing-the-services.
|
||||
# If you're using GitLab Runner 12.7 or earlier with the Kubernetes executor and Kubernetes 1.6 or earlier,
|
||||
# the variable must be set to tcp://localhost:2376 because of how the
|
||||
# Kubernetes executor connects services to the job container
|
||||
# DOCKER_HOST: tcp://localhost:2376
|
||||
#
|
||||
# Specify to Docker where to create the certificates. Docker
|
||||
# creates them automatically on boot, and creates
|
||||
# `/certs/client` to share between the service and job
|
||||
# container, thanks to volume mount from config.toml
|
||||
DOCKER_TLS_CERTDIR: "/certs"
|
||||
# These are usually specified by the entrypoint, however the
|
||||
# Kubernetes executor doesn't run entrypoints
|
||||
# https://gitlab.com/gitlab-org/gitlab-runner/-/issues/4125
|
||||
DOCKER_TLS_VERIFY: 1
|
||||
DOCKER_CERT_PATH: "$DOCKER_TLS_CERTDIR/client"
|
||||
|
||||
services:
|
||||
- docker:20.10.16-dind
|
||||
|
||||
stages:
|
||||
- build
|
||||
|
||||
build-job:
|
||||
stage: build
|
||||
tags:
|
||||
- docker
|
||||
only:
|
||||
- master
|
||||
script:
|
||||
- docker info
|
||||
- docker build -t docker-registry.dopcore.com/andrusyakka/astra-users .
|
||||
- echo "$DOCKER_PASSWORD" | docker login docker-registry.dopcore.com -u "$DOCKER_USER" --password-stdin
|
||||
- docker push docker-registry.dopcore.com/andrusyakka/astra-users
|
||||
24
Dockerfile
Normal file
24
Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
||||
FROM kandrusyak/go-build as build
|
||||
LABEL authors="andrusyakka@dopcore.com"
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ENV CGO_ENABLED 1
|
||||
|
||||
COPY go.mod ./
|
||||
|
||||
RUN go mod download
|
||||
|
||||
COPY . ./
|
||||
|
||||
RUN go build -o ./app
|
||||
|
||||
FROM alpine:edge
|
||||
|
||||
WORKDIR /
|
||||
|
||||
COPY --from=build /app /app
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
CMD ["/app/app"]
|
||||
23
go.mod
Normal file
23
go.mod
Normal file
@@ -0,0 +1,23 @@
|
||||
module astra-users
|
||||
|
||||
go 1.21rc1
|
||||
|
||||
require (
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
|
||||
github.com/jinzhu/inflection v1.0.0 // indirect
|
||||
github.com/jinzhu/now v1.1.5 // indirect
|
||||
github.com/labstack/echo/v4 v4.10.2 // indirect
|
||||
github.com/labstack/gommon v0.4.0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.17 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.17 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasttemplate v1.2.2 // indirect
|
||||
golang.org/x/crypto v0.6.0 // indirect
|
||||
golang.org/x/net v0.7.0 // indirect
|
||||
golang.org/x/sys v0.5.0 // indirect
|
||||
golang.org/x/text v0.7.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
gorm.io/driver/sqlite v1.5.2 // indirect
|
||||
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55 // indirect
|
||||
)
|
||||
52
go.sum
Normal file
52
go.sum
Normal file
@@ -0,0 +1,52 @@
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
|
||||
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
|
||||
github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ=
|
||||
github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8=
|
||||
github.com/labstack/echo/v4 v4.10.2 h1:n1jAhnq/elIFTHr1EYpiYtyKgx4RW9ccVgkqByZaN2M=
|
||||
github.com/labstack/echo/v4 v4.10.2/go.mod h1:OEyqf2//K1DFdE57vw2DRgWY0M7s65IVQO2FzvI4J5k=
|
||||
github.com/labstack/gommon v0.4.0 h1:y7cvthEAEbU0yHOf4axH8ZG2NH8knB9iNSoTO8dyIk8=
|
||||
github.com/labstack/gommon v0.4.0/go.mod h1:uW6kP17uPlLJsD3ijUYn3/M5bAxtlZhMI6m3MFxTMTM=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng=
|
||||
github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-sqlite3 v1.14.17 h1:mCRHCLDUBXgpKAqIKsaAaAsrAlbkeomtRFKXh2L6YIM=
|
||||
github.com/mattn/go-sqlite3 v1.14.17/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
|
||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
|
||||
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
github.com/valyala/fasttemplate v1.2.2 h1:lxLXG0uE3Qnshl9QyaK6XJxMXlQZELvChBOCmQD0Loo=
|
||||
github.com/valyala/fasttemplate v1.2.2/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
|
||||
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
|
||||
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211103235746-7861aae1554b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
|
||||
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gorm.io/driver/sqlite v1.5.2 h1:TpQ+/dqCY4uCigCFyrfnrJnrW9zjpelWVoEVNy5qJkc=
|
||||
gorm.io/driver/sqlite v1.5.2/go.mod h1:qxAuCol+2r6PannQDpOP1FP6ag3mKi4esLnB/jHed+4=
|
||||
gorm.io/gorm v1.25.1 h1:nsSALe5Pr+cM3V1qwwQ7rOkw+6UeLrX5O4v3llhHa64=
|
||||
gorm.io/gorm v1.25.1/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55 h1:sC1Xj4TYrLqg1n3AN10w871An7wJM0gzgcm8jkIkECQ=
|
||||
gorm.io/gorm v1.25.2-0.20230530020048-26663ab9bf55/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=
|
||||
29
handler/auth.go
Normal file
29
handler/auth.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"astra-users/model"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (h *Handler) Login(c echo.Context) (err error) {
|
||||
// Bind
|
||||
u := new(model.User)
|
||||
if err = c.Bind(u); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
u.Password = fmt.Sprintf("%x", sha256.Sum256([]byte(u.Password)))
|
||||
|
||||
var t = h.DB.Where("user_name = ? AND password = ?", u.UserName, u.Password).First(&u)
|
||||
|
||||
if t.RowsAffected == 0 {
|
||||
return c.NoContent(http.StatusNotFound)
|
||||
}
|
||||
|
||||
u.Password = ""
|
||||
|
||||
return c.JSON(http.StatusOK, u)
|
||||
}
|
||||
7
handler/handler.go
Normal file
7
handler/handler.go
Normal file
@@ -0,0 +1,7 @@
|
||||
package handler
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type Handler struct {
|
||||
DB *gorm.DB
|
||||
}
|
||||
14
handler/health.go
Normal file
14
handler/health.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (h *Handler) Health(c echo.Context) error {
|
||||
type Resp struct {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, Resp{Status: "OK"})
|
||||
}
|
||||
114
handler/users.go
Normal file
114
handler/users.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"astra-users/model"
|
||||
"astra-users/pkg/utils"
|
||||
"crypto/sha256"
|
||||
"fmt"
|
||||
"github.com/labstack/echo/v4"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (h *Handler) GetCurrentUser(c echo.Context) error {
|
||||
userId := c.Request().Header.Get("UserId")
|
||||
|
||||
if userId == "" {
|
||||
return c.NoContent(http.StatusBadRequest)
|
||||
}
|
||||
|
||||
u := new(model.User)
|
||||
|
||||
tx := h.DB.First(&u, userId)
|
||||
|
||||
if tx.RowsAffected == 0 {
|
||||
return c.NoContent(http.StatusNotFound)
|
||||
}
|
||||
|
||||
u.Password = ""
|
||||
|
||||
return c.JSON(http.StatusOK, &u)
|
||||
}
|
||||
|
||||
func (h *Handler) GetUsers(c echo.Context) error {
|
||||
var users []model.User
|
||||
|
||||
query := c.Request().URL.Query()
|
||||
limit, offset := utils.GetPaginationParams(query)
|
||||
sortCol, isDesc, filterCol, filterVal := utils.GetFilterParams(query)
|
||||
|
||||
tx := h.DB.Limit(limit).Offset(offset)
|
||||
|
||||
utils.ApplyIdFilter(c, tx)
|
||||
utils.ApplySort(tx, sortCol, isDesc)
|
||||
utils.ApplyFilters(tx, filterCol, filterVal)
|
||||
|
||||
tx = tx.Find(&users)
|
||||
|
||||
if tx.RowsAffected == 1 {
|
||||
return c.JSON(http.StatusOK, users[0])
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, users)
|
||||
}
|
||||
|
||||
func (h *Handler) UpdateUser(c echo.Context) (err error) {
|
||||
var user = new(model.User)
|
||||
var apiUser = new(model.APIUser)
|
||||
tx := h.DB
|
||||
|
||||
id := c.Param("id")
|
||||
tx = tx.Find(&user, id)
|
||||
|
||||
if tx.RowsAffected == 0 {
|
||||
return c.NoContent(http.StatusNotFound)
|
||||
}
|
||||
|
||||
if err = c.Bind(apiUser); err != nil {
|
||||
return c.NoContent(http.StatusBadRequest)
|
||||
}
|
||||
|
||||
user.FirstName = apiUser.FirstName
|
||||
user.LastName = apiUser.LastName
|
||||
|
||||
tx = h.DB.Save(&user)
|
||||
|
||||
if tx.RowsAffected == 0 {
|
||||
return c.NoContent(http.StatusBadGateway)
|
||||
}
|
||||
|
||||
user.Password = ""
|
||||
|
||||
return c.JSON(http.StatusOK, &user)
|
||||
}
|
||||
|
||||
func (h *Handler) DeleteUser(c echo.Context) (err error) {
|
||||
id := c.Param("id")
|
||||
|
||||
tx := h.DB.Delete(&model.User{}, id)
|
||||
|
||||
if tx.RowsAffected == 0 {
|
||||
return c.NoContent(http.StatusBadGateway)
|
||||
}
|
||||
|
||||
return c.NoContent(http.StatusOK)
|
||||
}
|
||||
|
||||
func (h *Handler) CreateUser(c echo.Context) (err error) {
|
||||
var user = new(model.User)
|
||||
|
||||
if err = c.Bind(user); err != nil {
|
||||
return c.NoContent(http.StatusBadRequest)
|
||||
}
|
||||
|
||||
user.Password = fmt.Sprintf("%x", sha256.Sum256([]byte(user.Password)))
|
||||
|
||||
tx := h.DB.Omit("ID", "CreatedAt", "UpdatedAt", "DeletedAt").Create(user)
|
||||
|
||||
if tx.RowsAffected == 0 {
|
||||
return c.NoContent(http.StatusBadGateway)
|
||||
}
|
||||
|
||||
user.Password = ""
|
||||
|
||||
return c.JSON(http.StatusCreated, user)
|
||||
}
|
||||
52
main.go
Normal file
52
main.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"astra-users/handler"
|
||||
"astra-users/model"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/labstack/echo/v4/middleware"
|
||||
"gorm.io/driver/sqlite"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/logger"
|
||||
"log"
|
||||
"os"
|
||||
"time"
|
||||
)
|
||||
|
||||
func main() {
|
||||
newLogger := logger.New(
|
||||
log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
|
||||
logger.Config{
|
||||
SlowThreshold: time.Second, // Slow SQL threshold
|
||||
LogLevel: logger.Info, // Log level
|
||||
IgnoreRecordNotFoundError: true, // Ignore ErrRecordNotFound error for logger
|
||||
ParameterizedQueries: true, // Don't include params in the SQL log
|
||||
Colorful: false, // Disable color
|
||||
},
|
||||
)
|
||||
|
||||
db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{
|
||||
Logger: newLogger,
|
||||
})
|
||||
if err != nil {
|
||||
panic("failed to connect database")
|
||||
}
|
||||
e := echo.New()
|
||||
|
||||
db.AutoMigrate(&model.User{})
|
||||
|
||||
e.Use(middleware.Logger())
|
||||
|
||||
var h = &handler.Handler{DB: db}
|
||||
|
||||
e.POST("/login", h.Login)
|
||||
e.GET("/me", h.GetCurrentUser)
|
||||
e.POST("/", h.CreateUser)
|
||||
e.GET("/", h.GetUsers)
|
||||
e.GET("/:id", h.GetUsers)
|
||||
e.PATCH("/:id", h.UpdateUser)
|
||||
e.DELETE("/:id", h.DeleteUser)
|
||||
e.GET("/health", h.Health)
|
||||
|
||||
e.Logger.Fatal(e.Start(":8081"))
|
||||
}
|
||||
20
model/user.go
Normal file
20
model/user.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package model
|
||||
|
||||
import "gorm.io/gorm"
|
||||
|
||||
type (
|
||||
User struct {
|
||||
gorm.Model
|
||||
UserName string `json:"userName" gorm:"unique"`
|
||||
Password string `json:"password,omitempty"`
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
}
|
||||
)
|
||||
|
||||
type APIUser struct {
|
||||
UserName string `json:"userName" gorm:"unique"`
|
||||
Password string `json:"password,omitempty"`
|
||||
FirstName string `json:"firstName"`
|
||||
LastName string `json:"lastName"`
|
||||
}
|
||||
27
pkg/utils/query.go
Normal file
27
pkg/utils/query.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
func ApplySort(tx *gorm.DB, column string, isDesc bool) {
|
||||
tx.Order(clause.OrderByColumn{
|
||||
Column: clause.Column{Name: column},
|
||||
Desc: isDesc,
|
||||
})
|
||||
}
|
||||
|
||||
func ApplyFilters(tx *gorm.DB, column string, value string) {
|
||||
if column != "" && value != "" {
|
||||
tx.Where(column + " LIKE '%" + value + "%'")
|
||||
}
|
||||
}
|
||||
|
||||
func ApplyIdFilter(c echo.Context, tx *gorm.DB) {
|
||||
id := c.Param("id")
|
||||
if id != "" {
|
||||
tx.Where("id = ?", id)
|
||||
}
|
||||
}
|
||||
52
pkg/utils/url.go
Normal file
52
pkg/utils/url.go
Normal file
@@ -0,0 +1,52 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func GetQueryParam(query url.Values, key string, defaultVal string) string {
|
||||
data := query.Get(key)
|
||||
|
||||
if data == "" {
|
||||
return defaultVal
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
|
||||
func GetPaginationParams(query url.Values) (int, int) {
|
||||
offset := GetQueryParam(query, "offset", "0")
|
||||
limit := GetQueryParam(query, "limit", "10")
|
||||
|
||||
limitInt, err := strconv.Atoi(limit)
|
||||
|
||||
if err != nil {
|
||||
limitInt = 10
|
||||
}
|
||||
|
||||
offsetInt, err := strconv.Atoi(offset)
|
||||
|
||||
if err != nil {
|
||||
offsetInt = 0
|
||||
}
|
||||
|
||||
return limitInt, offsetInt
|
||||
}
|
||||
|
||||
func GetFilterParams(query url.Values) (string, bool, string, string) {
|
||||
sort := GetQueryParam(query, "sort", "id:asc")
|
||||
filter := GetQueryParam(query, "filter", ":")
|
||||
|
||||
filters := strings.Split(filter, ":")
|
||||
sorts := strings.Split(sort, ":")
|
||||
|
||||
isDesc := false
|
||||
|
||||
if sorts[1] == "desc" {
|
||||
isDesc = true
|
||||
}
|
||||
|
||||
return sorts[0], isDesc, filters[0], filters[1]
|
||||
}
|
||||
Reference in New Issue
Block a user