database

package
v0.0.0-...-447df18 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 28, 2025 License: MIT Imports: 16 Imported by: 0

Documentation

Overview

Package database provides access to the application's PostgreSQL database and defines the service layer for interacting with various data repositories. It offers a singleton service instance that exposes repository interfaces for different domain models such as users, products, authentication, and more.

This package also handles connection pooling, transaction management, and context-aware query execution using the pgx PostgreSQL driver.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrDuplicate      = "duplicate record"
	ErrForeignKey     = "related record not found"
	ErrNotFound       = "record not found"
	ErrInvalidInput   = "invalid input"
	ErrStringTooLong  = "input string is too long"
	ErrInvalidFormat  = "invalid input format"
	ErrNullViolation  = "missing required field"
	ErrCheckViolation = "invalid value for one of the fields"
	ErrUnknown        = "unknown database error"
)
View Source
var (
	StringDataRightTruncationCode = "22001" // A string is longer than the column allows.
	InvalidTextRepresentationCode = "22P02" // PostgreSQL can’t cast a string to the target data type.
	NotNullViolationCode          = "23502"
	ForeignKeyViolationCode       = "23503"
	UniqueViolationCode           = "23505"
	CheckViolationCode            = "23514"
)

Functions

func IsDBNotFoundErr

func IsDBNotFoundErr(err error) bool

func Parse

func Parse(err error, repo, method string, constraints Constraints) error

Parse interprets a database error and returns a more descriptive application-level error. It maps known PostgreSQL error codes (e.g., unique violations, foreign key violations) to domain-specific errors using the provided constraints map, and attaches contextual information such as the repository and method where the error occurred.

Types

type AccountVerificationCodeRepository

type AccountVerificationCodeRepository interface {
	// Create phone verification code,
	// columns reqired: otp_code, user_id, expires_at
	Create(ctx *gin.Context, db Querier, a *models.AccountVerificationCode) error

	// Update phone verification code,
	// columns reqired: is_used,
	// by user_id.
	Update(ctx *gin.Context, db Querier, a *models.AccountVerificationCode) error

	// Get phone verification code,
	// by user_id.
	Get(ctx *gin.Context, db Querier, userID int32) (*models.AccountVerificationCode, error)

	// count how many otp codes does the user have
	CountUserOtpCodes(ctx *gin.Context, db Querier, userID int) (int, error)

	// count the number of otp codes a user have in a day
	CountUserOTPCodesPerDay(
		ctx *gin.Context,
		db Querier,
		userID int32,
	) (int, error)
}

func NewAccountVerificationCodeRepository

func NewAccountVerificationCodeRepository() AccountVerificationCodeRepository

type BrandRepository

type BrandRepository interface{}

func NewBrandRepository

func NewBrandRepository() BrandRepository

type CartItemRepository

type CartItemRepository interface {
	// Create cart item.
	//
	// required columns: cart_id, product_id, total_price, quantity
	Create(ctx *gin.Context, db Querier, cartItem *models.CartItem) error

	// This method will get.
	//
	// The total_price of the whole cart as well as the whole quantity
	GetPriceQuantityByCartID(ctx *gin.Context, db Querier, cartID int32) (int, int, error)

	// Get cart Items by cart_id
	GetAll(ctx *gin.Context, db Querier, cartID int32) ([]GetCartItems, error)

	// Update cart item quantity by id
	Update(ctx *gin.Context, db Querier, id int32, quantity int) error

	// Delete cart item by id
	Delete(ctx *gin.Context, db Querier, id int32) error
}

func NewCartItemRepository

func NewCartItemRepository() CartItemRepository

type CartRepository

type CartRepository interface {
	// Create cart by user id
	Create(ctx *gin.Context, db Querier, userID int32) (int32, error)

	// Update cart by user id
	// required columns: total_price, quantity
	Update(ctx *gin.Context, db Querier, cart *models.Cart) error

	// Get cart id by user id
	GetIDByUserID(ctx *gin.Context, db Querier, userID int32) (int32, error)

	// Get cart by user id
	GetByUserID(ctx *gin.Context, db Querier, userID int32) (*models.Cart, error)

	// Delete cart by user id
	Delete(ctx *gin.Context, db Querier, userID int32) error
}

func NewCartRepository

func NewCartRepository() CartRepository

type CategoryRepository

type CategoryRepository interface {
	// Create new category,
	// required columns: name, parent_id.
	Create(ctx *gin.Context, db Querier, category *models.Category) (int32, error)

	// Get all categories
	GetAll(ctx *gin.Context, db Querier) (*[]models.Category, error)

	// Delete category by id.
	Delete(ctx *gin.Context, db Querier, id int32) error

	// Update category name by id
	Update(ctx *gin.Context, db Querier, id int32, newName string) error
}

func NewCategoryRepository

func NewCategoryRepository() CategoryRepository

type CityRepository

type CityRepository interface {
	GetAll(ctx *gin.Context, db Querier) (*[]models.City, error)
}

func NewCityRepository

func NewCityRepository() CityRepository

type ColorRepository

type ColorRepository interface {
	// Create color, required columns: color
	Create(ctx *gin.Context, db Querier, color string) error

	// Get all colors
	GetAll(ctx *gin.Context, db Querier) (*[]models.Color, error)

	// Update color by id
	Update(ctx *gin.Context, db Querier, id int32, color string) error

	// Delete color by id
	Delete(ctx *gin.Context, db Querier, id int32) error
}

func NewColorRepository

func NewColorRepository() ColorRepository

type Constraints

type Constraints map[string]string

type DBError

type DBError struct {
	Message string
	Repo    string
	Method  string
	Code    string
	Err     error
	Column  string
}

func NewDBError

func NewDBError(err error, message, repo, method, code, constraint string) DBError

func (DBError) Error

func (e DBError) Error() string

type GetCartItems

type GetCartItems struct {
	ID           int32  `json:"id"`
	Quantity     int    `json:"quantity"`
	TotalPrice   int    `json:"totalPrice"`
	VariantID    int32  `json:"variantId"`
	ProductName  string `json:"productName"`
	ProductImg   string `json:"productImg"`
	ProductPrice int    `json:"productPrice"`
	ColorID      int32  `json:"colorId"`
	SizeID       int32  `json:"sizeId"`
}

type ImageRepository

type ImageRepository interface {
	GetAllOfProduct(
		c *gin.Context,
		db Querier,
		productID int32,
	) ([]models.Image, error)

	// This method will create a record in the images table.
	//
	// Columns required: image, low_res_image, product_id.
	Create(*gin.Context, Querier, *models.Image) error
}

func NewImageRepository

func NewImageRepository() ImageRepository

type LocalAuthRepository

type LocalAuthRepository interface {
	// fetch the local auth model
	Get(ctx *gin.Context, db Querier, userID int32) (*models.LocalAuth, error)

	// create JWT based authentication,
	// columns required: user_id, password_hash.
	Create(ctx *gin.Context, db Querier, l *models.LocalAuth) error

	// update user local auth,
	// required columns: is_phone_verified, password_hash,
	// by user_id.
	Update(ctx *gin.Context, db Querier, l *models.LocalAuth) error

	// update is_account_verified column to true,
	// by user_id.
	UpdateIsAccountVerifiedToTrue(ctx *gin.Context, db Querier, userID int32) error

	CheckUserVerification(
		ctx *gin.Context,
		db Querier,
		userID int32,
	) (bool, error)
}

func NewLocalAuthRepository

func NewLocalAuthRepository() LocalAuthRepository

type OAuthRepository

type OAuthRepository interface {
	Create(ctx *gin.Context, db Querier, oauth *models.OAuth) error
}

func NewOAuthRepository

func NewOAuthRepository() OAuthRepository

type OrderDetailsRepository

type OrderDetailsRepository interface {
	// Create order details
	//
	// required columns: product_id, quantity, total_price, order_id
	Create(ctx *gin.Context, db Querier, orderDetails *models.OrderDetails) error
}

func NewOrderDetailsRepository

func NewOrderDetailsRepository() OrderDetailsRepository

type OrderRepository

type OrderRepository interface {
	Create(ctx *gin.Context, db Querier, order *models.Order) (int32, error)
}

func NewOrderRepository

func NewOrderRepository() OrderRepository

type PasswordResetRepository

type PasswordResetRepository interface {
	// Create password reset,
	// required columns: otp_code, expires_at, user_id
	Create(ctx *gin.Context, db Querier, p *models.PasswordReset) error

	// Get password reset by user_id
	Get(ctx *gin.Context, db Querier, userID int32) (*models.PasswordReset, error)

	// update is_used column to true by user_id
	UpdateAttemptToUsed(ctx *gin.Context, db Querier, userID int32) error

	// count the OTP codes per day
	CountOTPCodesPerDay(ctx *gin.Context, db Querier, userID int32) (int, error)
}

func NewPasswordResetRepository

func NewPasswordResetRepository() PasswordResetRepository

type Product

type Product struct {
	ID        int32   `json:"id"`
	Name      string  `json:"name"`
	Thumbnail string  `json:"thumbnail"`
	Brand     string  `json:"brand"`
	Category  string  `json:"category"`
	Price     int     `json:"price"`
	Rating    float32 `json:"rating"`
}

type ProductDetails

type ProductDetails struct {
	ID         int32       `json:"id"`
	Name       string      `json:"name"`
	Details    pgtype.Text `json:"details"`
	Thumbnail  string      `json:"thumbnail"`
	BrandID    int         `json:"brandId"`
	Brand      string      `json:"brand"`
	CategoryID int         `json:"categoryId"`
	Category   string      `json:"category"`
}

type ProductRepository

type ProductRepository interface {
	GetAll(
		ctx *gin.Context,
		db Querier,
		filters filters.Filters,
		prodFilter *filters.ProductFilterOptions,
	) ([]Product, filters.Metadata, error)

	GetDetails(ctx *gin.Context, db Querier, productID int) (*ProductDetails, error)

	Get(ctx *gin.Context, db Querier, productID int) (*models.Product, error)

	// This function will create a product.
	//
	// Columns required: name, details, thumbnail, brand_id, product_category.
	// Returns: id.
	Create(*gin.Context, Querier, *models.Product) (productID int32, err error)

	// This Method will update the product.
	//
	// Columns required: name, details, brand_id, product_category.
	// By: id.
	Update(*gin.Context, Querier, *models.Product) error

	// This method will delete a product and all its variants
	Delete(c *gin.Context, db Querier, id int32) error
}

func NewProductRepository

func NewProductRepository() ProductRepository

type ProductVariantDetails

type ProductVariantDetails struct {
	ID       int32  `json:"id"`
	Quantity int    `json:"quantity"`
	Price    int    `json:"price"`
	Color    string `json:"color"`
	Size     string `json:"size"`
}

type ProductVariantRepository

type ProductVariantRepository interface {
	GetAllOfProduct(c *gin.Context, db Querier, productID int32) ([]ProductVariantDetails, error)
	GetPriceByID(c *gin.Context, db Querier, id int32) (int, error)

	// This method will create a product variant.
	//
	// Columns required: quantity, price, product_id, color_id, size_id.
	Create(*gin.Context, Querier, *models.ProductVariant) error

	// This method will get a variant by id.
	Get(c *gin.Context, db Querier, variantID int32) (ProductVariantDetails, error)

	// This method will delete a variant by id.
	Delete(c *gin.Context, db Querier, variantID int) error

	// This method will update the product variant.
	//
	// Columns required: quantity, price, color_id, size_id,
	// By: id.
	Update(*gin.Context, Querier, *models.ProductVariant) error
}

func NewProductVariantRepository

func NewProductVariantRepository() ProductVariantRepository

type Querier

type Querier interface {
	Query(ctx context.Context, sql string, args ...any) (pgx.Rows, error)
	QueryRow(ctx context.Context, sql string, args ...any) pgx.Row
	Exec(ctx context.Context, sql string, args ...any) (pgconn.CommandTag, error)
}

type RatingReviewRepository

type RatingReviewRepository interface {
	// This method will create a Review, with the following data:
	// rating, review, user_id, product_id.
	Create(
		c *gin.Context,
		db Querier,
		rr *models.RatingReview,
	) error

	Get(c *gin.Context, db Querier, reviewID int32) (*models.RatingReview, error)

	GetAllOfProduct(
		c *gin.Context,
		db Querier,
		productID int32,
	) ([]RatingsAndReviewDetails, error)

	GetAllOfUser(c *gin.Context, db Querier, userID int32) ([]models.RatingReview, error)

	// This method updates the RatingReview model,
	// Required columns: rating, review.
	// By: id.
	Update(c *gin.Context, db Querier, rr *models.RatingReview) error

	// This method will delete a review from the database
	// by the review id.
	Delete(c *gin.Context, db Querier, reviewID int32) error
}

func NewRatingReviewRepository

func NewRatingReviewRepository() RatingReviewRepository

type RatingsAndReviewDetails

type RatingsAndReviewDetails struct {
	ID        int32       `json:"id"`
	Rating    int32       `json:"rating"`
	Review    string      `json:"review"`
	CreatedAt time.Time   `json:"createdAt"`
	UpdatedAt time.Time   `json:"updatedAt"`
	FirstName string      `json:"firstName"`
	LastName  string      `json:"lastName"`
	UserImage pgtype.Text `json:"userImage"`
	UserID    int32       `json:"userId"`
}

type Service

type Service interface {
	City() CityRepository
	OrderDetails() OrderDetailsRepository
	Order() OrderRepository
	CartItem() CartItemRepository
	Cart() CartRepository
	Brand() BrandRepository
	Category() CategoryRepository
	Color() ColorRepository
	Image() ImageRepository
	Product() ProductRepository
	ProductVariant() ProductVariantRepository
	RatingReview() RatingReviewRepository
	Size() SizeRepository
	PasswordReset() PasswordResetRepository
	AccountVerificationCode() AccountVerificationCodeRepository
	LocalAuth() LocalAuthRepository
	Oauth() OAuthRepository
	User() UserRepository
	Session() SessionRepository
	Wishlist() WishlistRepository
	Pool() *pgxpool.Pool
	// Make sure to use this method when all errors being returned are db errors.
	// you can use it when other errors are being returned but still.
	WithTransaction(ctx context.Context, fn func(tx pgx.Tx) error) error
	BeginTx(ctx *gin.Context) (pgx.Tx, error)
	Close()
}

Service represents a service that interacts with a database.

func New

func New(env *config.Env) Service

type SessionRepository

type SessionRepository interface {
	// Get a single session.
	//
	// By: user_id, user_agent.
	GetByUserIDAndUserAgent(
		ctx *gin.Context,
		db Querier,
		userID int32,
		userAgent string,
	) (models.Session, error)

	// Fetch all sessions of a certain user
	GetAllOfUser(
		ctx *gin.Context,
		db Querier,
		userID int32,
	) ([]models.Session, error)

	// This method will create a session, the following columns are required:
	// user_id, user_agent, refresh_token, expires_at.
	Create(ctx *gin.Context, db Querier, sess *models.Session) error

	// Update the user session with the following columns:
	// revoked, refresh_token, expires_at.
	// the session will be updated using its id.
	Update(ctx *gin.Context, db Querier, sess *models.Session) error

	// This method will revoke all sessions of a certain user
	RevokeAllOfUser(ctx *gin.Context, db Querier, userID int32) error
}

func NewSessionRepository

func NewSessionRepository() SessionRepository

type SizeRepository

type SizeRepository interface {
	// Create new size,
	// required columns: size, label.
	Create(ctx *gin.Context, db Querier, size *models.Size) error

	// Get all sizes
	GetAll(ctx *gin.Context, db Querier) (*[]models.Size, error)

	// Get size by label
	GetByLabel(ctx *gin.Context, db Querier, label []string) (*[]models.Size, error)

	// Update size and label by id,
	// required columns:size, label.
	Update(ctx *gin.Context, db Querier, size *models.Size) error

	// Delete size by id
	Delete(ctx *gin.Context, db Querier, id int32) error
}

func NewSizeRepository

func NewSizeRepository() SizeRepository

type UserRepository

type UserRepository interface {
	// This method will create the user, with the following data:
	// first_name, last_name, image, email, phone_number, role.
	Create(ctx *gin.Context, db Querier, user *models.User) (int, error)

	// This method will update the following user columns:
	// first_name, last_name, image, role.
	// based on the user id.
	Update(ctx *gin.Context, db Querier, u *models.User) error

	// Get user by id
	Get(ctx *gin.Context, db Querier, id int) (*models.User, error)

	// Delete user by id
	Delete(ctx *gin.Context, db Querier, id int) error

	// Get user by email
	GetByEmail(ctx *gin.Context, db Querier, email string) (*models.User, error)

	// Get the user role by user id
	GetRole(ctx *gin.Context, db Querier, id int32) (models.Role, error)

	// Get user id by email
	GetIDByEmail(ctx *gin.Context, db Querier, email string) (int, error)

	// Check if email is exist
	CheckEmailExistence(ctx *gin.Context, db Querier, email string) error
}

func NewUserRepository

func NewUserRepository() UserRepository

type WishlistRepository

type WishlistRepository interface {
	GetAllOfUser(c *gin.Context, db Querier, userID int32) ([]wishlist, error)

	// This method creates a wishlist record,
	// columns required: product_id, user_id
	Create(*gin.Context, Querier, *models.Wishlist) error

	Delete(c *gin.Context, db Querier, wishlistID int32) error
}

func NewWishlistRepository

func NewWishlistRepository() WishlistRepository

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL