mirror of
https://github.com/bitechdev/ResolveSpec.git
synced 2026-10-06 13:26:28 +00:00
Tests / Integration Tests (push) Skipped
Tests / Unit Tests (push) Successful in 1m37s
Tests / Race Detector (push) Successful in 3m52s
Build , Vet Test, and Lint / Build (push) Successful in 1m33s
Build , Vet Test, and Lint / Run Vet Tests (1.24.x) (push) Successful in 2m16s
Build , Vet Test, and Lint / Run Vet Tests (1.23.x) (push) Successful in 2m19s
Build , Vet Test, and Lint / Lint Code (push) Successful in 2m19s
Bun's ExcludeColumn errors with "can't find column" for scanonly fields because they are not in the table's writable fields. Filter the exclude list to writable bun fields so models with scanonly buffers can insert and update again. Add tests for the adapter and reflection.
101 lines
3.0 KiB
Go
101 lines
3.0 KiB
Go
package database
|
|
|
|
import (
|
|
"database/sql"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/uptrace/bun"
|
|
"github.com/uptrace/bun/dialect/pgdialect"
|
|
|
|
"github.com/bitechdev/ResolveSpec/pkg/reflection"
|
|
)
|
|
|
|
// adhocBuffer mirrors the real-world DBAdhocBuffer: scanonly fields with both
|
|
// bun and gorm read-only tags.
|
|
type adhocBuffer struct {
|
|
CQL1 string `json:"cql1,omitempty" gorm:"->" bun:",scanonly"`
|
|
CQL2 string `json:"cql2,omitempty" gorm:"->" bun:",scanonly"`
|
|
RowNumber int64 `json:"_rownumber,omitempty" gorm:"-" bun:",scanonly"`
|
|
RecordError string `json:"_error,omitempty" gorm:"-" bun:",scanonly"`
|
|
}
|
|
|
|
type excludeModel struct {
|
|
bun.BaseModel `bun:"table:public.crmnote,alias:crmnote"`
|
|
ID int `json:"id" bun:"id,pk"`
|
|
Note string `json:"note" bun:"note,type:citext,"`
|
|
Norm string `json:"norm" bun:"norm,generated"`
|
|
|
|
adhocBuffer `json:",omitempty" bun:",scanonly"`
|
|
}
|
|
|
|
func newExcludeDB() *bun.DB {
|
|
return bun.NewDB(&sql.DB{}, pgdialect.New())
|
|
}
|
|
|
|
// TestBunExcludeColumnWithNonWritableColumns feeds the reflection output
|
|
// straight into the adapter, as the handlers do, for insert and update.
|
|
func TestBunExcludeColumnWithNonWritableColumns(t *testing.T) {
|
|
db := newExcludeDB()
|
|
m := &excludeModel{}
|
|
cols := reflection.NonWritableColumns(m)
|
|
if len(cols) == 0 {
|
|
t.Fatal("expected non-writable columns")
|
|
}
|
|
|
|
ins := &BunInsertQuery{query: db.NewInsert().Model(m)}
|
|
ins.ExcludeColumn(cols...)
|
|
insSQL, err := ins.query.AppendQuery(db.QueryGen(), nil)
|
|
if err != nil {
|
|
t.Fatalf("insert: %v", err)
|
|
}
|
|
|
|
upd := &BunUpdateQuery{query: db.NewUpdate().Model(m).Where("id = 1")}
|
|
upd.ExcludeColumn(cols...)
|
|
updSQL, err := upd.query.AppendQuery(db.QueryGen(), nil)
|
|
if err != nil {
|
|
t.Fatalf("update: %v", err)
|
|
}
|
|
|
|
for name, q := range map[string]string{"insert": string(insSQL), "update": string(updSQL)} {
|
|
for _, bad := range []string{"cql1", "cql2", "_rownumber", "_error", "norm"} {
|
|
if strings.Contains(q, `"`+bad+`"`) {
|
|
t.Errorf("%s writes non-writable column %s: %s", name, bad, q)
|
|
}
|
|
}
|
|
if !strings.Contains(q, `"note"`) {
|
|
t.Errorf("%s dropped writable column note: %s", name, q)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBunExcludeColumnIgnoresUnknownAndKeepsWritable(t *testing.T) {
|
|
db := newExcludeDB()
|
|
m := &excludeModel{}
|
|
|
|
ins := &BunInsertQuery{query: db.NewInsert().Model(m)}
|
|
ins.ExcludeColumn("does_not_exist", "note")
|
|
q, err := ins.query.AppendQuery(db.QueryGen(), nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if strings.Contains(string(q), `"note"`) {
|
|
t.Errorf("writable column note should have been excluded: %s", q)
|
|
}
|
|
}
|
|
|
|
func TestBunExcludeColumnOnlyNonWritable(t *testing.T) {
|
|
db := newExcludeDB()
|
|
ins := &BunInsertQuery{query: db.NewInsert().Model(&excludeModel{})}
|
|
ins.ExcludeColumn("cql1") // everything filtered out: must not error or panic
|
|
if _, err := ins.query.AppendQuery(db.QueryGen(), nil); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
|
|
func TestBunExcludeColumnWithoutModel(t *testing.T) {
|
|
db := newExcludeDB()
|
|
ins := &BunInsertQuery{query: db.NewInsert()}
|
|
ins.ExcludeColumn("cql1") // no model yet: must not panic
|
|
}
|