-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdb.go
102 lines (81 loc) · 2.6 KB
/
db.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
package main
import (
"database/sql"
"fmt"
sq "github.com/Masterminds/squirrel"
_ "github.com/lib/pq"
)
const (
PRODUCTS_TBL = `CREATE TABLE IF NOT EXISTS products (
name TEXT PRIMARY KEY,
category TEXT NOT NULL,
package TEXT NOT NULL,
price INTEGER NOT NULL,
retail INTEGER NOT NULL
);`
)
type Store struct {
db *sql.DB
builder sq.StatementBuilderType
}
func newStore(dsn string) (*Store, error) {
db, err := sql.Open("postgres", dsn)
if err != nil {
return nil, fmt.Errorf("error opening database connection: %w", err)
}
if _, err := db.Exec(PRODUCTS_TBL); err != nil {
return nil, fmt.Errorf("error creating products table: %w", err)
}
cache := sq.NewStmtCache(db)
store := Store{db: db, builder: sq.StatementBuilder.PlaceholderFormat(sq.Dollar).RunWith(cache)}
return &store, nil
}
func (s Store) createProduct(product Product) error {
q := s.builder.Insert("products").SetMap(product.Map())
if _, err := q.Exec(); err != nil {
return fmt.Errorf("error inserting product: %w", err)
}
return nil
}
func (s Store) getProduct(name string) (Product, error) {
var product Product
q := s.builder.Select("name", "category", "package", "price", "retail").From("products").Where(sq.Eq{"name": name})
if err := q.QueryRow().Scan(&product.Name, &product.Category, &product.Package, &product.Price, &product.Retail); err != nil {
return product, fmt.Errorf("error scanning product: %w", err)
}
return product, nil
}
func (s Store) listProducts() ([]Product, error) {
q := s.builder.Select("name", "category", "package", "price", "retail").From("products").OrderBy("name ASC")
rows, err := q.Query()
if err != nil {
return nil, fmt.Errorf("error getting products: %w", err)
}
defer rows.Close()
var products []Product
for rows.Next() {
var product Product
if err := rows.Scan(&product.Name, &product.Category, &product.Package, &product.Price, &product.Retail); err != nil {
return nil, fmt.Errorf("error scanning product: %w", err)
}
products = append(products, product)
}
if err := rows.Err(); err != nil {
return nil, fmt.Errorf("error scanning products: %w", err)
}
return products, nil
}
func (s Store) updateProduct(name string, updates map[string]any) error {
q := s.builder.Update("products").SetMap(updates).Where(sq.Eq{"name": name})
if _, err := q.Exec(); err != nil {
return fmt.Errorf("error updating product: %w", err)
}
return nil
}
func (s Store) deleteProduct(name string) error {
q := s.builder.Delete("products").Where(sq.Eq{"name": name})
if _, err := q.Exec(); err != nil {
return fmt.Errorf("error deleting product: %w", err)
}
return nil
}