diff options
| author | Stefan Majewsky <majewsky@gmx.net> | 2026-04-16 21:18:04 +0200 |
|---|---|---|
| committer | Stefan Majewsky <majewsky@gmx.net> | 2026-04-16 21:18:04 +0200 |
| commit | d964c2be59a73e6b21ce1a8031fe913588bddf66 (patch) | |
| tree | d252f968b9b825591854352a073f1d4f1135269b /query.go | |
| parent | a646924f1f474aeb5acd3d753cfcb2379dca5210 (diff) | |
| download | go-oblast-d964c2be59a73e6b21ce1a8031fe913588bddf66.tar.gz | |
add Store.Update()
Diffstat (limited to 'query.go')
| -rw-r--r-- | query.go | 54 |
1 files changed, 53 insertions, 1 deletions
@@ -105,7 +105,59 @@ func (s Store[R]) Insert(db Handle, records ...R) (returnedRecords []R, returned return records, nil } -// TODO: Store.Update +// Update executes an SQL UPDATE statement for each of the provided records, updating all non-primary-key columns with the values in the records. +// Returns [MissingRecordError] if any of the records does not exist in the database, that is, if for any of the records, the database contains no row with the same primary key values. +// +// Returns an error if [NewStore] was called without the [TableNameIs] or [PrimaryKeyIs] options, which are both required to generate a query for this method. +func (s Store[R]) Update(db Handle, records ...R) (returnedError error) { + if s.plan.Update.Query == "" { + return errors.New("cannot execute Update() because query could not be autogenerated") + } + + var ( + argumentIndexes = s.plan.Update.ArgumentIndexes + argumentSlots = make([]any, len(argumentIndexes)) + ) + + var stmt *sql.Stmt + if len(records) >= PrepareThreshold { + var err error + stmt, err = db.Prepare(s.plan.Update.Query) + if err != nil { + return fmt.Errorf("during Prepare(): %w", err) + } + defer func() { + returnedError = mergeCloseError("Stmt", returnedError, stmt.Close()) + }() + } + + for idx, r := range records { + v := reflect.ValueOf(&r).Elem() + for idx, index := range argumentIndexes { + argumentSlots[idx] = v.FieldByIndex(index).Addr().Interface() + } + var ( + result sql.Result + err error + ) + if stmt == nil { + result, err = db.Exec(s.plan.Update.Query, argumentSlots...) + } else { + result, err = stmt.Exec(argumentSlots...) + } + if err != nil { + return fmt.Errorf("during Exec() for record with idx = %d: %w", idx, err) + } + rowsAffected, err := result.RowsAffected() + if err != nil { + return fmt.Errorf("during RowsAffected() for record with idx = %d: %w", idx, err) + } + if rowsAffected == 0 { + return MissingRecordError[R]{r, s.plan} + } + } + return nil +} // Delete executes an SQL DELETE statement for each of the provided records, using their primary keys to locate the respective table rows. // |
