package product import ( "context" "github.com/jmoiron/sqlx" "sismedika.com/sas/westone/types" ) type Store struct { db *sqlx.DB } func NewStore(db *sqlx.DB) *Store { return &Store{db: db} } func (s *Store) GetProductByID(productID int) (*types.Product, error) { product := new(types.Product) query := "SELECT * FROM products WHERE id = ?" // sqlx.Get is used for fetching a single record and scanning it into the struct if err := s.db.Get(product, query, productID); err != nil { return nil, err } return product, nil } func (s *Store) GetProductsByID(productIDs []int) ([]types.Product, error) { query, args, err := sqlx.In("SELECT * FROM products WHERE id IN (?)", productIDs) if err != nil { return nil, err } // Rebind the query for the specific database driver (e.g., mysql uses "?", postgres uses "$1", etc.) query = s.db.Rebind(query) var products []types.Product err = s.db.Select(&products, query, args...) if err != nil { return nil, err } return products, nil } func (s *Store) GetProducts() ([]*types.Product, error) { var products []*types.Product query := "SELECT * FROM products" // sqlx.Select is used to fetch multiple rows and map them into a slice of structs if err := s.db.Select(&products, query); err != nil { return nil, err } return products, nil } func (s *Store) CreateProduct(product types.CreateProductPayload) error { query := `INSERT INTO products (name, price, image, description, quantity) VALUES (:name, :price, :image, :description, :quantity)` // Using sqlx.NamedExec to map struct fields to named parameters in the query _, err := s.db.NamedExec(query, product) if err != nil { return err } return nil } func (s *Store) UpdateProduct(product types.Product) error { // Start a new transaction tx, err := s.db.BeginTxx(context.Background(), nil) if err != nil { return err } // Defer rollback to ensure transaction is rolled back in case of an error defer func() { if err != nil { tx.Rollback() } }() query := `UPDATE products SET name = :name, price = :price, image = :image, description = :description, quantity = :quantity WHERE id = :id` // Using tx.NamedExec to execute the update within the transaction _, err = tx.NamedExec(query, product) if err != nil { return err } // Commit the transaction if everything succeeded if err = tx.Commit(); err != nil { return err } return nil }