8d697eda5b
Add Delete/DeleteAffected, context-aware CRUD helpers, WithTx, ContainsCol, and queryReturning deduplication for returning statements. Co-authored-by: Cursor <cursoragent@cursor.com>
100 lines
2.2 KiB
Go
100 lines
2.2 KiB
Go
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)
|
|
}
|