ft/adds first sqlc models and first tests

This commit is contained in:
itsscb 2023-09-12 23:28:09 +02:00
parent b28a52dc38
commit e04d132b39
11 changed files with 614 additions and 1 deletions

1
.gitignore vendored
View File

@ -13,6 +13,7 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
coverage.html
# Dependency directories (remove the comment below to include it)
# vendor/

View File

@ -24,4 +24,13 @@ dropdb:
sqlc:
sqlc generate
.PHONY: postgres migratenew createdb dropdb migrateup migratedown sqlc
sqlcinit:
sqlc init
test:
go test -v -coverage -short -count=1 ./...
coverage:
go test -coverprofile=coverage.out ./... && go tool cover -html=coverage.out
.PHONY: postgres migratenew createdb dropdb migrateup migratedown sqlc sqlcinit test

51
db/query/customer.sql Normal file
View File

@ -0,0 +1,51 @@
-- name: GetCustomer :one
SELECT * FROM customers
WHERE "ID" = $1 LIMIT 1;
-- name: CreateCutomer :one
INSERT INTO customers (
username,
passwordhash,
firstname,
lastname,
birthday,
email,
phone,
city,
zip,
street,
country,
creator,
changer
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13
) RETURNING *;
-- name: ListCustomers :many
SELECT * FROM customers
ORDER BY username
LIMIT $1
OFFSET $2;
-- name: UpdateCustomer :one
UPDATE customers
SET
username = COALESCE(sqlc.narg(username), username),
passwordhash = COALESCE(sqlc.narg(passwordhash), passwordhash),
firstname = COALESCE(sqlc.narg(firstname), firstname),
lastname = COALESCE(sqlc.narg(lastname), lastname),
birthday = COALESCE(sqlc.narg(birthday), birthday),
email = COALESCE(sqlc.narg(email), email),
phone = COALESCE(sqlc.narg(phone), phone),
city = COALESCE(sqlc.narg(city), city),
zip = COALESCE(sqlc.narg(zip), zip),
street = COALESCE(sqlc.narg(street), street),
country = COALESCE(sqlc.narg(country), country),
changer = $2,
changed = now()
WHERE "ID" = $1
RETURNING *;
-- name: DeleteCustomer :exec
DELETE FROM customers
WHERE "ID" = $1;

271
db/sqlc/customer.sql.go Normal file
View File

@ -0,0 +1,271 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.21.0
// source: customer.sql
package db
import (
"context"
"database/sql"
"time"
)
const createCutomer = `-- name: CreateCutomer :one
INSERT INTO customers (
username,
passwordhash,
firstname,
lastname,
birthday,
email,
phone,
city,
zip,
street,
country,
creator,
changer
) VALUES (
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13
) RETURNING "ID", username, passwordhash, firstname, lastname, birthday, "privacyAccepted", "privacyAcceptedDate", email, phone, city, zip, street, country, token, "tokenValid", "tokenExpiration", creator, created, changer, changed
`
type CreateCutomerParams struct {
Username string `json:"username"`
Passwordhash string `json:"passwordhash"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
Birthday time.Time `json:"birthday"`
Email string `json:"email"`
Phone sql.NullString `json:"phone"`
City string `json:"city"`
Zip string `json:"zip"`
Street string `json:"street"`
Country string `json:"country"`
Creator string `json:"creator"`
Changer string `json:"changer"`
}
func (q *Queries) CreateCutomer(ctx context.Context, arg CreateCutomerParams) (Customer, error) {
row := q.db.QueryRowContext(ctx, createCutomer,
arg.Username,
arg.Passwordhash,
arg.Firstname,
arg.Lastname,
arg.Birthday,
arg.Email,
arg.Phone,
arg.City,
arg.Zip,
arg.Street,
arg.Country,
arg.Creator,
arg.Changer,
)
var i Customer
err := row.Scan(
&i.ID,
&i.Username,
&i.Passwordhash,
&i.Firstname,
&i.Lastname,
&i.Birthday,
&i.PrivacyAccepted,
&i.PrivacyAcceptedDate,
&i.Email,
&i.Phone,
&i.City,
&i.Zip,
&i.Street,
&i.Country,
&i.Token,
&i.TokenValid,
&i.TokenExpiration,
&i.Creator,
&i.Created,
&i.Changer,
&i.Changed,
)
return i, err
}
const deleteCustomer = `-- name: DeleteCustomer :exec
DELETE FROM customers
WHERE "ID" = $1
`
func (q *Queries) DeleteCustomer(ctx context.Context, id int64) error {
_, err := q.db.ExecContext(ctx, deleteCustomer, id)
return err
}
const getCustomer = `-- name: GetCustomer :one
SELECT "ID", username, passwordhash, firstname, lastname, birthday, "privacyAccepted", "privacyAcceptedDate", email, phone, city, zip, street, country, token, "tokenValid", "tokenExpiration", creator, created, changer, changed FROM customers
WHERE "ID" = $1 LIMIT 1
`
func (q *Queries) GetCustomer(ctx context.Context, id int64) (Customer, error) {
row := q.db.QueryRowContext(ctx, getCustomer, id)
var i Customer
err := row.Scan(
&i.ID,
&i.Username,
&i.Passwordhash,
&i.Firstname,
&i.Lastname,
&i.Birthday,
&i.PrivacyAccepted,
&i.PrivacyAcceptedDate,
&i.Email,
&i.Phone,
&i.City,
&i.Zip,
&i.Street,
&i.Country,
&i.Token,
&i.TokenValid,
&i.TokenExpiration,
&i.Creator,
&i.Created,
&i.Changer,
&i.Changed,
)
return i, err
}
const listCustomers = `-- name: ListCustomers :many
SELECT "ID", username, passwordhash, firstname, lastname, birthday, "privacyAccepted", "privacyAcceptedDate", email, phone, city, zip, street, country, token, "tokenValid", "tokenExpiration", creator, created, changer, changed FROM customers
ORDER BY username
LIMIT $1
OFFSET $2
`
type ListCustomersParams struct {
Limit int32 `json:"limit"`
Offset int32 `json:"offset"`
}
func (q *Queries) ListCustomers(ctx context.Context, arg ListCustomersParams) ([]Customer, error) {
rows, err := q.db.QueryContext(ctx, listCustomers, arg.Limit, arg.Offset)
if err != nil {
return nil, err
}
defer rows.Close()
items := []Customer{}
for rows.Next() {
var i Customer
if err := rows.Scan(
&i.ID,
&i.Username,
&i.Passwordhash,
&i.Firstname,
&i.Lastname,
&i.Birthday,
&i.PrivacyAccepted,
&i.PrivacyAcceptedDate,
&i.Email,
&i.Phone,
&i.City,
&i.Zip,
&i.Street,
&i.Country,
&i.Token,
&i.TokenValid,
&i.TokenExpiration,
&i.Creator,
&i.Created,
&i.Changer,
&i.Changed,
); err != nil {
return nil, err
}
items = append(items, i)
}
if err := rows.Close(); err != nil {
return nil, err
}
if err := rows.Err(); err != nil {
return nil, err
}
return items, nil
}
const updateCustomer = `-- name: UpdateCustomer :one
UPDATE customers
SET
username = COALESCE($3, username),
passwordhash = COALESCE($4, passwordhash),
firstname = COALESCE($5, firstname),
lastname = COALESCE($6, lastname),
birthday = COALESCE($7, birthday),
email = COALESCE($8, email),
phone = COALESCE($9, phone),
city = COALESCE($10, city),
zip = COALESCE($11, zip),
street = COALESCE($12, street),
country = COALESCE($13, country),
changer = $2,
changed = now()
WHERE "ID" = $1
RETURNING "ID", username, passwordhash, firstname, lastname, birthday, "privacyAccepted", "privacyAcceptedDate", email, phone, city, zip, street, country, token, "tokenValid", "tokenExpiration", creator, created, changer, changed
`
type UpdateCustomerParams struct {
ID int64 `json:"ID"`
Changer string `json:"changer"`
Username sql.NullString `json:"username"`
Passwordhash sql.NullString `json:"passwordhash"`
Firstname sql.NullString `json:"firstname"`
Lastname sql.NullString `json:"lastname"`
Birthday sql.NullTime `json:"birthday"`
Email sql.NullString `json:"email"`
Phone sql.NullString `json:"phone"`
City sql.NullString `json:"city"`
Zip sql.NullString `json:"zip"`
Street sql.NullString `json:"street"`
Country sql.NullString `json:"country"`
}
func (q *Queries) UpdateCustomer(ctx context.Context, arg UpdateCustomerParams) (Customer, error) {
row := q.db.QueryRowContext(ctx, updateCustomer,
arg.ID,
arg.Changer,
arg.Username,
arg.Passwordhash,
arg.Firstname,
arg.Lastname,
arg.Birthday,
arg.Email,
arg.Phone,
arg.City,
arg.Zip,
arg.Street,
arg.Country,
)
var i Customer
err := row.Scan(
&i.ID,
&i.Username,
&i.Passwordhash,
&i.Firstname,
&i.Lastname,
&i.Birthday,
&i.PrivacyAccepted,
&i.PrivacyAcceptedDate,
&i.Email,
&i.Phone,
&i.City,
&i.Zip,
&i.Street,
&i.Country,
&i.Token,
&i.TokenValid,
&i.TokenExpiration,
&i.Creator,
&i.Created,
&i.Changer,
&i.Changed,
)
return i, err
}

52
db/sqlc/customer_test.go Normal file
View File

@ -0,0 +1,52 @@
package db
import (
"context"
"database/sql"
"testing"
"time"
"github.com/stretchr/testify/require"
)
func TestCreateCustomer(t *testing.T) {
arg := CreateCutomerParams{
Username: "whoami123",
Passwordhash: "abcdefghijklmnopqrstuvwxyz123456789",
Firstname: "John",
Lastname: "Doe",
Birthday: time.Date(1990, 1, 1, 0, 0, 0, 0, time.UTC),
Email: "john.doe@example.com",
Phone: sql.NullString{
Valid: true,
String: "0123456789",
},
City: "New York",
Zip: "12345",
Street: "Main Street 1",
Country: "United States",
Creator: "user",
}
account, err := testQueries.CreateCutomer(context.Background(), arg)
require.NoError(t, err)
require.NotEmpty(t, account)
require.Equal(t, arg.Username, account.Username)
require.Equal(t, arg.Passwordhash, account.Passwordhash)
require.Equal(t, arg.Firstname, account.Firstname)
require.Equal(t, arg.Lastname, account.Lastname)
require.Equal(t, arg.Birthday, account.Birthday)
require.Equal(t, arg.Email, account.Email)
require.Equal(t, arg.Phone, account.Phone)
require.Equal(t, arg.City, account.City)
require.Equal(t, arg.Zip, account.Zip)
require.Equal(t, arg.Street, account.Street)
require.Equal(t, arg.Country, account.Country)
require.Equal(t, arg.Creator, account.Creator)
require.NotZero(t, account.ID)
require.NotZero(t, account.Created)
_ = testQueries.DeleteCustomer(context.Background(), account.ID)
}

31
db/sqlc/db.go Normal file
View File

@ -0,0 +1,31 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.21.0
package db
import (
"context"
"database/sql"
)
type DBTX interface {
ExecContext(context.Context, string, ...interface{}) (sql.Result, error)
PrepareContext(context.Context, string) (*sql.Stmt, error)
QueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)
QueryRowContext(context.Context, string, ...interface{}) *sql.Row
}
func New(db DBTX) *Queries {
return &Queries{db: db}
}
type Queries struct {
db DBTX
}
func (q *Queries) WithTx(tx *sql.Tx) *Queries {
return &Queries{
db: tx,
}
}

28
db/sqlc/main_test.go Normal file
View File

@ -0,0 +1,28 @@
package db
import (
"database/sql"
"log"
"os"
"testing"
_ "github.com/lib/pq"
)
var testQueries *Queries
const (
dbDriver = "postgres"
dbSource = "postgresql://root:secret@localhost:5432/df?sslmode=disable"
)
func TestMain(m *testing.M) {
conn, err := sql.Open(dbDriver, dbSource)
if err != nil {
log.Fatalf("could not connect to DB: %s", err)
}
testQueries = New(conn)
os.Exit(m.Run())
}

128
db/sqlc/models.go Normal file
View File

@ -0,0 +1,128 @@
// Code generated by sqlc. DO NOT EDIT.
// versions:
// sqlc v1.21.0
package db
import (
"database/sql"
"time"
)
type Customer struct {
ID int64 `json:"ID"`
Username string `json:"username"`
Passwordhash string `json:"passwordhash"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
Birthday time.Time `json:"birthday"`
PrivacyAccepted bool `json:"privacyAccepted"`
PrivacyAcceptedDate sql.NullTime `json:"privacyAcceptedDate"`
Email string `json:"email"`
Phone sql.NullString `json:"phone"`
City string `json:"city"`
Zip string `json:"zip"`
Street string `json:"street"`
Country string `json:"country"`
Token sql.NullString `json:"token"`
TokenValid sql.NullBool `json:"tokenValid"`
TokenExpiration time.Time `json:"tokenExpiration"`
Creator string `json:"creator"`
Created time.Time `json:"created"`
Changer string `json:"changer"`
Changed time.Time `json:"changed"`
}
type Document struct {
ID int64 `json:"ID"`
PersonID sql.NullInt64 `json:"personID"`
Name string `json:"name"`
Type string `json:"type"`
Path string `json:"path"`
Url string `json:"url"`
Valid bool `json:"valid"`
ValidDate sql.NullTime `json:"validDate"`
ValidatedBy sql.NullString `json:"validatedBy"`
}
type Mail struct {
ID int64 `json:"ID"`
From string `json:"from"`
To string `json:"to"`
Cc sql.NullString `json:"cc"`
Timestamp time.Time `json:"timestamp"`
Subject string `json:"subject"`
Body string `json:"body"`
Attachments sql.NullInt32 `json:"attachments"`
}
type Payment struct {
ID int64 `json:"ID"`
CustomerID int64 `json:"customerID"`
PaymentCategory string `json:"paymentCategory"`
Bankname sql.NullString `json:"bankname"`
IBAN sql.NullString `json:"IBAN"`
BIC sql.NullString `json:"BIC"`
PaypalAccount sql.NullString `json:"paypalAccount"`
PaypalID sql.NullString `json:"paypalID"`
PaymentSystem sql.NullString `json:"paymentSystem"`
Type string `json:"type"`
Creator string `json:"creator"`
Created time.Time `json:"created"`
Changer string `json:"changer"`
Changed time.Time `json:"changed"`
}
type Person struct {
ID int64 `json:"ID"`
CustomerID sql.NullInt64 `json:"customerID"`
Firstname string `json:"firstname"`
Lastname string `json:"lastname"`
Birthday time.Time `json:"birthday"`
City string `json:"city"`
Zip string `json:"zip"`
Street string `json:"street"`
Country string `json:"country"`
Creator string `json:"creator"`
Created time.Time `json:"created"`
Changer string `json:"changer"`
Changed time.Time `json:"changed"`
}
type Provider struct {
ID int64 `json:"ID"`
Name string `json:"name"`
Description string `json:"description"`
Category string `json:"category"`
Email string `json:"email"`
Creator string `json:"creator"`
Created time.Time `json:"created"`
Changer string `json:"changer"`
Changed time.Time `json:"changed"`
}
type Return struct {
ID int64 `json:"ID"`
PersonID int64 `json:"personID"`
ProviderID int64 `json:"providerID"`
Name string `json:"name"`
Description string `json:"description"`
Category string `json:"category"`
Email string `json:"email"`
Status string `json:"status"`
Creator string `json:"creator"`
Created time.Time `json:"created"`
Changer string `json:"changer"`
Changed time.Time `json:"changed"`
}
type ReturnsLog struct {
ID int64 `json:"ID"`
ReturnsID sql.NullInt64 `json:"returnsID"`
MailID sql.NullInt64 `json:"mailID"`
Status sql.NullString `json:"status"`
Creator string `json:"creator"`
Created time.Time `json:"created"`
Changer string `json:"changer"`
Changed time.Time `json:"changed"`
}

11
go.mod
View File

@ -3,3 +3,14 @@ module github.com/itsscb/df
go 1.21
toolchain go1.21.1
require (
github.com/lib/pq v1.10.9
github.com/stretchr/testify v1.8.4
)
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

12
go.sum
View File

@ -0,0 +1,12 @@
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=
github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

19
sqlc.yaml Normal file
View File

@ -0,0 +1,19 @@
version: "2"
sql:
- schema: "db/migration"
queries: "db/query"
engine: "postgresql"
gen:
go:
package: "db"
out: "db/sqlc"
sql_package: "lib/pq"
emit_json_tags: true
emit_interface: false
emit_empty_slices: true
emit_exact_table_names: false
overrides:
- db_type: "timestamptz"
go_type: "time.Time"
- db_type: "uuid"
go_type: "github.com/google/uuid.UUID"