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 }