WIP: Insert sets PK

This commit is contained in:
2026-05-20 23:16:42 +02:00
parent e98dbe3338
commit 4726204413
4 changed files with 79 additions and 18 deletions
+10 -4
View File
@@ -113,8 +113,9 @@ func (s Select[T]) Execute(conn *simpleorm.DBConnection) ([]T, error) {
} }
type Insert[T any] struct { type Insert[T any] struct {
target schema.Table target schema.Table
toInsert []T toInsert []T
lastInsertId int64
} }
func NewInsert[T any](orm *simpleorm.ORM, toInsert ...T) (Insert[T], error) { func NewInsert[T any](orm *simpleorm.ORM, toInsert ...T) (Insert[T], error) {
@@ -156,12 +157,16 @@ func (ins Insert[T]) Execute(conn *simpleorm.DBConnection) ([]T, error) {
} else { } else {
rowsAffected, _ := result.RowsAffected() rowsAffected, _ := result.RowsAffected()
log.LogInfo("Inserted %s row", rowsAffected) log.LogInfo("Inserted %s row", rowsAffected)
lastInsertId, _ := result.LastInsertId() ins.lastInsertId, _ = result.LastInsertId()
log.LogInfo("Last ID: %s", lastInsertId) log.LogInfo("Last ID: %s", ins.lastInsertId)
} }
return []T{}, nil return []T{}, nil
} }
func (ins Insert[T]) LastInsertId() int64 {
return ins.lastInsertId
}
type Update[T any] struct { type Update[T any] struct {
target schema.Table target schema.Table
toUpdate T toUpdate T
@@ -207,6 +212,7 @@ func (u Update[T]) Execute(conn *simpleorm.DBConnection) ([]T, error) {
} else { } else {
rowsAffected, _ := result.RowsAffected() rowsAffected, _ := result.RowsAffected()
log.LogInfo("Updated %s row", rowsAffected) log.LogInfo("Updated %s row", rowsAffected)
result.LastInsertId()
} }
return []T{u.toUpdate}, nil return []T{u.toUpdate}, nil
} }
+11 -5
View File
@@ -1,6 +1,7 @@
package repository package repository
import ( import (
"errors"
"reflect" "reflect"
"strings" "strings"
@@ -11,6 +12,7 @@ import (
type HasPK interface { type HasPK interface {
IsInsertable() bool IsInsertable() bool
SetPk(pks ...any)
} }
type Repository[T HasPK] struct { type Repository[T HasPK] struct {
@@ -87,32 +89,36 @@ func (r *Repository[T]) SelectByPk(pks ...any) *T {
return &res[0] return &res[0]
} }
func (r *Repository[T]) Save(entity T) { func (r *Repository[T]) Save(entity T) (*T, error) {
// Insert // Insert
if entity.IsInsertable() { if entity.IsInsertable() {
insertExec, err := exec.NewInsert[T](r.orm, entity) insertExec, err := exec.NewInsert[T](r.orm, entity)
if err != nil { if err != nil {
log.LogError("Failed to create insert execution: %s", err) log.LogError("Failed to create insert execution: %s", err)
return return nil, errors.New("")
} }
if _, err := insertExec.Execute(r.conn); err != nil { if _, err := insertExec.Execute(r.conn); err != nil {
log.LogError("Insert failed for entity: %s", entity) log.LogError("Insert failed for entity: %s", entity)
} }
return return nil, errors.New("")
} }
updateExec, err := exec.NewUpdate[T](r.orm, entity) updateExec, err := exec.NewUpdate[T](r.orm, entity)
if err != nil { if err != nil {
log.LogError("Failed to create update execution: %s", err) log.LogError("Failed to create update execution: %s", err)
return return nil, errors.New("")
} }
_, err = updateExec.Execute(r.conn) _, err = updateExec.Execute(r.conn)
if err != nil { if err != nil {
log.LogError("Update failed: %s", err) log.LogError("Update failed: %s", err)
return return nil, errors.New("")
} }
return &entity, nil
} }
func (r *Repository[T]) Delete(entity T) { func (r *Repository[T]) Delete(entity T) {
+51 -2
View File
@@ -15,45 +15,94 @@ type Test struct {
StringField string `sql:"nn"` StringField string `sql:"nn"`
} }
func (t Test) IsInsertable() bool { func (t *Test) IsInsertable() bool {
return t.ID == 0 return t.ID == 0
} }
func (t *Test) SetPk(pks ...any) {
t.ID = pks[0].(int)
}
type TestWithFk struct { type TestWithFk struct {
ID int `sql:"pk"` ID int `sql:"pk"`
TestID int `sql:"nn;fk=Test.ID"` TestID int `sql:"nn;fk=Test.ID"`
} }
func (t *TestWithFk) IsInsertable() bool {
return t.ID == 0
}
func (t *TestWithFk) SetPk(pks ...any) {
t.ID = pks[0].(int)
}
type TestWithFkAndFkId struct { type TestWithFkAndFkId struct {
ID int `sql:"pk"` ID int `sql:"pk"`
TestID int `sql:"nn;fk=Test.ID;fk_id=custom_fk"` TestID int `sql:"nn;fk=Test.ID;fk_id=custom_fk"`
} }
func (t *TestWithFkAndFkId) IsInsertable() bool {
return t.ID == 0
}
func (t *TestWithFkAndFkId) SetPk(pks ...any) {
t.ID = pks[0].(int)
}
type TestWithCompositePk struct { type TestWithCompositePk struct {
ID int `sql:"nn;pk;"` ID int `sql:"nn;pk;"`
Name string `sql:"nn;pk"` Name string `sql:"nn;pk"`
} }
func (t TestWithCompositePk) IsInsertable() bool { func (t *TestWithCompositePk) IsInsertable() bool {
return t.ID == 0 && t.Name == "" return t.ID == 0 && t.Name == ""
} }
func (t *TestWithCompositePk) SetPk(pks ...any) {
t.ID = pks[0].(int)
t.Name = pks[1].(string)
}
type TestWithCompositeFk struct { type TestWithCompositeFk struct {
ID int `sql:"nn;pk"` ID int `sql:"nn;pk"`
CompositeFkId int `sql:"nn;fk=TestWithCompositePk.ID;"` CompositeFkId int `sql:"nn;fk=TestWithCompositePk.ID;"`
CompositeFkName string `sql:"nn;fk=TestWithCompositePk.Name;"` CompositeFkName string `sql:"nn;fk=TestWithCompositePk.Name;"`
} }
func (t *TestWithCompositeFk) IsInsertable() bool {
return t.ID == 0
}
func (t *TestWithCompositeFk) SetPk(pks ...any) {
t.ID = pks[0].(int)
}
type TestWithBool struct { type TestWithBool struct {
ID int `sql:"pk"` ID int `sql:"pk"`
BoolField bool `sql:"nn"` BoolField bool `sql:"nn"`
} }
func (t *TestWithBool) IsInsertable() bool {
return t.ID == 0
}
func (t *TestWithBool) SetPk(pks ...any) {
t.ID = pks[0].(int)
}
type TestWithTime struct { type TestWithTime struct {
ID int `sql:"pk"` ID int `sql:"pk"`
TimeField int64 `sql:"nn"` TimeField int64 `sql:"nn"`
} }
func (t *TestWithTime) IsInsertable() bool {
return t.ID == 0
}
func (t *TestWithTime) SetPk(pks ...any) {
t.ID = pks[0].(int)
}
func TestMain(m *testing.M) { func TestMain(m *testing.M) {
log.SetupLogs("Info") log.SetupLogs("Info")
+7 -7
View File
@@ -33,7 +33,7 @@ func TestRepoSelectAll(t *testing.T) {
return return
} }
_, err = insertExec.Execute(conn) _, err = insertExec.Execute(conn)
repo := repository.NewRepository[Test](conn, orm) repo := repository.NewRepository[*Test](conn, orm)
// WHEN // WHEN
res := repo.SelectAll() res := repo.SelectAll()
@@ -59,7 +59,7 @@ func TestRepoSelectByPk(t *testing.T) {
return return
} }
_, err = insertExec.Execute(conn) _, err = insertExec.Execute(conn)
repo := repository.NewRepository[Test](conn, orm) repo := repository.NewRepository[*Test](conn, orm)
// WHEN // WHEN
res := repo.SelectByPk(1) res := repo.SelectByPk(1)
@@ -85,7 +85,7 @@ func TestRepoSelectByCompundPk(t *testing.T) {
return return
} }
_, err = insertExec.Execute(conn) _, err = insertExec.Execute(conn)
repo := repository.NewRepository[TestWithCompositePk](conn, orm) repo := repository.NewRepository[*TestWithCompositePk](conn, orm)
// WHEN // WHEN
res := repo.SelectByPk(42069, "Test") res := repo.SelectByPk(42069, "Test")
@@ -104,10 +104,10 @@ func TestRepoSave(t *testing.T) {
defer cleanUp("test.db", conn) defer cleanUp("test.db", conn)
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"} testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
repo := repository.NewRepository[Test](conn, orm) repo := repository.NewRepository[*Test](conn, orm)
// WHEN // WHEN
repo.Save(testObj) repo.Save(&testObj)
// THEN // THEN
res := repo.SelectByPk(1) res := repo.SelectByPk(1)
@@ -124,9 +124,9 @@ func TestRepoDelete(t *testing.T) {
defer cleanUp("test.db", conn) defer cleanUp("test.db", conn)
testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"} testObj := Test{Int64Field: 54, IntField: 12, StringField: "asdf"}
repo := repository.NewRepository[Test](conn, orm) repo := repository.NewRepository[*Test](conn, orm)
repo.Save(testObj) repo.Save(&testObj)
res := repo.SelectByPk(1) res := repo.SelectByPk(1)
if res == nil { if res == nil {