Adds the database abstraction layer (DAL) with a Transactions method and a Connection object to encapsulate the DB open connection. Includes a DAL unit test using the go-sqlmock library. Connection to a PostgreSQL database using environment variables to store the secrets. Overall, with the /transactions endpoint requesting directly to the DB, this patch finish the tracer bullet project. Issues #1, #5, #6 and #7
61 lines
1.1 KiB
Go
61 lines
1.1 KiB
Go
package dal
|
|
|
|
import (
|
|
"database/sql"
|
|
"errors"
|
|
"fmt"
|
|
"log"
|
|
"os"
|
|
|
|
"git.rosemyrtle.work/personal-finance/server/internal/entities"
|
|
|
|
_ "github.com/jackc/pgx/v5/stdlib"
|
|
)
|
|
|
|
type Connection struct {
|
|
db *sql.DB
|
|
}
|
|
|
|
func Open(credentials *entities.Credentials) (*Connection, error) {
|
|
if credentials == nil {
|
|
return nil, errors.New("missing credentials")
|
|
}
|
|
|
|
db, err := sql.Open("pgx", credentials.Database)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Unable to connect to database: %v\n", err)
|
|
return nil, err
|
|
}
|
|
|
|
if err := db.Ping(); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
return &Connection{db}, nil
|
|
}
|
|
|
|
func (c *Connection) Close() {
|
|
c.db.Close()
|
|
}
|
|
|
|
func (conn *Connection) Transactions() []entities.Transaction {
|
|
q := "SELECT t.date, t.description, t.amount FROM transactions t;"
|
|
|
|
rows, err := conn.db.Query(q)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
var result []entities.Transaction
|
|
|
|
for rows.Next() {
|
|
var t entities.Transaction
|
|
if err := rows.Scan(&t.Date, &t.Description, &t.Value); err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
result = append(result, t)
|
|
}
|
|
|
|
return result
|
|
}
|