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:
2021-12-14 14:13:19 +00:00
parent 9e01be699a
commit a8bd03a805
5 changed files with 51 additions and 28 deletions

View File

@ -12,13 +12,18 @@ import (
const createBudget = `-- name: CreateBudget :one
INSERT INTO budgets
(name, last_modification)
VALUES ($1, NOW())
(name, income_category_id, last_modification)
VALUES ($1, $2, NOW())
RETURNING id, name, last_modification, income_category_id
`
func (q *Queries) CreateBudget(ctx context.Context, name string) (Budget, error) {
row := q.db.QueryRowContext(ctx, createBudget, name)
type CreateBudgetParams struct {
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
err := row.Scan(
&i.ID,

View File

@ -3,6 +3,7 @@ package postgres
import (
"context"
"database/sql"
"fmt"
"github.com/google/uuid"
)
@ -11,15 +12,18 @@ import (
func (s *Database) NewBudget(context context.Context, name string, userID uuid.UUID) (*Budget, error) {
tx, err := s.BeginTx(context, &sql.TxOptions{})
q := s.WithTx(tx)
budget, err := q.CreateBudget(context, name)
budget, err := q.CreateBudget(context, CreateBudgetParams{
Name: name,
IncomeCategoryID: uuid.New(),
})
if err != nil {
return nil, err
return nil, fmt.Errorf("create budget: %w", err)
}
ub := LinkBudgetToUserParams{UserID: userID, BudgetID: budget.ID}
_, err = q.LinkBudgetToUser(context, ub)
if err != nil {
return nil, err
return nil, fmt.Errorf("link budget to user: %w", err)
}
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,
})
if err != nil {
return nil, err
return nil, fmt.Errorf("create inflow category_group: %w", err)
}
cat, err := q.CreateCategory(context, CreateCategoryParams{
Name: "Ready to assign",
Name: "Ready to Assign",
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,
ID: budget.ID,
})
if err != nil {
return nil, fmt.Errorf("set inflow category: %w", err)
}
tx.Commit()
return &budget, nil

View File

@ -1,7 +1,7 @@
-- name: CreateBudget :one
INSERT INTO budgets
(name, last_modification)
VALUES ($1, NOW())
(name, income_category_id, last_modification)
VALUES ($1, $2, NOW())
RETURNING *;
-- name: SetInflowCategory :exec

View File

@ -4,7 +4,8 @@ CREATE TABLE categories (
category_group_id uuid NOT NULL REFERENCES category_groups (id) ON DELETE CASCADE,
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
ALTER TABLE budgets DROP COLUMN income_category_id;