diff --git a/api/location.go b/api/location.go index d35fdf3..2782fe6 100644 --- a/api/location.go +++ b/api/location.go @@ -1,7 +1,6 @@ package api import ( - "database/sql" "fmt" "net/http" "os" @@ -11,6 +10,7 @@ import ( db "git.nochill.in/nochill/hiling_go/db/sqlc" "git.nochill.in/nochill/hiling_go/util" "github.com/gin-gonic/gin" + "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgtype" "github.com/meilisearch/meilisearch-go" ysqlc "github.com/yiplee/sqlc" @@ -63,7 +63,7 @@ func (server *Server) createLocation(ctx *gin.Context) { SubmittedBy: req.SubmittedBy, RegencyID: req.RegencyID, IsDeleted: false, - ApprovedBy: sql.NullInt32{Int32: 0, Valid: false}, + ApprovedBy: pgtype.Int4{Int32: 0, Valid: false}, GoogleMapsLink: pgtype.Text{Valid: len(req.GoogleMapsLink) > 0, String: req.GoogleMapsLink}, Thumbnail: tempImg, } @@ -111,7 +111,7 @@ type getTopListLocationsReq struct { Page int32 `form:"page" binding:"required,min=1"` PageSize int32 `form:"page_size" binding:"required,min=5"` OrderBy int16 `form:"order_by" binding:"numeric,min=1,max=3"` - RegionType int16 `form:"region_type" binding:"numeric,min=0,max=7"` + RegionType int32 `form:"region_type" binding:"numeric,min=0,max=7"` } func (server *Server) getTopListLocations(ctx *gin.Context) { @@ -136,7 +136,7 @@ func (server *Server) getTopListLocations(ctx *gin.Context) { Limit: req.PageSize, Offset: (req.Page - 1) * req.PageSize, OrderBy: orderby, - RegionType: sql.NullInt16{Valid: req.RegionType > 0, Int16: req.RegionType}, + RegionType: pgtype.Int4{Valid: req.RegionType > 0, Int32: req.RegionType}, } locations, err := server.Store.GetTopListLocations(ctx, arg) @@ -192,7 +192,7 @@ func (server *Server) getLocation(ctx *gin.Context) { location, err := server.Store.GetLocation(ctx, req.ID) if err != nil { - if err == sql.ErrNoRows { + if err == pgx.ErrNoRows { ctx.JSON(http.StatusNotFound, ErrorResponse(err, "")) return } @@ -272,7 +272,7 @@ func (server *Server) getListLocationReviews(ctx *gin.Context) { reviews, err := server.Store.GetListLocationReviews(ctx, arg) if err != nil { - if err == sql.ErrNoRows { + if err == pgx.ErrNoRows { ctx.JSON(http.StatusNotFound, ErrorResponse(err, "There's no critics reviews for this location yet")) return } @@ -294,7 +294,7 @@ func (server *Server) getListLocationReviews(ctx *gin.Context) { reviews, err := server.Store.GetListLocationReviews(ctx, arg) if err != nil { - if err == sql.ErrNoRows { + if err == pgx.ErrNoRows { ctx.JSON(http.StatusNotFound, ErrorResponse(err, "There's no critics reviews for this location yet")) return } diff --git a/api/reviews.go b/api/reviews.go index 0e3eb4a..2f41146 100644 --- a/api/reviews.go +++ b/api/reviews.go @@ -1,12 +1,13 @@ package api import ( - "database/sql" + "log" "net/http" db "git.nochill.in/nochill/hiling_go/db/sqlc" "git.nochill.in/nochill/hiling_go/util/token" "github.com/gin-gonic/gin" + "github.com/jackc/pgx/v5" ) type createReviewReq struct { @@ -76,6 +77,8 @@ func (server *Server) getUserReviewByLocation(ctx *gin.Context) { authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) + log.Println(authPayload) + arg := db.GetUserReviewByLocationParams{ SubmittedBy: int32(authPayload.UserID), LocationID: req.LocationID, @@ -84,7 +87,7 @@ func (server *Server) getUserReviewByLocation(ctx *gin.Context) { review, err := server.Store.GetUserReviewByLocation(ctx, arg) if err != nil { - if err == sql.ErrNoRows { + if err == pgx.ErrNoRows { ctx.JSON(http.StatusNotFound, ErrorResponse(err, "Review not found")) return } diff --git a/api/token.go b/api/token.go index 4f720ac..8223066 100644 --- a/api/token.go +++ b/api/token.go @@ -1,12 +1,12 @@ package api import ( - "database/sql" "fmt" "net/http" "time" "github.com/gin-gonic/gin" + "github.com/jackc/pgx/v5" ) type renewAccessRequest struct { @@ -33,7 +33,7 @@ func (server *Server) renewAccessToken(ctx *gin.Context) { session, err := server.Store.GetSession(ctx, int32(refreshPayload.UserID)) if err != nil { - if err == sql.ErrNoRows { + if err == pgx.ErrNoRows { ctx.JSON(http.StatusNotFound, ErrorResponse(err, "")) return } @@ -67,7 +67,7 @@ func (server *Server) renewAccessToken(ctx *gin.Context) { user, err := server.Store.GetUser(ctx, refreshPayload.Username) if err != nil { - if err == sql.ErrNoRows { + if err == pgx.ErrNoRows { ctx.JSON(http.StatusNotFound, ErrorResponse(err, "")) return } diff --git a/api/user.go b/api/user.go index 4a455b8..dfde29e 100644 --- a/api/user.go +++ b/api/user.go @@ -1,7 +1,6 @@ package api import ( - "database/sql" "encoding/json" "fmt" "net/http" @@ -13,6 +12,7 @@ import ( "git.nochill.in/nochill/hiling_go/util" "git.nochill.in/nochill/hiling_go/util/token" "github.com/gin-gonic/gin" + "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgtype" ) @@ -22,18 +22,18 @@ type createUserRequest struct { } type createUserResponse struct { - ID int32 `json:"id"` - Username string `json:"username"` - AvatarPicture string `json:"avatar_picture"` // avatar_url - BannedAt sql.NullTime `json:"banned_at"` - BannedUntil sql.NullTime `json:"banned_until"` - BanReason string `json:"ban_reason"` - IsPermaban bool `json:"is_permaban"` - IsAdmin bool `json:"is_admin"` - IsCritics bool `json:"is_critics"` - IsVerified bool `json:"is_verified"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID int32 `json:"id"` + Username string `json:"username"` + AvatarPicture string `json:"avatar_picture"` // avatar_url + BannedAt pgtype.Timestamp `json:"banned_at"` + BannedUntil pgtype.Timestamp `json:"banned_until"` + BanReason string `json:"ban_reason"` + IsPermaban bool `json:"is_permaban"` + IsAdmin bool `json:"is_admin"` + IsCritics bool `json:"is_critics"` + IsVerified bool `json:"is_verified"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } func (server *Server) createUser(ctx *gin.Context) { @@ -101,8 +101,8 @@ func (server *Server) createUser(ctx *gin.Context) { ID: user.ID, Username: user.Username, AvatarPicture: user.AvatarPicture.String, - BannedAt: sql.NullTime{Valid: user.BannedAt.Valid, Time: user.BannedAt.Time}, - BannedUntil: sql.NullTime{Valid: user.BannedUntil.Valid, Time: user.BannedUntil.Time}, + BannedAt: pgtype.Timestamp{Valid: user.BannedAt.Valid, Time: user.BannedAt.Time}, + BannedUntil: pgtype.Timestamp{Valid: user.BannedUntil.Valid, Time: user.BannedUntil.Time}, BanReason: user.BanReason.String, IsPermaban: user.IsPermaban.Bool, IsAdmin: user.IsAdmin.Bool, @@ -177,9 +177,9 @@ func (server *Server) updateUser(ctx *gin.Context) { authPayload := ctx.MustGet(authorizationPayloadKey).(*token.Payload) user, err := server.Store.UpdateUser(ctx, db.UpdateUserParams{ - About: sql.NullString{String: req.About, Valid: true}, + About: pgtype.Text{String: req.About, Valid: true}, SocialMedia: req.SocialMedia, - Website: sql.NullString{String: req.Website, Valid: len(req.Website) > 0}, + Website: pgtype.Text{String: req.Website, Valid: len(req.Website) > 0}, ID: int32(authPayload.UserID), }) @@ -258,7 +258,7 @@ func (server *Server) login(ctx *gin.Context) { user, err := server.Store.GetUser(ctx, req.Username) if err != nil { - if err == sql.ErrNoRows { + if err == pgx.ErrNoRows { ctx.JSON(http.StatusNotFound, ErrorResponse(err, "User not found")) return } diff --git a/db/sqlc/locations.go b/db/sqlc/locations.go index e4ce2a3..8bd0307 100644 --- a/db/sqlc/locations.go +++ b/db/sqlc/locations.go @@ -2,7 +2,6 @@ package db import ( "context" - "database/sql" "fmt" "github.com/jackc/pgx/v5/pgtype" @@ -12,33 +11,33 @@ type GetTopListLocationsParams struct { Limit int32 Offset int32 OrderBy string - RegionType sql.NullInt16 + RegionType pgtype.Int4 } type GetTopListLocationsRow struct { - RowNumber int32 `json:"row_number"` - ID int32 `json:"id"` - Name string `json:"name"` - RegionName string `json:"region_name"` - Thumbnail sql.NullString `json:"thumbnail"` - Address string `json:"address"` - GoogleMapsLink string `json:"google_maps_link"` - RegencyName string `json:"regency_name"` - CriticScore int16 `json:"critic_score"` - CriticCount int16 `json:"critic_count"` - UserScore int16 `json:"user_score"` - UserCount int16 `json:"user_count"` - TotalCount int16 `json:"total_count"` - CriticBayes int16 `json:"critic_bayes"` - UserBayes int16 `json:"user_bayes"` - AvgBayes int16 `json:"avg_bayes"` + RowNumber int32 `json:"row_number"` + ID int32 `json:"id"` + Name string `json:"name"` + RegionName string `json:"region_name"` + Thumbnail pgtype.Text `json:"thumbnail"` + Address string `json:"address"` + GoogleMapsLink string `json:"google_maps_link"` + RegencyName string `json:"regency_name"` + CriticScore int16 `json:"critic_score"` + CriticCount int16 `json:"critic_count"` + UserScore int16 `json:"user_score"` + UserCount int16 `json:"user_count"` + TotalCount int16 `json:"total_count"` + CriticBayes int16 `json:"critic_bayes"` + UserBayes int16 `json:"user_bayes"` + AvgBayes int16 `json:"avg_bayes"` } func (q *Queries) GetTopListLocations(ctx context.Context, arg GetTopListLocationsParams) ([]GetTopListLocationsRow, error) { regionType := "" if arg.RegionType.Valid { - regionType = fmt.Sprintf("AND reg.id = %d", arg.RegionType.Int16) + regionType = fmt.Sprintf("AND reg.id = %d", arg.RegionType.Int32) } // https://fulmicoton.com/posts/bayesian_rating/ @@ -111,19 +110,19 @@ func (q *Queries) GetTopListLocations(ctx context.Context, arg GetTopListLocatio } type GetLocationRow struct { - ID int32 `json:"id"` - Name string `json:"name"` - Address string `json:"address"` - RegencyName string `json:"regency_name"` - ProvinceName string `json:"province_name"` - RegionName string `json:"region_name"` - GoogleMapsLink string `json:"google_maps_link"` - Thumbnail sql.NullString `json:"thumbnail"` - SubmittedBy string `json:"submitted_by"` - CriticScore int32 `json:"critic_score"` - CriticCount int32 `json:"critic_count"` - UserScore int32 `json:"user_score"` - UserCount int32 `json:"user_count"` + ID int32 `json:"id"` + Name string `json:"name"` + Address string `json:"address"` + RegencyName string `json:"regency_name"` + ProvinceName string `json:"province_name"` + RegionName string `json:"region_name"` + GoogleMapsLink string `json:"google_maps_link"` + Thumbnail pgtype.Text `json:"thumbnail"` + SubmittedBy string `json:"submitted_by"` + CriticScore int32 `json:"critic_score"` + CriticCount int32 `json:"critic_count"` + UserScore int32 `json:"user_score"` + UserCount int32 `json:"user_count"` } var getLocationQ = ` @@ -189,14 +188,14 @@ RETURNING id ` type CreateLocationParams struct { - Address string `json:"address"` - Name string `json:"name"` - SubmittedBy int32 `json:"submitted_by"` - LocationType LocationType `json:"location_type"` - RegencyID int16 `json:"regency_id"` - GoogleMapsLink pgtype.Text `json:"google_maps_link"` - IsDeleted bool `json:"is_deleted"` - ApprovedBy sql.NullInt32 `json:"approved_by"` + Address string `json:"address"` + Name string `json:"name"` + SubmittedBy int32 `json:"submitted_by"` + LocationType LocationType `json:"location_type"` + RegencyID int16 `json:"regency_id"` + GoogleMapsLink pgtype.Text `json:"google_maps_link"` + IsDeleted bool `json:"is_deleted"` + ApprovedBy pgtype.Int4 `json:"approved_by"` } func (q *Queries) CreateLocation(ctx context.Context, arg CreateLocationParams) (int32, error) { diff --git a/db/sqlc/reviews.go b/db/sqlc/reviews.go index 8f949d6..3ab5de8 100644 --- a/db/sqlc/reviews.go +++ b/db/sqlc/reviews.go @@ -2,8 +2,9 @@ package db import ( "context" - "database/sql" "time" + + "github.com/jackc/pgx/v5/pgtype" ) const createReview = `-- name: CreateReview :one @@ -59,14 +60,14 @@ type GetListLocationReviewsParams struct { } type GetListLocationReviewsRow struct { - ID int32 `json:"id"` - Score int8 `json:"score"` - Comment string `json:"comments"` - UserID int32 `json:"user_id"` - Username string `json:"username"` - UserAvatar sql.NullString `json:"user_avatar"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID int32 `json:"id"` + Score int8 `json:"score"` + Comment string `json:"comments"` + UserID int32 `json:"user_id"` + Username string `json:"username"` + UserAvatar pgtype.Text `json:"user_avatar"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } const getListLocationReviews = ` diff --git a/db/sqlc/tx_location.go b/db/sqlc/tx_location.go index e56004e..6abf91c 100644 --- a/db/sqlc/tx_location.go +++ b/db/sqlc/tx_location.go @@ -2,7 +2,6 @@ package db import ( "context" - "database/sql" "github.com/jackc/pgx/v5/pgtype" ) @@ -15,7 +14,7 @@ type CreateLocationTxParams struct { RegencyID int16 `json:"regency_id"` GoogleMapsLink pgtype.Text `json:"google_maps_link"` IsDeleted bool `json:"is_deleted"` - ApprovedBy sql.NullInt32 `json:"approved_by"` + ApprovedBy pgtype.Int4 `json:"approved_by"` Thumbnail []CreateImageParams `json:"thumbnails"` } diff --git a/db/sqlc/users.go b/db/sqlc/users.go index da1308f..3bece90 100644 --- a/db/sqlc/users.go +++ b/db/sqlc/users.go @@ -2,9 +2,10 @@ package db import ( "context" - "database/sql" "encoding/json" "time" + + "github.com/jackc/pgx/v5/pgtype" ) const getUserQ = `-- name: GetUser :one @@ -32,24 +33,24 @@ WHERE username = $1 ` type GetUserRow struct { - ID int32 `json:"id"` - Email string `json:"email"` - Password string `json:"-"` - About string `json:"about"` - Website string `json:"website"` - Username string `json:"username"` - GoogleSignInPayload string `json:"google_sign_in_payload"` - AvatarPicture string `json:"avatar_picture"` - BannedAt sql.NullTime `json:"banned_at"` - BannedUntil sql.NullTime `json:"banned_until"` - BanReason string `json:"ban_reason"` - IsPermaban bool `json:"is_permaban"` - IsAdmin bool `json:"is_admin"` - IsCritics bool `json:"is_critics"` - IsVerified bool `json:"is_verified"` - SocialMedia json.RawMessage `json:"social_media"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID int32 `json:"id"` + Email string `json:"email"` + Password string `json:"-"` + About string `json:"about"` + Website string `json:"website"` + Username string `json:"username"` + GoogleSignInPayload string `json:"google_sign_in_payload"` + AvatarPicture string `json:"avatar_picture"` + BannedAt pgtype.Timestamp `json:"banned_at"` + BannedUntil pgtype.Timestamp `json:"banned_until"` + BanReason string `json:"ban_reason"` + IsPermaban bool `json:"is_permaban"` + IsAdmin bool `json:"is_admin"` + IsCritics bool `json:"is_critics"` + IsVerified bool `json:"is_verified"` + SocialMedia json.RawMessage `json:"social_media"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } func (q *Queries) GetUser(ctx context.Context, username string) (GetUserRow, error) { @@ -173,31 +174,31 @@ RETURNING ` type UpdateUserParams struct { - About sql.NullString `json:"about"` - SocialMedia interface{} `json:"social_media"` - Website sql.NullString `json:"website"` - ID int32 `json:"id"` + About pgtype.Text `json:"about"` + SocialMedia interface{} `json:"social_media"` + Website pgtype.Text `json:"website"` + ID int32 `json:"id"` } type UpdateUserRow struct { - ID int32 `json:"id"` - Email string `json:"email"` - Username string `json:"username"` - AvatarPicture string `json:"avatar_picture"` - About string `json:"about"` - Website string `json:"website"` - GoogleSignInPayload string `json:"google_sign_in_payload"` - BannedAt sql.NullTime `json:"banned_at"` - BannedUntil sql.NullTime `json:"banned_until"` - BanReason string `json:"ban_reason"` - IsPermaban bool `json:"is_permaban"` - IsAdmin bool `json:"is_admin"` - IsCritics bool `json:"is_critics"` - IsVerified bool `json:"is_verified"` - IsActive bool `json:"is_active"` - SocialMedia json.RawMessage `json:"social_media"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ID int32 `json:"id"` + Email string `json:"email"` + Username string `json:"username"` + AvatarPicture string `json:"avatar_picture"` + About string `json:"about"` + Website string `json:"website"` + GoogleSignInPayload string `json:"google_sign_in_payload"` + BannedAt pgtype.Timestamp `json:"banned_at"` + BannedUntil pgtype.Timestamp `json:"banned_until"` + BanReason string `json:"ban_reason"` + IsPermaban bool `json:"is_permaban"` + IsAdmin bool `json:"is_admin"` + IsCritics bool `json:"is_critics"` + IsVerified bool `json:"is_verified"` + IsActive bool `json:"is_active"` + SocialMedia json.RawMessage `json:"social_media"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } func (q *Queries) UpdateUser(ctx context.Context, arg UpdateUserParams) (UpdateUserRow, error) {