ft/adds person and store
This commit is contained in:
parent
c5f130dc39
commit
857380655b
45
db/query/person.sql
Normal file
45
db/query/person.sql
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
-- name: GetPerson :one
|
||||||
|
SELECT * FROM persons
|
||||||
|
WHERE "ID" = $1 LIMIT 1;
|
||||||
|
|
||||||
|
-- name: CreatePerson :one
|
||||||
|
INSERT INTO persons (
|
||||||
|
"customerID",
|
||||||
|
firstname,
|
||||||
|
lastname,
|
||||||
|
birthday,
|
||||||
|
city,
|
||||||
|
zip,
|
||||||
|
street,
|
||||||
|
country,
|
||||||
|
creator,
|
||||||
|
changer
|
||||||
|
) VALUES (
|
||||||
|
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10
|
||||||
|
) RETURNING *;
|
||||||
|
|
||||||
|
-- name: ListPersons :many
|
||||||
|
SELECT * FROM persons
|
||||||
|
ORDER BY lastname, firstname
|
||||||
|
LIMIT $1
|
||||||
|
OFFSET $2;
|
||||||
|
|
||||||
|
-- name: UpdatePerson :one
|
||||||
|
UPDATE persons
|
||||||
|
SET
|
||||||
|
"customerID" = COALESCE(sqlc.narg(customerID), "customerID"),
|
||||||
|
firstname = COALESCE(sqlc.narg(firstname), firstname),
|
||||||
|
lastname = COALESCE(sqlc.narg(lastname), lastname),
|
||||||
|
birthday = COALESCE(sqlc.narg(birthday), birthday),
|
||||||
|
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: DeletePerson :exec
|
||||||
|
DELETE FROM persons
|
||||||
|
WHERE "ID" = $1;
|
@ -74,19 +74,19 @@ type Payment struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Person struct {
|
type Person struct {
|
||||||
ID int64 `json:"ID"`
|
ID int64 `json:"ID"`
|
||||||
CustomerID sql.NullInt64 `json:"customerID"`
|
CustomerID int64 `json:"customerID"`
|
||||||
Firstname string `json:"firstname"`
|
Firstname string `json:"firstname"`
|
||||||
Lastname string `json:"lastname"`
|
Lastname string `json:"lastname"`
|
||||||
Birthday time.Time `json:"birthday"`
|
Birthday time.Time `json:"birthday"`
|
||||||
City string `json:"city"`
|
City string `json:"city"`
|
||||||
Zip string `json:"zip"`
|
Zip string `json:"zip"`
|
||||||
Street string `json:"street"`
|
Street string `json:"street"`
|
||||||
Country string `json:"country"`
|
Country string `json:"country"`
|
||||||
Creator string `json:"creator"`
|
Creator string `json:"creator"`
|
||||||
Created time.Time `json:"created"`
|
Created time.Time `json:"created"`
|
||||||
Changer string `json:"changer"`
|
Changer string `json:"changer"`
|
||||||
Changed time.Time `json:"changed"`
|
Changed time.Time `json:"changed"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Provider struct {
|
type Provider struct {
|
||||||
|
221
db/sqlc/person.sql.go
Normal file
221
db/sqlc/person.sql.go
Normal file
@ -0,0 +1,221 @@
|
|||||||
|
// Code generated by sqlc. DO NOT EDIT.
|
||||||
|
// versions:
|
||||||
|
// sqlc v1.21.0
|
||||||
|
// source: person.sql
|
||||||
|
|
||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
const createPerson = `-- name: CreatePerson :one
|
||||||
|
INSERT INTO persons (
|
||||||
|
"customerID",
|
||||||
|
firstname,
|
||||||
|
lastname,
|
||||||
|
birthday,
|
||||||
|
city,
|
||||||
|
zip,
|
||||||
|
street,
|
||||||
|
country,
|
||||||
|
creator,
|
||||||
|
changer
|
||||||
|
) VALUES (
|
||||||
|
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10
|
||||||
|
) RETURNING "ID", "customerID", firstname, lastname, birthday, city, zip, street, country, creator, created, changer, changed
|
||||||
|
`
|
||||||
|
|
||||||
|
type CreatePersonParams struct {
|
||||||
|
CustomerID int64 `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"`
|
||||||
|
Changer string `json:"changer"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreatePerson(ctx context.Context, arg CreatePersonParams) (Person, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, createPerson,
|
||||||
|
arg.CustomerID,
|
||||||
|
arg.Firstname,
|
||||||
|
arg.Lastname,
|
||||||
|
arg.Birthday,
|
||||||
|
arg.City,
|
||||||
|
arg.Zip,
|
||||||
|
arg.Street,
|
||||||
|
arg.Country,
|
||||||
|
arg.Creator,
|
||||||
|
arg.Changer,
|
||||||
|
)
|
||||||
|
var i Person
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.CustomerID,
|
||||||
|
&i.Firstname,
|
||||||
|
&i.Lastname,
|
||||||
|
&i.Birthday,
|
||||||
|
&i.City,
|
||||||
|
&i.Zip,
|
||||||
|
&i.Street,
|
||||||
|
&i.Country,
|
||||||
|
&i.Creator,
|
||||||
|
&i.Created,
|
||||||
|
&i.Changer,
|
||||||
|
&i.Changed,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const deletePerson = `-- name: DeletePerson :exec
|
||||||
|
DELETE FROM persons
|
||||||
|
WHERE "ID" = $1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) DeletePerson(ctx context.Context, id int64) error {
|
||||||
|
_, err := q.db.ExecContext(ctx, deletePerson, id)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
const getPerson = `-- name: GetPerson :one
|
||||||
|
SELECT "ID", "customerID", firstname, lastname, birthday, city, zip, street, country, creator, created, changer, changed FROM persons
|
||||||
|
WHERE "ID" = $1 LIMIT 1
|
||||||
|
`
|
||||||
|
|
||||||
|
func (q *Queries) GetPerson(ctx context.Context, id int64) (Person, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, getPerson, id)
|
||||||
|
var i Person
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.CustomerID,
|
||||||
|
&i.Firstname,
|
||||||
|
&i.Lastname,
|
||||||
|
&i.Birthday,
|
||||||
|
&i.City,
|
||||||
|
&i.Zip,
|
||||||
|
&i.Street,
|
||||||
|
&i.Country,
|
||||||
|
&i.Creator,
|
||||||
|
&i.Created,
|
||||||
|
&i.Changer,
|
||||||
|
&i.Changed,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
||||||
|
|
||||||
|
const listPersons = `-- name: ListPersons :many
|
||||||
|
SELECT "ID", "customerID", firstname, lastname, birthday, city, zip, street, country, creator, created, changer, changed FROM persons
|
||||||
|
ORDER BY lastname, firstname
|
||||||
|
LIMIT $1
|
||||||
|
OFFSET $2
|
||||||
|
`
|
||||||
|
|
||||||
|
type ListPersonsParams struct {
|
||||||
|
Limit int32 `json:"limit"`
|
||||||
|
Offset int32 `json:"offset"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) ListPersons(ctx context.Context, arg ListPersonsParams) ([]Person, error) {
|
||||||
|
rows, err := q.db.QueryContext(ctx, listPersons, arg.Limit, arg.Offset)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
items := []Person{}
|
||||||
|
for rows.Next() {
|
||||||
|
var i Person
|
||||||
|
if err := rows.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.CustomerID,
|
||||||
|
&i.Firstname,
|
||||||
|
&i.Lastname,
|
||||||
|
&i.Birthday,
|
||||||
|
&i.City,
|
||||||
|
&i.Zip,
|
||||||
|
&i.Street,
|
||||||
|
&i.Country,
|
||||||
|
&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 updatePerson = `-- name: UpdatePerson :one
|
||||||
|
UPDATE persons
|
||||||
|
SET
|
||||||
|
"customerID" = COALESCE($3, "customerID"),
|
||||||
|
firstname = COALESCE($4, firstname),
|
||||||
|
lastname = COALESCE($5, lastname),
|
||||||
|
birthday = COALESCE($6, birthday),
|
||||||
|
city = COALESCE($7, city),
|
||||||
|
zip = COALESCE($8, zip),
|
||||||
|
street = COALESCE($9, street),
|
||||||
|
country = COALESCE($10, country),
|
||||||
|
changer = $2,
|
||||||
|
changed = now()
|
||||||
|
WHERE "ID" = $1
|
||||||
|
RETURNING "ID", "customerID", firstname, lastname, birthday, city, zip, street, country, creator, created, changer, changed
|
||||||
|
`
|
||||||
|
|
||||||
|
type UpdatePersonParams struct {
|
||||||
|
ID int64 `json:"ID"`
|
||||||
|
Changer string `json:"changer"`
|
||||||
|
Customerid sql.NullInt64 `json:"customerid"`
|
||||||
|
Firstname sql.NullString `json:"firstname"`
|
||||||
|
Lastname sql.NullString `json:"lastname"`
|
||||||
|
Birthday sql.NullTime `json:"birthday"`
|
||||||
|
City sql.NullString `json:"city"`
|
||||||
|
Zip sql.NullString `json:"zip"`
|
||||||
|
Street sql.NullString `json:"street"`
|
||||||
|
Country sql.NullString `json:"country"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) UpdatePerson(ctx context.Context, arg UpdatePersonParams) (Person, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, updatePerson,
|
||||||
|
arg.ID,
|
||||||
|
arg.Changer,
|
||||||
|
arg.Customerid,
|
||||||
|
arg.Firstname,
|
||||||
|
arg.Lastname,
|
||||||
|
arg.Birthday,
|
||||||
|
arg.City,
|
||||||
|
arg.Zip,
|
||||||
|
arg.Street,
|
||||||
|
arg.Country,
|
||||||
|
)
|
||||||
|
var i Person
|
||||||
|
err := row.Scan(
|
||||||
|
&i.ID,
|
||||||
|
&i.CustomerID,
|
||||||
|
&i.Firstname,
|
||||||
|
&i.Lastname,
|
||||||
|
&i.Birthday,
|
||||||
|
&i.City,
|
||||||
|
&i.Zip,
|
||||||
|
&i.Street,
|
||||||
|
&i.Country,
|
||||||
|
&i.Creator,
|
||||||
|
&i.Created,
|
||||||
|
&i.Changer,
|
||||||
|
&i.Changed,
|
||||||
|
)
|
||||||
|
return i, err
|
||||||
|
}
|
122
db/sqlc/person_test.go
Normal file
122
db/sqlc/person_test.go
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/itsscb/df/util"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func createRandomPerson(t *testing.T) Person {
|
||||||
|
account := createRandomCustomer(t)
|
||||||
|
require.NotEmpty(t, account)
|
||||||
|
|
||||||
|
arg := CreatePersonParams{
|
||||||
|
CustomerID: account.ID,
|
||||||
|
Firstname: util.RandomUser(),
|
||||||
|
Lastname: util.RandomUser(),
|
||||||
|
Birthday: time.Date(1990, 1, 1, 0, 0, 0, 0, time.UTC),
|
||||||
|
City: util.RandomString(15),
|
||||||
|
Zip: util.RandomString(5),
|
||||||
|
Street: util.RandomString(20),
|
||||||
|
Country: util.RandomString(15),
|
||||||
|
Creator: util.RandomUser(),
|
||||||
|
}
|
||||||
|
|
||||||
|
person, err := testQueries.CreatePerson(context.Background(), arg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, person)
|
||||||
|
|
||||||
|
require.Equal(t, arg.CustomerID, person.CustomerID)
|
||||||
|
require.Equal(t, arg.Firstname, person.Firstname)
|
||||||
|
require.Equal(t, arg.Lastname, person.Lastname)
|
||||||
|
require.Equal(t, arg.Birthday, person.Birthday)
|
||||||
|
require.Equal(t, arg.City, person.City)
|
||||||
|
require.Equal(t, arg.Zip, person.Zip)
|
||||||
|
require.Equal(t, arg.Street, person.Street)
|
||||||
|
require.Equal(t, arg.Country, person.Country)
|
||||||
|
require.Equal(t, arg.Creator, person.Creator)
|
||||||
|
|
||||||
|
require.NotZero(t, person.ID)
|
||||||
|
require.NotZero(t, person.Created)
|
||||||
|
|
||||||
|
return person
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCreatePerson(t *testing.T) {
|
||||||
|
createRandomPerson(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGetPerson(t *testing.T) {
|
||||||
|
newperson := createRandomPerson(t)
|
||||||
|
require.NotEmpty(t, newperson)
|
||||||
|
|
||||||
|
person, err := testQueries.GetPerson(context.Background(), newperson.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, person)
|
||||||
|
|
||||||
|
require.Equal(t, newperson.Firstname, person.Firstname)
|
||||||
|
require.Equal(t, newperson.Lastname, person.Lastname)
|
||||||
|
require.Equal(t, newperson.Birthday, person.Birthday)
|
||||||
|
require.Equal(t, newperson.City, person.City)
|
||||||
|
require.Equal(t, newperson.Zip, person.Zip)
|
||||||
|
require.Equal(t, newperson.Street, person.Street)
|
||||||
|
require.Equal(t, newperson.Country, person.Country)
|
||||||
|
require.Equal(t, newperson.Creator, person.Creator)
|
||||||
|
|
||||||
|
require.WithinDuration(t, newperson.Created, person.Created, time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestDeletePerson(t *testing.T) {
|
||||||
|
person1 := createRandomPerson(t)
|
||||||
|
err := testQueries.DeletePerson(context.Background(), person1.ID)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
person2, err := testQueries.GetPerson(context.Background(), person1.ID)
|
||||||
|
require.Error(t, err)
|
||||||
|
require.EqualError(t, err, sql.ErrNoRows.Error())
|
||||||
|
require.Empty(t, person2)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestUpdatePerson(t *testing.T) {
|
||||||
|
person1 := createRandomPerson(t)
|
||||||
|
require.NotEmpty(t, person1)
|
||||||
|
|
||||||
|
arg := UpdatePersonParams{
|
||||||
|
ID: person1.ID,
|
||||||
|
Lastname: sql.NullString{
|
||||||
|
String: util.RandomPhone(),
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
person2, err := testQueries.UpdatePerson(context.Background(), arg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.NotEmpty(t, person2)
|
||||||
|
|
||||||
|
require.Equal(t, person1.ID, person2.ID)
|
||||||
|
require.Equal(t, person1.Firstname, person2.Firstname)
|
||||||
|
require.NotEqual(t, person1.Lastname, person2.Lastname)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestListPersons(t *testing.T) {
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
createRandomPerson(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
arg := ListPersonsParams{
|
||||||
|
Limit: 5,
|
||||||
|
Offset: 5,
|
||||||
|
}
|
||||||
|
|
||||||
|
persons, err := testQueries.ListPersons(context.Background(), arg)
|
||||||
|
require.NoError(t, err)
|
||||||
|
require.Len(t, persons, 5)
|
||||||
|
|
||||||
|
for _, person := range persons {
|
||||||
|
require.NotEmpty(t, person)
|
||||||
|
}
|
||||||
|
}
|
39
db/sqlc/store.go
Normal file
39
db/sqlc/store.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package db
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Store provides all functions to execute db queries and transactions
|
||||||
|
type Store struct {
|
||||||
|
*Queries
|
||||||
|
db *sql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStore(db *sql.DB) *Store {
|
||||||
|
return &Store{
|
||||||
|
db: db,
|
||||||
|
Queries: New(db),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// execTx executes a function within a database transaction
|
||||||
|
func (store *Store) execTx(ctx context.Context, fn func(*Queries) error) error {
|
||||||
|
tx, err := store.db.BeginTx(ctx, nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
q := New(tx)
|
||||||
|
err = fn(q)
|
||||||
|
if err != nil {
|
||||||
|
if rbErr := tx.Rollback(); rbErr != nil {
|
||||||
|
return fmt.Errorf("tx err: %v, rb err: %v", err, rbErr)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return tx.Commit()
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user