From 8d91fc9aab011a6b0d399f0284c2301554499779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Dulai?= Date: Sun, 5 Jul 2026 08:45:45 +0200 Subject: [PATCH 1/3] Separate execs into their own files --- exec/count.go | 84 +++++++++++++ exec/delete.go | 71 +++++++++++ exec/exec.go | 262 --------------------------------------- exec/insert.go | 85 +++++++++++++ exec/select.go | 2 +- exec/update.go | 66 ++++++++++ repository/repository.go | 4 +- test/exec_test.go | 10 +- test/select_test.go | 16 +-- 9 files changed, 322 insertions(+), 278 deletions(-) create mode 100644 exec/count.go create mode 100644 exec/delete.go create mode 100644 exec/insert.go create mode 100644 exec/update.go diff --git a/exec/count.go b/exec/count.go new file mode 100644 index 0000000..6f39da2 --- /dev/null +++ b/exec/count.go @@ -0,0 +1,84 @@ +package exec + +import ( + "database/sql" + "errors" + "reflect" + + "git.gdulai.com/gdulai/simpleorm" + "git.gdulai.com/gdulai/simpleorm/schema" + log "gitlab.com/gdulai/simpleloglvl" +) + +type Count[T any] struct { + target schema.Table + whereStmt string + args []any + result int64 +} + +func CreateCount[T any](orm *simpleorm.ORM, whereStmt string, args ...any) (Count[T], error) { + table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) + if !ok { + return Count[T]{}, errors.New("Failed to get table from schema cache") + } + + return Count[T]{target: *table, whereStmt: whereStmt, args: args}, nil +} + +func (c *Count[T]) Result() int64 { + return c.result +} + +func (c *Count[T]) Execute(conn *simpleorm.DBConnection) error { + return c.execute(conn, nil) +} + +func (c *Count[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { + // Reinit the results, new execution + c.result = -1 + dml := c.target.GetCountDML() + + if c.whereStmt != "" { + dml += " WHERE " + c.whereStmt + } + + log.LogDebug("Preparing sql: %s, with args: %s", dml, c.args) + + var stmt *sql.Stmt + var err error + if tx != nil { + stmt, err = tx.Prepare(dml) + } else { + stmt, err = conn.Prepare(dml) + } + + if err != nil { + return err + } + defer stmt.Close() + + log.LogDebug("Executing statement: %s", stmt) + + if len(c.args) == 0 { + err = stmt.QueryRow().Scan(&c.result) + } else { + // Flattent args to make sure it can be parsed correctly + var flatArgs []any + for _, a := range c.args { + if s, ok := a.([]any); ok { + flatArgs = append(flatArgs, s...) + } else { + flatArgs = append(flatArgs, a) + } + } + + err = stmt.QueryRow(flatArgs...).Scan(&c.result) + + } + if err != nil { + return err + } + + return nil +} diff --git a/exec/delete.go b/exec/delete.go new file mode 100644 index 0000000..9bae265 --- /dev/null +++ b/exec/delete.go @@ -0,0 +1,71 @@ +package exec + +import ( + "database/sql" + "errors" + "reflect" + + "git.gdulai.com/gdulai/simpleorm" + "git.gdulai.com/gdulai/simpleorm/schema" + log "gitlab.com/gdulai/simpleloglvl" +) + +type Delete[T any] struct { + target schema.Table + toDelete []T +} + +func NewDelete[T any](orm *simpleorm.ORM, toDelete []T) (Delete[T], error) { + table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) + if !ok { + return Delete[T]{}, errors.New("Failed to get table from schema cache") + } + + return Delete[T]{target: *table, toDelete: toDelete}, nil +} + +func (d *Delete[T]) Execute(conn *simpleorm.DBConnection) error { + return d.execute(conn, nil) +} + +func (d *Delete[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { + count := len(d.toDelete) + dml, err := d.target.GetDeleteDML(count) + if err != nil { + return err + } + + var params []any + + for _, del := range d.toDelete { + pkCols, err := getPk(del, d.target) + if err != nil { + return err + } + + for _, pk := range pkCols { + params = append(params, pk) + } + } + + log.LogDebug("%s [%s]", dml, params) + + var stmt *sql.Stmt + if tx != nil { + stmt, err = tx.Prepare(dml) + } else { + stmt, err = conn.Prepare(dml) + } + defer stmt.Close() + + result, err := stmt.Exec(params...) + if err != nil { + return err + } else { + rowsAffected, _ := result.RowsAffected() + log.LogInfo("Deleted %s row", rowsAffected) + } + + return nil + +} diff --git a/exec/exec.go b/exec/exec.go index 6caa9cb..6f11787 100644 --- a/exec/exec.go +++ b/exec/exec.go @@ -157,268 +157,6 @@ type Exec[T any] interface { execute(conn *simpleorm.DBConnection, tx *sql.Tx) error } -type Count[T any] struct { - target schema.Table - whereStmt string - args []any - result int64 -} - -func CreateCount[T any](orm *simpleorm.ORM, whereStmt string, args ...any) (Count[T], error) { - table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) - if !ok { - return Count[T]{}, errors.New("Failed to get table from schema cache") - } - - return Count[T]{target: *table, whereStmt: whereStmt, args: args}, nil -} - -func (c *Count[T]) Result() int64 { - return c.result -} - -func (c *Count[T]) Execute(conn *simpleorm.DBConnection) error { - return c.execute(conn, nil) -} - -func (c *Count[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { - // Reinit the results, new execution - c.result = -1 - dml := c.target.GetCountDML() - - if c.whereStmt != "" { - dml += " WHERE " + c.whereStmt - } - - log.LogDebug("Preparing sql: %s, with args: %s", dml, c.args) - - var stmt *sql.Stmt - var err error - if tx != nil { - stmt, err = tx.Prepare(dml) - } else { - stmt, err = conn.Prepare(dml) - } - - if err != nil { - return err - } - defer stmt.Close() - - log.LogDebug("Executing statement: %s", stmt) - - if len(c.args) == 0 { - err = stmt.QueryRow().Scan(&c.result) - } else { - // Flattent args to make sure it can be parsed correctly - var flatArgs []any - for _, a := range c.args { - if s, ok := a.([]any); ok { - flatArgs = append(flatArgs, s...) - } else { - flatArgs = append(flatArgs, a) - } - } - - err = stmt.QueryRow(flatArgs...).Scan(&c.result) - - } - if err != nil { - return err - } - - return nil -} - -type Insert[T any] struct { - target schema.Table - toInsert []T - results []T -} - -func NewInsert[T any](orm *simpleorm.ORM, toInsert ...T) (Insert[T], error) { - table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) - if !ok { - return Insert[T]{}, errors.New("Failed to get table from schema cache") - } - - return Insert[T]{target: *table, toInsert: toInsert}, nil -} - -func (ins *Insert[T]) Results() []T { - return ins.results -} - -func (ins *Insert[T]) Execute(conn *simpleorm.DBConnection) error { - return ins.execute(conn, nil) -} - -func (ins *Insert[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { - dml, err := ins.target.GetInsertDML(len(ins.toInsert)) - if err != nil { - return err - } - - var params []any - for i := range len(ins.toInsert) { - actualParams := prepareParams(ins.toInsert[i], ins.target) - if len(params) == 0 { - params = make([]any, len(ins.toInsert)*len(actualParams)) - } - for j := range actualParams { - params[(i*len(actualParams))+j] = actualParams[j] - } - } - - log.LogDebug("%s [%s]", dml, params) - - var stmt *sql.Stmt - if tx != nil { - stmt, err = tx.Prepare(dml) - } else { - stmt, err = conn.Prepare(dml) - } - defer stmt.Close() - - // Flattent args to make sure it can be parsed correctly - var flatParams []any - for _, param := range params { - if s, ok := param.([]any); ok { - flatParams = append(flatParams, s...) - } else { - flatParams = append(flatParams, param) - } - } - - rows, err := stmt.Query(flatParams...) - - if err != nil { - return err - } - - ins.results, err = readRows[T](ins.target, rows) - if err != nil { - return err - } - - return nil -} - -type Update[T any] struct { - target schema.Table - toUpdate T -} - -func NewUpdate[T any](orm *simpleorm.ORM, toUpdate T) (Update[T], error) { - table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) - if !ok { - return Update[T]{}, errors.New("Failed to get table from schema cache") - } - - return Update[T]{target: *table, toUpdate: toUpdate}, nil -} - -func (u Update[T]) Execute(conn *simpleorm.DBConnection) error { - return u.execute(conn, nil) -} - -func (u Update[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { - dml, err := u.target.GetUpdateDML() - if err != nil { - return err - } - - params := prepareParams(u.toUpdate, u.target) - - pkCols, err := getPk(u.toUpdate, u.target) - if err != nil { - return err - } - // Put the pks back at the end - for _, pk := range pkCols { - params = append(params, pk) - } - - log.LogDebug("%s [%s]", dml, params) - - var stmt *sql.Stmt - if tx != nil { - stmt, err = tx.Prepare(dml) - } else { - stmt, err = conn.Prepare(dml) - } - defer stmt.Close() - - result, err := stmt.Exec(params...) - if err != nil { - return err - } else { - rowsAffected, _ := result.RowsAffected() - log.LogInfo("Updated %s row", rowsAffected) - } - return nil -} - -type Delete[T any] struct { - target schema.Table - toDelete []T -} - -func NewDelete[T any](orm *simpleorm.ORM, toDelete []T) (Delete[T], error) { - table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) - if !ok { - return Delete[T]{}, errors.New("Failed to get table from schema cache") - } - - return Delete[T]{target: *table, toDelete: toDelete}, nil -} - -func (d *Delete[T]) Execute(conn *simpleorm.DBConnection) error { - return d.execute(conn, nil) -} - -func (d *Delete[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { - count := len(d.toDelete) - dml, err := d.target.GetDeleteDML(count) - if err != nil { - return err - } - - var params []any - - for _, del := range d.toDelete { - pkCols, err := getPk(del, d.target) - if err != nil { - return err - } - - for _, pk := range pkCols { - params = append(params, pk) - } - } - - log.LogDebug("%s [%s]", dml, params) - - var stmt *sql.Stmt - if tx != nil { - stmt, err = tx.Prepare(dml) - } else { - stmt, err = conn.Prepare(dml) - } - defer stmt.Close() - - result, err := stmt.Exec(params...) - if err != nil { - return err - } else { - rowsAffected, _ := result.RowsAffected() - log.LogInfo("Deleted %s row", rowsAffected) - } - - return nil - -} - func createSelectResultContainer(t schema.Table) []any { typ := t.Type() vals := make([]any, typ.NumField()) diff --git a/exec/insert.go b/exec/insert.go new file mode 100644 index 0000000..41fd5c3 --- /dev/null +++ b/exec/insert.go @@ -0,0 +1,85 @@ +package exec + +import ( + "database/sql" + "errors" + "reflect" + + "git.gdulai.com/gdulai/simpleorm" + "git.gdulai.com/gdulai/simpleorm/schema" + log "gitlab.com/gdulai/simpleloglvl" +) + +type Insert[T any] struct { + target schema.Table + toInsert []T + results []T +} + +func NewInsert[T any](orm *simpleorm.ORM, toInsert ...T) (Insert[T], error) { + table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) + if !ok { + return Insert[T]{}, errors.New("Failed to get table from schema cache") + } + + return Insert[T]{target: *table, toInsert: toInsert}, nil +} + +func (ins *Insert[T]) Results() []T { + return ins.results +} + +func (ins *Insert[T]) Execute(conn *simpleorm.DBConnection) error { + return ins.execute(conn, nil) +} + +func (ins *Insert[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { + dml, err := ins.target.GetInsertDML(len(ins.toInsert)) + if err != nil { + return err + } + + var params []any + for i := range len(ins.toInsert) { + actualParams := prepareParams(ins.toInsert[i], ins.target) + if len(params) == 0 { + params = make([]any, len(ins.toInsert)*len(actualParams)) + } + for j := range actualParams { + params[(i*len(actualParams))+j] = actualParams[j] + } + } + + log.LogDebug("%s [%s]", dml, params) + + var stmt *sql.Stmt + if tx != nil { + stmt, err = tx.Prepare(dml) + } else { + stmt, err = conn.Prepare(dml) + } + defer stmt.Close() + + // Flattent args to make sure it can be parsed correctly + var flatParams []any + for _, param := range params { + if s, ok := param.([]any); ok { + flatParams = append(flatParams, s...) + } else { + flatParams = append(flatParams, param) + } + } + + rows, err := stmt.Query(flatParams...) + + if err != nil { + return err + } + + ins.results, err = readRows[T](ins.target, rows) + if err != nil { + return err + } + + return nil +} diff --git a/exec/select.go b/exec/select.go index f226e40..7badcaf 100644 --- a/exec/select.go +++ b/exec/select.go @@ -22,7 +22,7 @@ type Select[T any] struct { } // Creates the select query builder -func CreateSelect[T any](orm *simpleorm.ORM) (Select[T], error) { +func NewSelect[T any](orm *simpleorm.ORM) (Select[T], error) { table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) if !ok { return Select[T]{}, errors.New("Failed to get table from schema cache") diff --git a/exec/update.go b/exec/update.go new file mode 100644 index 0000000..9bc1f1a --- /dev/null +++ b/exec/update.go @@ -0,0 +1,66 @@ +package exec + +import ( + "database/sql" + "errors" + "reflect" + + "git.gdulai.com/gdulai/simpleorm" + "git.gdulai.com/gdulai/simpleorm/schema" + log "gitlab.com/gdulai/simpleloglvl" +) + +type Update[T any] struct { + target schema.Table + toUpdate T +} + +func NewUpdate[T any](orm *simpleorm.ORM, toUpdate T) (Update[T], error) { + table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) + if !ok { + return Update[T]{}, errors.New("Failed to get table from schema cache") + } + + return Update[T]{target: *table, toUpdate: toUpdate}, nil +} + +func (u Update[T]) Execute(conn *simpleorm.DBConnection) error { + return u.execute(conn, nil) +} + +func (u Update[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { + dml, err := u.target.GetUpdateDML() + if err != nil { + return err + } + + params := prepareParams(u.toUpdate, u.target) + + pkCols, err := getPk(u.toUpdate, u.target) + if err != nil { + return err + } + // Put the pks back at the end + for _, pk := range pkCols { + params = append(params, pk) + } + + log.LogDebug("%s [%s]", dml, params) + + var stmt *sql.Stmt + if tx != nil { + stmt, err = tx.Prepare(dml) + } else { + stmt, err = conn.Prepare(dml) + } + defer stmt.Close() + + result, err := stmt.Exec(params...) + if err != nil { + return err + } else { + rowsAffected, _ := result.RowsAffected() + log.LogInfo("Updated %s row", rowsAffected) + } + return nil +} diff --git a/repository/repository.go b/repository/repository.go index 04763a7..cacacb3 100644 --- a/repository/repository.go +++ b/repository/repository.go @@ -23,7 +23,7 @@ func NewRepository[T HasPK](conn *simpleorm.DBConnection, orm *simpleorm.ORM) *R } func (r *Repository[T]) SelectAll() []*T { - selectExec, err := exec.CreateSelect[T](r.orm) + selectExec, err := exec.NewSelect[T](r.orm) if err != nil { log.LogError("Failed to create select execution: %s", err) return []*T{} @@ -68,7 +68,7 @@ func (r *Repository[T]) SelectByPk(pks ...any) *T { } - selectExec, err := exec.CreateSelect[T](r.orm) + selectExec, err := exec.NewSelect[T](r.orm) if err != nil { log.LogError("Failed to create select execution: %s", err) return nil diff --git a/test/exec_test.go b/test/exec_test.go index b56f645..a9c5e51 100644 --- a/test/exec_test.go +++ b/test/exec_test.go @@ -118,7 +118,7 @@ func TestInsertAndUpdate(t *testing.T) { return } - selectExec, err := exec.CreateSelect[Test](orm) + selectExec, err := exec.NewSelect[Test](orm) if err != nil { log.LogError("TestInsertMultipleAndSelectWithParam setup failed: %s", err) t.Fail() @@ -207,7 +207,7 @@ func TestInsertAndDelete(t *testing.T) { return } - selectExec, err := exec.CreateSelect[Test](orm) + selectExec, err := exec.NewSelect[Test](orm) if err != nil { log.LogError("TestInsertAndDelete setup failed: %s", err) t.Fail() @@ -263,7 +263,7 @@ func TestBoolInsertAndSelectSingle(t *testing.T) { return } - selectExec, err := exec.CreateSelect[TestWithBool](orm) + selectExec, err := exec.NewSelect[TestWithBool](orm) if err != nil { log.LogError("TestBoolInsertAndSelectSingle setup failed: %s", err) t.Fail() @@ -317,7 +317,7 @@ func TestTimeInsertAndSelectSingle(t *testing.T) { return } - selectExec, err := exec.CreateSelect[TestWithTime](orm) + selectExec, err := exec.NewSelect[TestWithTime](orm) if err != nil { log.LogError("TestTimeInsertAndSelectSingle setup failed: %s", err) t.Fail() @@ -423,7 +423,7 @@ func TestTransactionRollback(t *testing.T) { return } - selectExec, err := exec.CreateSelect[Test](orm) + selectExec, err := exec.NewSelect[Test](orm) if err != nil { log.LogError("TestTransactionRollback WHEN failed: %s", err) t.Fail() diff --git a/test/select_test.go b/test/select_test.go index 052c5bd..4db1ced 100644 --- a/test/select_test.go +++ b/test/select_test.go @@ -16,7 +16,7 @@ func TestSelectEmpty(t *testing.T) { defer cleanUp("test.db", conn) // WHEN - selectExec, err := exec.CreateSelect[Test](orm) + selectExec, err := exec.NewSelect[Test](orm) // THEN if err != nil { @@ -55,7 +55,7 @@ func TestSelectSingle(t *testing.T) { return } - selectExec, err := exec.CreateSelect[Test](orm) + selectExec, err := exec.NewSelect[Test](orm) if err != nil { log.LogError("TestInsertAndSelectSingle setup failed: %s", err) t.Fail() @@ -121,7 +121,7 @@ func TestSelectWithCompositePk(t *testing.T) { return } - selectExec, err := exec.CreateSelect[TestWithCompositePk](orm) + selectExec, err := exec.NewSelect[TestWithCompositePk](orm) if err != nil { log.LogError("TestInsertSelectWithCompositePk setup failed: %s", err) t.Fail() @@ -182,7 +182,7 @@ func TestSelectWithParam(t *testing.T) { return } - selectExec, err := exec.CreateSelect[Test](orm) + selectExec, err := exec.NewSelect[Test](orm) if err != nil { log.LogError("TestInsertMultipleAndSelectWithParam setup failed: %s", err) t.Fail() @@ -255,7 +255,7 @@ func TestSelectWithLimitAndOffset(t *testing.T) { } // WHEN - selectExec, err := exec.CreateSelect[Test](orm) + selectExec, err := exec.NewSelect[Test](orm) if err != nil { log.LogError("TestSelectWithLimitAndOffset failed: %s", err) t.Fail() @@ -291,7 +291,7 @@ func TestSelectOrderByDesc(t *testing.T) { } // WHEN - selectExec, err := exec.CreateSelect[Test](orm) + selectExec, err := exec.NewSelect[Test](orm) if err != nil { log.LogError("TestSelectOrderByDesc failed: %s", err) t.Fail() @@ -331,7 +331,7 @@ func TestSelectOrderByAsc(t *testing.T) { } // WHEN - selectExec, err := exec.CreateSelect[Test](orm) + selectExec, err := exec.NewSelect[Test](orm) if err != nil { log.LogError("TestSelectOrderByAsc failed: %s", err) t.Fail() @@ -371,7 +371,7 @@ func TestSelectOrderByAscWithLimitAndOffset(t *testing.T) { } // WHEN - selectExec, err := exec.CreateSelect[Test](orm) + selectExec, err := exec.NewSelect[Test](orm) if err != nil { log.LogError("TestSelectOrderByAsc failed: %s", err) t.Fail() -- 2.54.0 From 7553b57ec9941bd7b60af59967ad51984f9135c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Dulai?= Date: Tue, 28 Jul 2026 22:04:34 +0200 Subject: [PATCH 2/3] Documentation --- exec/count.go | 12 ++++++++++++ exec/insert.go | 37 +++++++++++++++++++++++++++++++++++++ orm.go | 7 ++++--- 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/exec/count.go b/exec/count.go index 6f39da2..3628236 100644 --- a/exec/count.go +++ b/exec/count.go @@ -10,6 +10,7 @@ import ( log "gitlab.com/gdulai/simpleloglvl" ) +// Count represents a count query. type Count[T any] struct { target schema.Table whereStmt string @@ -17,6 +18,9 @@ type Count[T any] struct { result int64 } +// CreateCount returns a new instance of Count. +// +// orm is the simpleorm.ORM instance which connects, caches and manages the relations. func CreateCount[T any](orm *simpleorm.ORM, whereStmt string, args ...any) (Count[T], error) { table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) if !ok { @@ -26,14 +30,22 @@ func CreateCount[T any](orm *simpleorm.ORM, whereStmt string, args ...any) (Coun return Count[T]{target: *table, whereStmt: whereStmt, args: args}, nil } +// Result returns the result of the count query. func (c *Count[T]) Result() int64 { return c.result } +// Execute executes the parsed count query against a connection and returns an error if there was any during the execution. +// +// conn is the simpleorm.DBConnection which handles the database connection. func (c *Count[T]) Execute(conn *simpleorm.DBConnection) error { return c.execute(conn, nil) } +// execute executes the parsed count query against a connection and transaction and returns an error if there was any during the execution. +// +// conn is the simpleorm.DBConnection which handles the database connection. +// tx is the sql.Tx transaction which the count query will be run in. func (c *Count[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { // Reinit the results, new execution c.result = -1 diff --git a/exec/insert.go b/exec/insert.go index 41fd5c3..0575066 100644 --- a/exec/insert.go +++ b/exec/insert.go @@ -10,12 +10,23 @@ import ( log "gitlab.com/gdulai/simpleloglvl" ) +// Insert represents an insert query operation. type Insert[T any] struct { target schema.Table toInsert []T results []T } +// Creates a new insert operation for the given model type. +// +// Parameters: +// - orm: The ORM instance that manages the database connection and schema +// - toInsert: A variadic list of model instances to insert +// +// Returns: +// - Insert[T]: A new insert operation instance +// - error: An error if the table could not be found in the schema cache + func NewInsert[T any](orm *simpleorm.ORM, toInsert ...T) (Insert[T], error) { table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) if !ok { @@ -25,14 +36,40 @@ func NewInsert[T any](orm *simpleorm.ORM, toInsert ...T) (Insert[T], error) { return Insert[T]{target: *table, toInsert: toInsert}, nil } +// Returns the results of the insert operation. +// +// Returns: +// - []T: A slice of model instances representing the inserted rows + func (ins *Insert[T]) Results() []T { return ins.results } +// Executes the insert operation using the provided database connection. +// +// Parameters: +// - conn: The database connection to use for executing the query +// +// Returns: +// - error: An error if the operation fails func (ins *Insert[T]) Execute(conn *simpleorm.DBConnection) error { + return ins.execute(conn, nil) } +// Executes the insert operation using the provided database connection or transaction. +// +// Parameters: +// - conn: The database connection to use for executing the query +// - tx: Optional transaction to use instead of a connection +// +// Returns: +// - error: An error if the operation fails +// +// Implementation Details: +// 1. Constructs the SQL INSERT statement using GetInsertDML +// 2. Prepares parameters by flattening nested any values +// 3. Executes the statement and maps results to model instances func (ins *Insert[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { dml, err := ins.target.GetInsertDML(len(ins.toInsert)) if err != nil { diff --git a/orm.go b/orm.go index ebc66c8..3450fe5 100644 --- a/orm.go +++ b/orm.go @@ -17,8 +17,9 @@ type ORM struct { cache *cache.SchemaCache } -// Inits the ORM library. -// Param objs is an array which should be an array of the types which describe the tables. +// NewOrm inits and creates an instance ORM library. +// +// obj is an array which should be an array of the types which describe the tables. func NewORM(objs ...any) *ORM { typeParsers := make(map[string]*schema.Parser) @@ -57,7 +58,7 @@ func NewORM(objs ...any) *ORM { return &ORM{cache: cache} } -// Builds the DDL and returns it as a string +// CreateSchmea builds the DDL and returns it as a string func (orm *ORM) CreateSchema() (string, error) { var ddl strings.Builder -- 2.54.0 From 120761ecfd89ae3f4b979f5eac8b579120aa4d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gerg=C5=91=20Dulai?= Date: Tue, 28 Jul 2026 22:15:29 +0200 Subject: [PATCH 3/3] Documentation --- exec/delete.go | 23 +++++++++++++++++++++-- exec/update.go | 23 +++++++++++++++++++++-- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/exec/delete.go b/exec/delete.go index 9bae265..3f1ac99 100644 --- a/exec/delete.go +++ b/exec/delete.go @@ -10,11 +10,21 @@ import ( log "gitlab.com/gdulai/simpleloglvl" ) +// Delete represents a delete operation. type Delete[T any] struct { - target schema.Table - toDelete []T + target schema.Table // The table from which records will be deleted. + toDelete []T // A slice of model instances to be deleted. } +// NewDelete creates a new instance of Delete. +// +// Parameters: +// - orm: The ORM instance that manages the database connection and schema +// - toDelete: A slice of model instances to delete +// +// Returns: +// - Delete[T]: A new Delete operation instance +// - error: An error if the table could not be found in the schema cache func NewDelete[T any](orm *simpleorm.ORM, toDelete []T) (Delete[T], error) { table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) if !ok { @@ -24,10 +34,19 @@ func NewDelete[T any](orm *simpleorm.ORM, toDelete []T) (Delete[T], error) { return Delete[T]{target: *table, toDelete: toDelete}, nil } +// Execute executes the delete operation. func (d *Delete[T]) Execute(conn *simpleorm.DBConnection) error { return d.execute(conn, nil) } +// execute constructs and executes the DELETE SQL statement. +// +// Parameters: +// - conn: The database connection to use for executing the query +// - tx: Optional transaction to use instead of a connection +// +// Returns: +// - error: An error if the operation fails func (d *Delete[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { count := len(d.toDelete) dml, err := d.target.GetDeleteDML(count) diff --git a/exec/update.go b/exec/update.go index 9bc1f1a..6e77ffa 100644 --- a/exec/update.go +++ b/exec/update.go @@ -10,11 +10,21 @@ import ( log "gitlab.com/gdulai/simpleloglvl" ) +// Update represents an update operation. type Update[T any] struct { - target schema.Table - toUpdate T + target schema.Table // The table where records will be updated. + toUpdate T // A model instance with the new values. } +// NewUpdate creates a new instance of Update. +// +// Parameters: +// - orm: The ORM instance that manages the database connection and schema +// - toUpdate: A model instance with new values +// +// Returns: +// - Update[T]: A new Update operation instance +// - error: An error if the table could not be found in the schema cache func NewUpdate[T any](orm *simpleorm.ORM, toUpdate T) (Update[T], error) { table, ok := orm.Cache().Get(reflect.TypeFor[T]().Name()) if !ok { @@ -24,10 +34,19 @@ func NewUpdate[T any](orm *simpleorm.ORM, toUpdate T) (Update[T], error) { return Update[T]{target: *table, toUpdate: toUpdate}, nil } +// Execute executes the update operation. func (u Update[T]) Execute(conn *simpleorm.DBConnection) error { return u.execute(conn, nil) } +// execute constructs and executes the UPDATE SQL statement. +// +// Parameters: +// - conn: The database connection to use for executing the query +// - tx: Optional transaction to use instead of a connection +// +// Returns: +// - error: An error if the operation fails func (u Update[T]) execute(conn *simpleorm.DBConnection, tx *sql.Tx) error { dml, err := u.target.GetUpdateDML() if err != nil { -- 2.54.0