feat: add delete, context, and tx helpers
Add Delete/DeleteAffected, context-aware CRUD helpers, WithTx, ContainsCol, and queryReturning deduplication for returning statements. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
package dbx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestInsert_ReturnsLastInsertID(t *testing.T) {
|
||||
stmt := mockStatement{
|
||||
execContextFn: func(_ context.Context) (sql.Result, error) {
|
||||
return mockResult{lastInsertID: 42}, nil
|
||||
},
|
||||
}
|
||||
|
||||
id, err := Insert(mockExecutable{}, stmt)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, uint64(42), id)
|
||||
}
|
||||
|
||||
func TestInsert_RejectsZeroID(t *testing.T) {
|
||||
stmt := mockStatement{
|
||||
execContextFn: func(_ context.Context) (sql.Result, error) {
|
||||
return mockResult{lastInsertID: 0}, nil
|
||||
},
|
||||
}
|
||||
|
||||
_, err := Insert(mockExecutable{}, stmt)
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestInsertReturning_ReturnsRow(t *testing.T) {
|
||||
stmt := mockStatement{
|
||||
queryContextFn: func(_ context.Context, dest any) error {
|
||||
ptr := dest.(*row)
|
||||
ptr.ID = 7
|
||||
return nil
|
||||
},
|
||||
}
|
||||
|
||||
result, err := InsertReturning[row](mockQueryable{}, stmt)
|
||||
require.NoError(t, err)
|
||||
require.NotNil(t, result)
|
||||
assert.Equal(t, 7, result.ID)
|
||||
}
|
||||
|
||||
func TestUpdateAffected_ReturnsCount(t *testing.T) {
|
||||
stmt := mockStatement{
|
||||
execContextFn: func(_ context.Context) (sql.Result, error) {
|
||||
return mockResult{rowsAffected: 3}, nil
|
||||
},
|
||||
}
|
||||
|
||||
n, err := UpdateAffected(mockExecutable{}, stmt)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(3), n)
|
||||
}
|
||||
|
||||
func TestDelete_Succeeds(t *testing.T) {
|
||||
called := false
|
||||
stmt := mockStatement{
|
||||
execContextFn: func(_ context.Context) (sql.Result, error) {
|
||||
called = true
|
||||
return mockResult{}, nil
|
||||
},
|
||||
}
|
||||
|
||||
err := Delete(mockExecutable{}, stmt)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, called)
|
||||
}
|
||||
|
||||
func TestDeleteAffected_ReturnsCount(t *testing.T) {
|
||||
stmt := mockStatement{
|
||||
execContextFn: func(_ context.Context) (sql.Result, error) {
|
||||
return mockResult{rowsAffected: 2}, nil
|
||||
},
|
||||
}
|
||||
|
||||
n, err := DeleteAffected(mockExecutable{}, stmt)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(2), n)
|
||||
}
|
||||
|
||||
func TestExecContext_PropagatesError(t *testing.T) {
|
||||
wantErr := errors.New("exec failed")
|
||||
stmt := mockStatement{
|
||||
execContextFn: func(_ context.Context) (sql.Result, error) {
|
||||
return nil, wantErr
|
||||
},
|
||||
}
|
||||
|
||||
err := DeleteContext(context.Background(), mockExecutable{}, stmt)
|
||||
assert.ErrorIs(t, err, wantErr)
|
||||
}
|
||||
Reference in New Issue
Block a user