customers.go (70 lines of code) (raw):
package main
import (
"context"
"fmt"
"github.com/jmoiron/sqlx"
)
type Customer struct {
ID int `json:"id"`
FullName string `json:"full_name"`
CompanyName string `json:"company_name"`
Email string `json:"email"`
Address string `json:"address"`
PostalCode string `json:"postal_code"`
City string `json:"city"`
Country string `json:"country"`
}
func getCustomers(ctx context.Context, db *sqlx.DB) ([]Customer, error) {
return queryCustomers(ctx, db, nil, nil, nil)
}
func getProductCustomers(ctx context.Context, db *sqlx.DB, productId, limit int) ([]Customer, error) {
return queryCustomers(ctx, db, nil, &productId, &limit)
}
func getCustomer(ctx context.Context, db *sqlx.DB, id int) (*Customer, error) {
customers, err := queryCustomers(ctx, db, &id, nil, nil)
if err != nil || len(customers) == 0 {
return nil, err
}
return &customers[0], nil
}
func queryCustomers(ctx context.Context, db *sqlx.DB, id, productId, limit *int) ([]Customer, error) {
var args []interface{}
queryString := `
SELECT
customers.id, full_name, company_name, email,
address, postal_code, city, country
FROM customers
`
if id != nil {
queryString += "WHERE id=?\n"
args = append(args, *id)
}
if productId != nil {
queryString += "" +
"JOIN orders ON customers.id=orders.customer_id " +
"JOIN order_lines ON orders.id=order_lines.order_id " +
"WHERE order_lines.product_id=?\n"
args = append(args, *productId)
}
if limit != nil {
queryString += fmt.Sprintf("LIMIT %d\n", *limit)
}
rows, err := db.QueryContext(ctx, db.Rebind(queryString), args...)
if err != nil {
return nil, err
}
defer rows.Close()
var customers []Customer
for rows.Next() {
var c Customer
if err := rows.Scan(
&c.ID, &c.FullName, &c.CompanyName,
&c.Email, &c.Address, &c.PostalCode,
&c.City, &c.Country,
); err != nil {
return nil, err
}
customers = append(customers, c)
}
return customers, rows.Err()
}