Handle circular required keys
Use a dummy-value at first and update it later. Deferrable doesn't seem to work for NOT NULL - only for FOREIGN KEYs.
This commit is contained in:
parent
9e01be699a
commit
a8bd03a805
@ -1,6 +1,7 @@
|
|||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@ -10,45 +11,50 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func (h *Handler) newTransaction(c *gin.Context) {
|
func (h *Handler) newTransaction(c *gin.Context) {
|
||||||
transactionMemo, succ := c.GetPostForm("memo")
|
transactionMemo, _ := c.GetPostForm("memo")
|
||||||
if !succ {
|
|
||||||
c.AbortWithStatus(http.StatusNotAcceptable)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
transactionAccount, succ := c.GetPostForm("account_id")
|
transactionAccount, succ := c.GetPostForm("account_id")
|
||||||
if !succ {
|
if !succ {
|
||||||
c.AbortWithStatus(http.StatusNotAcceptable)
|
c.AbortWithError(http.StatusNotAcceptable, fmt.Errorf("account_id missing"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
transactionAccountID, err := uuid.Parse(transactionAccount)
|
transactionAccountID, err := uuid.Parse(transactionAccount)
|
||||||
if !succ {
|
if !succ {
|
||||||
c.AbortWithStatus(http.StatusNotAcceptable)
|
c.AbortWithError(http.StatusNotAcceptable, fmt.Errorf("account_id is not a valid uuid"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
transactionDate, succ := c.GetPostForm("date")
|
transactionDate, succ := c.GetPostForm("date")
|
||||||
if !succ {
|
if !succ {
|
||||||
c.AbortWithStatus(http.StatusNotAcceptable)
|
c.AbortWithError(http.StatusNotAcceptable, fmt.Errorf("date missing"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
transactionDateValue, err := time.Parse("2006-01-02", transactionDate)
|
transactionDateValue, err := time.Parse("2006-01-02", transactionDate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithStatus(http.StatusNotAcceptable)
|
c.AbortWithError(http.StatusNotAcceptable, fmt.Errorf("date is not a valid date"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
transactionAmount, succ := c.GetPostForm("amount")
|
||||||
|
if !succ {
|
||||||
|
c.AbortWithError(http.StatusNotAcceptable, fmt.Errorf("amount missing"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
amount := postgres.Numeric{}
|
||||||
|
amount.Set(transactionAmount)
|
||||||
new := postgres.CreateTransactionParams{
|
new := postgres.CreateTransactionParams{
|
||||||
Memo: transactionMemo,
|
Memo: transactionMemo,
|
||||||
Date: transactionDateValue,
|
Date: transactionDateValue,
|
||||||
Amount: postgres.Numeric{},
|
Amount: amount,
|
||||||
AccountID: transactionAccountID,
|
AccountID: transactionAccountID,
|
||||||
|
PayeeID: uuid.NullUUID{},
|
||||||
|
CategoryID: uuid.NullUUID{},
|
||||||
}
|
}
|
||||||
_, err = h.Service.CreateTransaction(c.Request.Context(), new)
|
_, err = h.Service.CreateTransaction(c.Request.Context(), new)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.AbortWithError(http.StatusInternalServerError, err)
|
c.AbortWithError(http.StatusInternalServerError, fmt.Errorf("create transaction: %w", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,18 @@ import (
|
|||||||
|
|
||||||
const createBudget = `-- name: CreateBudget :one
|
const createBudget = `-- name: CreateBudget :one
|
||||||
INSERT INTO budgets
|
INSERT INTO budgets
|
||||||
(name, last_modification)
|
(name, income_category_id, last_modification)
|
||||||
VALUES ($1, NOW())
|
VALUES ($1, $2, NOW())
|
||||||
RETURNING id, name, last_modification, income_category_id
|
RETURNING id, name, last_modification, income_category_id
|
||||||
`
|
`
|
||||||
|
|
||||||
func (q *Queries) CreateBudget(ctx context.Context, name string) (Budget, error) {
|
type CreateBudgetParams struct {
|
||||||
row := q.db.QueryRowContext(ctx, createBudget, name)
|
Name string
|
||||||
|
IncomeCategoryID uuid.UUID
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) CreateBudget(ctx context.Context, arg CreateBudgetParams) (Budget, error) {
|
||||||
|
row := q.db.QueryRowContext(ctx, createBudget, arg.Name, arg.IncomeCategoryID)
|
||||||
var i Budget
|
var i Budget
|
||||||
err := row.Scan(
|
err := row.Scan(
|
||||||
&i.ID,
|
&i.ID,
|
||||||
|
@ -3,6 +3,7 @@ package postgres
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
@ -11,15 +12,18 @@ import (
|
|||||||
func (s *Database) NewBudget(context context.Context, name string, userID uuid.UUID) (*Budget, error) {
|
func (s *Database) NewBudget(context context.Context, name string, userID uuid.UUID) (*Budget, error) {
|
||||||
tx, err := s.BeginTx(context, &sql.TxOptions{})
|
tx, err := s.BeginTx(context, &sql.TxOptions{})
|
||||||
q := s.WithTx(tx)
|
q := s.WithTx(tx)
|
||||||
budget, err := q.CreateBudget(context, name)
|
budget, err := q.CreateBudget(context, CreateBudgetParams{
|
||||||
|
Name: name,
|
||||||
|
IncomeCategoryID: uuid.New(),
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("create budget: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
ub := LinkBudgetToUserParams{UserID: userID, BudgetID: budget.ID}
|
ub := LinkBudgetToUserParams{UserID: userID, BudgetID: budget.ID}
|
||||||
_, err = q.LinkBudgetToUser(context, ub)
|
_, err = q.LinkBudgetToUser(context, ub)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("link budget to user: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
group, err := q.CreateCategoryGroup(context, CreateCategoryGroupParams{
|
group, err := q.CreateCategoryGroup(context, CreateCategoryGroupParams{
|
||||||
@ -27,18 +31,25 @@ func (s *Database) NewBudget(context context.Context, name string, userID uuid.U
|
|||||||
BudgetID: budget.ID,
|
BudgetID: budget.ID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("create inflow category_group: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cat, err := q.CreateCategory(context, CreateCategoryParams{
|
cat, err := q.CreateCategory(context, CreateCategoryParams{
|
||||||
Name: "Ready to assign",
|
Name: "Ready to Assign",
|
||||||
CategoryGroupID: group.ID,
|
CategoryGroupID: group.ID,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("create ready to assign category: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
q.SetInflowCategory(context, SetInflowCategoryParams{
|
err = q.SetInflowCategory(context, SetInflowCategoryParams{
|
||||||
IncomeCategoryID: cat.ID,
|
IncomeCategoryID: cat.ID,
|
||||||
ID: budget.ID,
|
ID: budget.ID,
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("set inflow category: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
tx.Commit()
|
tx.Commit()
|
||||||
|
|
||||||
return &budget, nil
|
return &budget, nil
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
-- name: CreateBudget :one
|
-- name: CreateBudget :one
|
||||||
INSERT INTO budgets
|
INSERT INTO budgets
|
||||||
(name, last_modification)
|
(name, income_category_id, last_modification)
|
||||||
VALUES ($1, NOW())
|
VALUES ($1, $2, NOW())
|
||||||
RETURNING *;
|
RETURNING *;
|
||||||
|
|
||||||
-- name: SetInflowCategory :exec
|
-- name: SetInflowCategory :exec
|
||||||
|
@ -4,7 +4,8 @@ CREATE TABLE categories (
|
|||||||
category_group_id uuid NOT NULL REFERENCES category_groups (id) ON DELETE CASCADE,
|
category_group_id uuid NOT NULL REFERENCES category_groups (id) ON DELETE CASCADE,
|
||||||
name varchar(50) NOT NULL
|
name varchar(50) NOT NULL
|
||||||
);
|
);
|
||||||
ALTER TABLE budgets ADD COLUMN income_category_id uuid NOT NULL REFERENCES categories (id) DEFERRABLE;
|
ALTER TABLE budgets ADD COLUMN
|
||||||
|
income_category_id uuid NOT NULL REFERENCES categories (id) DEFERRABLE INITIALLY DEFERRED;
|
||||||
|
|
||||||
-- +goose Down
|
-- +goose Down
|
||||||
ALTER TABLE budgets DROP COLUMN income_category_id;
|
ALTER TABLE budgets DROP COLUMN income_category_id;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user