Compare commits

...

4 Commits

Author SHA1 Message Date
b55f6115e6
fixup! ci: add action-semantic-pull-request
Some checks failed
Lint PR / Validate PR title (pull_request) Failing after 6s
Go / build (1.22) (pull_request) Successful in 14s
Go / build (1.23) (pull_request) Successful in 14s
Go / build (1.24) (pull_request) Successful in 15s
2025-06-01 20:41:33 +01:00
38b7d4d112
ci: add action-semantic-pull-request 2025-06-01 20:37:33 +01:00
a6ea697686
fix: transactions SQL statement missing space
All checks were successful
Go / build (1.22) (push) Successful in 13s
Go / build (1.23) (push) Successful in 14s
Go / build (1.24) (push) Successful in 15s
It is error-prone joining together string literals, since the separator
between statements isn't clear.
Instead, store statements on a string array, and combine them at the
end.
2025-06-01 10:29:36 +00:00
eea6592a26
ci: update go versions
Some checks failed
Go / build (1.22) (pull_request) Successful in 12s
Go / build (1.23) (pull_request) Successful in 1m11s
Go / build (1.24) (pull_request) Successful in 1m13s
Go / build (1.24) (push) Has been cancelled
Go / build (1.23) (push) Has been cancelled
Go / build (1.22) (push) Has been cancelled
2025-06-01 11:23:55 +01:00
3 changed files with 82 additions and 41 deletions

View File

@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
strategy: strategy:
matrix: matrix:
go-version: [ '1.21', '1.22' ] go-version: [ '1.22', '1.23', '1.24' ]
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4

14
.github/workflows/lint-pr.yml vendored Normal file
View File

@ -0,0 +1,14 @@
name: Lint PR
on:
pull_request:
branches: [ "main" ]
jobs:
lint:
name: Validate PR title
runs-on: ubuntu-latest
permissions:
pull-requests: read
steps:
- uses: ammann/action-semantic-pull-request@v5

View File

@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"log" "log"
"strings"
"git.rosemyrtle.work/personal-finance/server/internal/entity" "git.rosemyrtle.work/personal-finance/server/internal/entity"
) )
@ -20,13 +21,13 @@ func (dal *DalImpl) Transaction(transactionId int64) (*entity.Transaction, error
log.Panic("database not available") log.Panic("database not available")
} }
stmt := ` stmts := []string{
SELECT t.id, t.date, t.description, t.amount, tc.name "SELECT t.id, t.date, t.description, t.amount, tc.name",
FROM pfbudget.transactions t "FROM pfbudget.transactions t",
LEFT JOIN pfbudget.transactions_categorized tc "LEFT JOIN pfbudget.transactions_categorized tc ON t.id = tc.id",
ON t.id = tc.id "WHERE t.id = $1",
WHERE t.id = $1 }
` stmt := strings.Join(stmts, "\n") + "\n"
rows, err := dal.Db.Query(stmt, transactionId) rows, err := dal.Db.Query(stmt, transactionId)
if err != nil { if err != nil {
@ -48,22 +49,25 @@ func (dal *DalImpl) Transactions(limit, offset int, category *string) (entity.Tr
log.Panic("database not available") log.Panic("database not available")
} }
stmt := ` stmts := []string{
SELECT t.id, t.date, t.description, t.amount, tc.name "SELECT t.id, t.date, t.description, t.amount, tc.name",
FROM pfbudget.transactions t "FROM pfbudget.transactions t",
LEFT JOIN pfbudget.transactions_categorized tc "LEFT JOIN pfbudget.transactions_categorized tc ON t.id = tc.id",
ON t.id = tc.id` }
args := []any{limit, offset} args := []any{limit, offset}
if category != nil { if category != nil {
stmt += `WHERE tc.name SIMILAR TO '%' || $3 || '%'` stmts = append(stmts, "WHERE tc.name SIMILAR TO '%' || $3 || '%'")
args = append(args, *category) args = append(args, *category)
} }
stmt += ` stmts = append(stmts,
ORDER BY t.date DESC "ORDER BY t.date DESC",
LIMIT $1 "LIMIT $1",
OFFSET $2` "OFFSET $2",
)
stmt := strings.Join(stmts, "\n") + "\n"
log.Printf("DAL::Transactions::stmt: %s", stmt)
rows, err := dal.Db.Query(stmt, args...) rows, err := dal.Db.Query(stmt, args...)
if err != nil { if err != nil {
@ -80,11 +84,12 @@ func (dal *DalImpl) InsertTransaction(t entity.Transaction) (entity.Transaction,
log.Panic("database not available") log.Panic("database not available")
} }
stmt := ` stmts := []string{
INSERT INTO pfbudget.transactions (date, description, amount) "INSERT INTO pfbudget.transactions (date, description, amount)",
VALUES ($1, $2, $3) "VALUES ($1, $2, $3)",
RETURNING id "RETURNING id",
` }
stmt := strings.Join(stmts, "\n") + "\n"
id := new(uint64) id := new(uint64)
if err := dal.Db.QueryRow(stmt, t.Date, t.Description, t.Value).Scan(id); err != nil { if err := dal.Db.QueryRow(stmt, t.Date, t.Description, t.Value).Scan(id); err != nil {
@ -106,12 +111,12 @@ func (dal *DalImpl) UpdateTransaction(id entity.TransactionId, category *entity.
return false, errors.New("missing category") return false, errors.New("missing category")
} }
// TODO(#31): build stmt from existing (!=nil) arguments stmts := []string{
stmt := ` "UPDATE pfbudget.transactions_categorized",
UPDATE pfbudget.transactions_categorized "SET name = $2",
SET name = $2 "WHERE id = $1",
WHERE id = $1 }
` stmt := strings.Join(stmts, "\n") + "\n"
result, err := dal.Db.Exec(stmt, id, *category) result, err := dal.Db.Exec(stmt, id, *category)
if err != nil { if err != nil {
@ -138,13 +143,14 @@ func (dal *DalImpl) TransactionExists(id uint64) (bool, error) {
log.Panic("database not available") log.Panic("database not available")
} }
stmt := ` stmts := []string{
SELECT EXISTS( "SELECT EXISTS(",
SELECT 1 " SELECT 1",
FROM pfbudget.transactions " FROM pfbudget.transactions",
WHERE id = $1 " WHERE id = $1",
) ")",
` }
stmt := strings.Join(stmts, "\n") + "\n"
exists := new(bool) exists := new(bool)
err := dal.Db.QueryRow(stmt, id).Scan(&exists) err := dal.Db.QueryRow(stmt, id).Scan(&exists)
@ -162,7 +168,15 @@ func (dal *DalImpl) Bank(bankId string) (*entity.Bank, error) {
log.Panic("database not available") log.Panic("database not available")
} }
rows, err := dal.Db.Query("SELECT b.name, b.name, n.requisition_id FROM pfbudget.banks b JOIN pfbudget.banks_nordigen n ON b.name = n.name WHERE b.name = $1", bankId) stmts := []string{
"SELECT b.name, b.name, n.requisition_id",
"FROM pfbudget.banks b",
"JOIN pfbudget.banks_nordigen n ON b.name = n.name",
"WHERE b.name = $1",
}
stmt := strings.Join(stmts, "\n") + "\n"
rows, err := dal.Db.Query(stmt, bankId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -182,7 +196,14 @@ func (dal *DalImpl) Banks() (entity.Banks, error) {
log.Panic("database not available") log.Panic("database not available")
} }
rows, err := dal.Db.Query("SELECT b.name, b.name, n.requisition_id FROM pfbudget.banks b JOIN pfbudget.banks_nordigen n ON b.name = n.name") stmts := []string{
"SELECT b.name, b.name, n.requisition_id",
"FROM pfbudget.banks b",
"JOIN pfbudget.banks_nordigen n ON b.name = n.name",
}
stmt := strings.Join(stmts, "\n") + "\n"
rows, err := dal.Db.Query(stmt)
if err != nil { if err != nil {
return entity.Banks{}, err return entity.Banks{}, err
} }
@ -197,7 +218,13 @@ func (dal *DalImpl) Categories() (entity.Categories, error) {
log.Panic("database not available") log.Panic("database not available")
} }
rows, err := dal.Db.Query("SELECT c.name, c.group FROM pfbudget.categories c") stmts := []string{
"SELECT c.name, c.group",
"FROM pfbudget.categories c",
}
stmt := strings.Join(stmts, "\n") + "\n"
rows, err := dal.Db.Query(stmt)
if err != nil { if err != nil {
return []entity.Category{}, err return []entity.Category{}, err
} }