diff --git a/internal/db/read_writer.go b/internal/db/read_writer.go index b4a78faec..f8414832e 100644 --- a/internal/db/read_writer.go +++ b/internal/db/read_writer.go @@ -463,14 +463,15 @@ func (rw *Db) CreateItems(ctx context.Context, createItems []interface{}, opt .. // which almost always should be to rollback. Update returns the number of // rows updated. // -// Supported options: WithOplog, NewOplogMsg and WithVersion. +// Supported options: WithOplog, NewOplogMsg, WithWhere and WithVersion. // WithOplog will write an oplog entry for the update. NewOplogMsg // will return in-memory oplog message. WithOplog and NewOplogMsg cannot be // used together. If WithVersion is used, then the update will include the // version number in the update where clause, which basically makes the update // use optimistic locking and the update will only succeed if the existing rows // version matches the WithVersion option. Zero is not a valid value for the -// WithVersion option and will return an error. +// WithVersion option and will return an error. WithWhere allows specifying an +// additional constraint on the operation in addition to the PKs. func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string, setToNullPaths []string, opt ...Option) (int, error) { const op = "db.Update" if rw.underlying == nil { @@ -620,8 +621,8 @@ func (rw *Db) Update(ctx context.Context, i interface{}, fieldMaskPaths []string // Delete an object in the db with options: WithOplog, NewOplogMsg, WithWhere. // WithOplog will write an oplog entry for the delete. NewOplogMsg will return // in-memory oplog message. WithOplog and NewOplogMsg cannot be used together. -// WithWhere allows specifying a constraint. Delete returns the number of rows -// deleted and any errors. +//WithWhere allows specifying an additional constraint on the operation in +//addition to the PKs. Delete returns the number of rows deleted and any errors. func (rw *Db) Delete(ctx context.Context, i interface{}, opt ...Option) (int, error) { const op = "db.Delete" if rw.underlying == nil { diff --git a/internal/db/read_writer_test.go b/internal/db/read_writer_test.go index ed6d2dd91..a45cfa993 100644 --- a/internal/db/read_writer_test.go +++ b/internal/db/read_writer_test.go @@ -1282,6 +1282,13 @@ func TestDb_Delete(t *testing.T) { "resource-public-id": []string{publicId}, } } + + // seed some test users, so we won't just happen to get a false positive + // with only 1 entry in the db + for i := 0; i < 1000; i++ { + _ = newUser() + } + type args struct { i *db_test.TestUser opt []Option @@ -1294,6 +1301,7 @@ func TestDb_Delete(t *testing.T) { args args want int wantOplog bool + wantFound bool wantErr bool wantErrIs errors.Code }{ @@ -1307,6 +1315,29 @@ func TestDb_Delete(t *testing.T) { want: 1, wantErr: false, }, + { + name: "with-where-no-delete", + underlying: db, + wrapper: TestWrapper(t), + args: args{ + i: newUser(), + opt: []Option{WithWhere("1 = ?", 2)}, + }, + wantFound: true, + want: 0, + wantErr: false, + }, + { + name: "with-where-and-delete", + underlying: db, + wrapper: TestWrapper(t), + args: args{ + i: newUser(), + opt: []Option{WithWhere("1 = ?", 1)}, + }, + want: 1, + wantErr: false, + }, { name: "valid-with-oplog", underlying: db, @@ -1394,6 +1425,11 @@ func TestDb_Delete(t *testing.T) { foundUser := tt.args.i.Clone().(*db_test.TestUser) foundUser.PublicId = tt.args.i.PublicId err = rw.LookupByPublicId(context.Background(), foundUser) + if tt.wantFound { + assert.NoError(err) + assert.Equal(tt.args.i.PublicId, foundUser.PublicId) + return + } assert.Error(err) assert.True(errors.Match(errors.T(errors.RecordNotFound), err))