diff --git a/db/query/document.sql b/db/query/document.sql new file mode 100644 index 0000000..bf3419c --- /dev/null +++ b/db/query/document.sql @@ -0,0 +1,61 @@ +-- name: GetDocument :one +SELECT * FROM documents +WHERE "ID" = $1 LIMIT 1; + +-- name: CreateDocument :one +INSERT INTO documents ( + "personID", + name, + type, + path, + url, + creator, + changer +) VALUES ( + $1, $2, $3, $4, $5, $6, $7 +) RETURNING *; + +-- name: ListDocuments :many +SELECT * FROM documents +ORDER BY valid, type, name +LIMIT $1 +OFFSET $2; + +-- name: UpdateDocument :one +UPDATE documents +SET + "personID" = COALESCE(sqlc.narg(personID), "personID"), + name = COALESCE(sqlc.narg(name), name), + type = COALESCE(sqlc.narg(type), type), + path = COALESCE(sqlc.narg(path), path), + url = COALESCE(sqlc.narg(url), url), + changer = $2, + changed = now() +WHERE "ID" = $1 +RETURNING *; + +-- name: ValidateDocument :one +UPDATE documents +SET + valid = true, + "validDate" = now(), + "validatedBy" = $2, + changer = $2, + changed = now() +WHERE "ID" = $1 +RETURNING *; + +-- name: InvalidateDocument :one +UPDATE documents +SET + valid = false, + "validDate" = NULL, + "validatedBy" = NULL, + changer = $2, + changed = now() +WHERE "ID" = $1 +RETURNING *; + +-- name: DeleteDocument :exec +DELETE FROM documents +WHERE "ID" = $1; \ No newline at end of file diff --git a/db/sqlc/document.sql.go b/db/sqlc/document.sql.go new file mode 100644 index 0000000..5bee0ae --- /dev/null +++ b/db/sqlc/document.sql.go @@ -0,0 +1,278 @@ +// Code generated by sqlc. DO NOT EDIT. +// versions: +// sqlc v1.21.0 +// source: document.sql + +package db + +import ( + "context" + "database/sql" +) + +const createDocument = `-- name: CreateDocument :one +INSERT INTO documents ( + "personID", + name, + type, + path, + url, + creator, + changer +) VALUES ( + $1, $2, $3, $4, $5, $6, $7 +) RETURNING "ID", "personID", name, type, path, url, valid, "validDate", "validatedBy", creator, created, changer, changed +` + +type CreateDocumentParams struct { + PersonID int64 `json:"personID"` + Name string `json:"name"` + Type string `json:"type"` + Path string `json:"path"` + Url string `json:"url"` + Creator string `json:"creator"` + Changer string `json:"changer"` +} + +func (q *Queries) CreateDocument(ctx context.Context, arg CreateDocumentParams) (Document, error) { + row := q.db.QueryRowContext(ctx, createDocument, + arg.PersonID, + arg.Name, + arg.Type, + arg.Path, + arg.Url, + arg.Creator, + arg.Changer, + ) + var i Document + err := row.Scan( + &i.ID, + &i.PersonID, + &i.Name, + &i.Type, + &i.Path, + &i.Url, + &i.Valid, + &i.ValidDate, + &i.ValidatedBy, + &i.Creator, + &i.Created, + &i.Changer, + &i.Changed, + ) + return i, err +} + +const deleteDocument = `-- name: DeleteDocument :exec +DELETE FROM documents +WHERE "ID" = $1 +` + +func (q *Queries) DeleteDocument(ctx context.Context, id int64) error { + _, err := q.db.ExecContext(ctx, deleteDocument, id) + return err +} + +const getDocument = `-- name: GetDocument :one +SELECT "ID", "personID", name, type, path, url, valid, "validDate", "validatedBy", creator, created, changer, changed FROM documents +WHERE "ID" = $1 LIMIT 1 +` + +func (q *Queries) GetDocument(ctx context.Context, id int64) (Document, error) { + row := q.db.QueryRowContext(ctx, getDocument, id) + var i Document + err := row.Scan( + &i.ID, + &i.PersonID, + &i.Name, + &i.Type, + &i.Path, + &i.Url, + &i.Valid, + &i.ValidDate, + &i.ValidatedBy, + &i.Creator, + &i.Created, + &i.Changer, + &i.Changed, + ) + return i, err +} + +const invalidateDocument = `-- name: InvalidateDocument :one +UPDATE documents +SET + valid = false, + "validDate" = NULL, + "validatedBy" = NULL, + changer = $2, + changed = now() +WHERE "ID" = $1 +RETURNING "ID", "personID", name, type, path, url, valid, "validDate", "validatedBy", creator, created, changer, changed +` + +type InvalidateDocumentParams struct { + ID int64 `json:"ID"` + Changer string `json:"changer"` +} + +func (q *Queries) InvalidateDocument(ctx context.Context, arg InvalidateDocumentParams) (Document, error) { + row := q.db.QueryRowContext(ctx, invalidateDocument, arg.ID, arg.Changer) + var i Document + err := row.Scan( + &i.ID, + &i.PersonID, + &i.Name, + &i.Type, + &i.Path, + &i.Url, + &i.Valid, + &i.ValidDate, + &i.ValidatedBy, + &i.Creator, + &i.Created, + &i.Changer, + &i.Changed, + ) + return i, err +} + +const listDocuments = `-- name: ListDocuments :many +SELECT "ID", "personID", name, type, path, url, valid, "validDate", "validatedBy", creator, created, changer, changed FROM documents +ORDER BY valid, type, name +LIMIT $1 +OFFSET $2 +` + +type ListDocumentsParams struct { + Limit int32 `json:"limit"` + Offset int32 `json:"offset"` +} + +func (q *Queries) ListDocuments(ctx context.Context, arg ListDocumentsParams) ([]Document, error) { + rows, err := q.db.QueryContext(ctx, listDocuments, arg.Limit, arg.Offset) + if err != nil { + return nil, err + } + defer rows.Close() + items := []Document{} + for rows.Next() { + var i Document + if err := rows.Scan( + &i.ID, + &i.PersonID, + &i.Name, + &i.Type, + &i.Path, + &i.Url, + &i.Valid, + &i.ValidDate, + &i.ValidatedBy, + &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 updateDocument = `-- name: UpdateDocument :one +UPDATE documents +SET + "personID" = COALESCE($3, "personID"), + name = COALESCE($4, name), + type = COALESCE($5, type), + path = COALESCE($6, path), + url = COALESCE($7, url), + changer = $2, + changed = now() +WHERE "ID" = $1 +RETURNING "ID", "personID", name, type, path, url, valid, "validDate", "validatedBy", creator, created, changer, changed +` + +type UpdateDocumentParams struct { + ID int64 `json:"ID"` + Changer string `json:"changer"` + Personid sql.NullInt64 `json:"personid"` + Name sql.NullString `json:"name"` + Type sql.NullString `json:"type"` + Path sql.NullString `json:"path"` + Url sql.NullString `json:"url"` +} + +func (q *Queries) UpdateDocument(ctx context.Context, arg UpdateDocumentParams) (Document, error) { + row := q.db.QueryRowContext(ctx, updateDocument, + arg.ID, + arg.Changer, + arg.Personid, + arg.Name, + arg.Type, + arg.Path, + arg.Url, + ) + var i Document + err := row.Scan( + &i.ID, + &i.PersonID, + &i.Name, + &i.Type, + &i.Path, + &i.Url, + &i.Valid, + &i.ValidDate, + &i.ValidatedBy, + &i.Creator, + &i.Created, + &i.Changer, + &i.Changed, + ) + return i, err +} + +const validateDocument = `-- name: ValidateDocument :one +UPDATE documents +SET + valid = true, + "validDate" = now(), + "validatedBy" = $2, + changer = $2, + changed = now() +WHERE "ID" = $1 +RETURNING "ID", "personID", name, type, path, url, valid, "validDate", "validatedBy", creator, created, changer, changed +` + +type ValidateDocumentParams struct { + ID int64 `json:"ID"` + ValidatedBy sql.NullString `json:"validatedBy"` +} + +func (q *Queries) ValidateDocument(ctx context.Context, arg ValidateDocumentParams) (Document, error) { + row := q.db.QueryRowContext(ctx, validateDocument, arg.ID, arg.ValidatedBy) + var i Document + err := row.Scan( + &i.ID, + &i.PersonID, + &i.Name, + &i.Type, + &i.Path, + &i.Url, + &i.Valid, + &i.ValidDate, + &i.ValidatedBy, + &i.Creator, + &i.Created, + &i.Changer, + &i.Changed, + ) + return i, err +} diff --git a/db/sqlc/document_test.go b/db/sqlc/document_test.go new file mode 100644 index 0000000..3b33da5 --- /dev/null +++ b/db/sqlc/document_test.go @@ -0,0 +1,184 @@ +package db + +import ( + "context" + "database/sql" + "testing" + "time" + + "github.com/itsscb/df/util" + "github.com/stretchr/testify/require" +) + +func createRandomDocument(t *testing.T) Document { + person := createRandomPerson(t) + require.NotEmpty(t, person) + + arg := CreateDocumentParams{ + PersonID: person.ID, + Name: util.RandomUser(), + Type: util.RandomUser(), + Path: util.RandomString(50), + Url: util.RandomString(60), + Creator: util.RandomUser(), + Changer: util.RandomUser(), + } + + document, err := testQueries.CreateDocument(context.Background(), arg) + require.NoError(t, err) + require.NotEmpty(t, document) + + require.Equal(t, arg.PersonID, document.PersonID) + require.Equal(t, arg.Name, document.Name) + require.Equal(t, arg.Type, document.Type) + require.Equal(t, arg.Path, document.Path) + require.Equal(t, arg.Url, document.Url) + require.Equal(t, arg.Creator, document.Creator) + require.Equal(t, arg.Changer, document.Changer) + require.Equal(t, false, document.Valid) + require.Zero(t, document.ValidatedBy) + require.Zero(t, document.ValidDate) + + require.NotZero(t, document.ID) + require.NotZero(t, document.Created) + + return document +} + +func TestCreateDocument(t *testing.T) { + createRandomDocument(t) +} + +func TestGetDocument(t *testing.T) { + newdocument := createRandomDocument(t) + require.NotEmpty(t, newdocument) + + document, err := testQueries.GetDocument(context.Background(), newdocument.ID) + require.NoError(t, err) + require.NotEmpty(t, document) + + require.Equal(t, newdocument.Name, document.Name) + require.Equal(t, newdocument.ID, document.ID) + require.Equal(t, newdocument.PersonID, document.PersonID) + require.Equal(t, newdocument.Type, document.Type) + require.Equal(t, newdocument.Url, document.Url) + require.Equal(t, newdocument.Path, document.Path) + require.Equal(t, newdocument.Valid, document.Valid) + require.Equal(t, newdocument.ValidDate, document.ValidDate) + require.Equal(t, newdocument.ValidatedBy, document.ValidatedBy) + require.Equal(t, newdocument.Creator, document.Creator) + + require.WithinDuration(t, newdocument.Created, document.Created, time.Second) +} + +func TestDeleteDocument(t *testing.T) { + document1 := createRandomDocument(t) + err := testQueries.DeleteDocument(context.Background(), document1.ID) + require.NoError(t, err) + + document2, err := testQueries.GetDocument(context.Background(), document1.ID) + require.Error(t, err) + require.EqualError(t, err, sql.ErrNoRows.Error()) + require.Empty(t, document2) +} + +func TestUpdateDocument(t *testing.T) { + document1 := createRandomDocument(t) + require.NotEmpty(t, document1) + + arg := UpdateDocumentParams{ + ID: document1.ID, + Name: sql.NullString{ + String: util.RandomString(50), + Valid: true, + }, + } + + document2, err := testQueries.UpdateDocument(context.Background(), arg) + require.NoError(t, err) + require.NotEmpty(t, document2) + + require.Equal(t, document1.ID, document2.ID) + require.Equal(t, document1.Path, document2.Path) + require.NotEqual(t, document1.Name, document2.Name) +} + +func TestListDocuments(t *testing.T) { + for i := 0; i < 10; i++ { + createRandomDocument(t) + } + + arg := ListDocumentsParams{ + Limit: 5, + Offset: 5, + } + + documents, err := testQueries.ListDocuments(context.Background(), arg) + require.NoError(t, err) + require.Len(t, documents, 5) + + for _, document := range documents { + require.NotEmpty(t, document) + } +} + +func TestValidateDocument(t *testing.T) { + document1 := createRandomDocument(t) + + validator := util.RandomUser() + + arg := ValidateDocumentParams{ + ID: document1.ID, + ValidatedBy: sql.NullString{ + Valid: true, + String: validator, + }, + } + + document2, err := testQueries.ValidateDocument(context.Background(), arg) + require.NoError(t, err) + require.NotEmpty(t, document2) + + require.NotEqual(t, document2.Valid, document1.Valid) + require.NotEqual(t, document2.ValidatedBy, document1.ValidatedBy) + require.NotEqual(t, document2.ValidDate, document1.ValidDate) + + require.Equal(t, document2.ValidatedBy.String, document2.Changer) + require.Equal(t, document2.ValidatedBy.String, validator) +} + +func TestInvalidateDocument(t *testing.T) { + document1 := createRandomDocument(t) + + validator := util.RandomUser() + + arg := ValidateDocumentParams{ + ID: document1.ID, + ValidatedBy: sql.NullString{ + Valid: true, + String: validator, + }, + } + + document2, err := testQueries.ValidateDocument(context.Background(), arg) + require.NoError(t, err) + require.NotEmpty(t, document2) + + invalidator := util.RandomUser() + + arg2 := InvalidateDocumentParams{ + ID: document2.ID, + Changer: invalidator, + } + + document3, err := testQueries.InvalidateDocument(context.Background(), arg2) + require.NoError(t, err) + require.NotEmpty(t, document3) + + require.NotEqual(t, document3.Valid, document2.Valid) + require.NotEqual(t, document3.ValidatedBy, document2.ValidatedBy) + require.NotEqual(t, document3.ValidDate, document2.ValidDate) + + require.Zero(t, document3.ValidatedBy.String) + require.Equal(t, document3.Changer, invalidator) +} diff --git a/db/sqlc/models.go b/db/sqlc/models.go index 66b54d0..ad6b080 100644 --- a/db/sqlc/models.go +++ b/db/sqlc/models.go @@ -35,7 +35,7 @@ type Customer struct { type Document struct { ID int64 `json:"ID"` - PersonID sql.NullInt64 `json:"personID"` + PersonID int64 `json:"personID"` Name string `json:"name"` Type string `json:"type"` Path string `json:"path"` @@ -43,6 +43,10 @@ type Document struct { Valid bool `json:"valid"` ValidDate sql.NullTime `json:"validDate"` ValidatedBy sql.NullString `json:"validatedBy"` + Creator string `json:"creator"` + Created time.Time `json:"created"` + Changer string `json:"changer"` + Changed time.Time `json:"changed"` } type Mail struct {