Skip to content

Commit 2955549

Browse files
committed
Make execs with assert rows more compact
1 parent b6660ec commit 2955549

5 files changed

Lines changed: 39 additions & 35 deletions

File tree

README.md

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -141,11 +141,9 @@ func FindCustomerByID(ctx context.Context, executor qrbpgx.Executor, id uuid.UUI
141141
Where(customer.ID.Eq(qrb.Arg(id))).
142142
GroupBy(customer.ID)
143143

144-
row, err := qrbpgx.Build(q).WithExecutor(executor).QueryRow(ctx)
145-
if err != nil {
146-
return result, err
147-
}
148-
return constructpgx.ScanRow[model.Customer](row)
144+
return constructpgx.ScanRow[model.Customer](
145+
qrbpgx.Build(q).WithExecutor(executor).QueryRow(ctx),
146+
)
149147
}
150148

151149
// CustomerChangeSet is generated by construct for handling partially filled models
@@ -165,12 +163,9 @@ func UpdateCustomer(ctx context.Context, executor qrbpgx.Executor, id uuid.UUID,
165163
Where(customer.ID.Eq(qrb.Arg(id))).
166164
SetMap(changeSet.toMap())
167165

168-
res, err := qrbpgx.Build(q).WithExecutor(executor).Exec(ctx)
169-
if err != nil {
170-
return err
171-
}
172-
173-
return constructpgx.AssertRowsAffected(res, "update", 1)
166+
return constructpgx.AssertRowsAffected("update", 1)(
167+
qrbpgx.Build(q).WithExecutor(executor).Exec(ctx),
168+
)
174169
}
175170

176171
func customerJson() builder.JsonBuildObjectBuilder {

constructpgx/constructpgx.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -61,13 +61,14 @@ func scanRow[T any](row pgx.Row) (T, error) {
6161
return result, nil
6262
}
6363

64-
// AssertRowsAffected checks if the given result affected exactly the expected number of rows.
65-
func AssertRowsAffected(result pgconn.CommandTag, operation string, expectedRows int) error {
66-
actualRows := result.RowsAffected()
67-
if actualRows != int64(expectedRows) {
68-
return fmt.Errorf("%s affected %d rows, but expected exactly %d", operation, actualRows, expectedRows)
69-
}
70-
71-
return nil
64+
// AssertRowsAffected returns a func that checks if the given operation result affected exactly the expected number of rows.
65+
func AssertRowsAffected(operation string, expectedRows int) func(pgconn.CommandTag) error {
66+
return func(result pgconn.CommandTag) error {
67+
actualRows := result.RowsAffected()
68+
if actualRows != int64(expectedRows) {
69+
return fmt.Errorf("%s affected %d rows, but expected exactly %d", operation, actualRows, expectedRows)
70+
}
7271

72+
return nil
73+
}
7374
}

constructpgx/constructpgx_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,12 +88,12 @@ func TestScanRow(t *testing.T) {
8888

8989
func TestAssertRowsAffected(t *testing.T) {
9090
t.Run("returns nil if rows affected matches expected", func(t *testing.T) {
91-
err := constructpgx.AssertRowsAffected(pgconn.NewCommandTag("UPDATE 2"), "update", 2)
91+
err := constructpgx.AssertRowsAffected("update", 2)(pgconn.NewCommandTag("UPDATE 2"))
9292
require.NoError(t, err)
9393
})
9494

9595
t.Run("returns error if rows affected does not match expected", func(t *testing.T) {
96-
err := constructpgx.AssertRowsAffected(pgconn.NewCommandTag("UPDATE 2"), "update", 1)
96+
err := constructpgx.AssertRowsAffected("update", 1)(pgconn.NewCommandTag("UPDATE 2"))
9797
require.Error(t, err)
9898
})
9999
}

constructsql/constructsql.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,16 +71,20 @@ func scanRow[T any](row RowScanner) (result T, err error) {
7171
}
7272

7373
// AssertRowsAffected checks if the given result affected exactly the expected number of rows.
74-
func AssertRowsAffected(result sql.Result, operation string, expectedRows int) error {
75-
actualRows, err := result.RowsAffected()
76-
if err != nil {
77-
return fmt.Errorf("getting affected rows: %w", err)
78-
}
79-
80-
if actualRows != int64(expectedRows) {
81-
return fmt.Errorf("%s affected %d rows, but expected exactly %d", operation, actualRows, expectedRows)
82-
}
74+
func AssertRowsAffected(operation string, expectedRows int) func(sql.Result, error) error {
75+
return func(result sql.Result, err error) error {
76+
if err != nil {
77+
return err
78+
}
79+
actualRows, err := result.RowsAffected()
80+
if err != nil {
81+
return fmt.Errorf("getting affected rows: %w", err)
82+
}
8383

84-
return nil
84+
if actualRows != int64(expectedRows) {
85+
return fmt.Errorf("%s affected %d rows, but expected exactly %d", operation, actualRows, expectedRows)
86+
}
8587

88+
return nil
89+
}
8690
}

constructsql/constructsql_test.go

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,22 @@ func (r sqlResult) RowsAffected() (int64, error) {
100100

101101
func TestAssertRowsAffected(t *testing.T) {
102102
t.Run("returns nil if rows affected matches expected", func(t *testing.T) {
103-
104-
err := constructsql.AssertRowsAffected(sqlResult{affectedRows: 2}, "update", 2)
103+
err := constructsql.AssertRowsAffected("update", 2)(sqlResult{affectedRows: 2}, nil)
105104
require.NoError(t, err)
106105
})
107106

108107
t.Run("returns error if rows affected does not match expected", func(t *testing.T) {
109-
err := constructsql.AssertRowsAffected(sqlResult{affectedRows: 2}, "update", 1)
108+
err := constructsql.AssertRowsAffected("update", 1)(sqlResult{affectedRows: 2}, nil)
110109
require.Error(t, err)
111110
})
112111

113112
t.Run("returns error if rows affected returns error", func(t *testing.T) {
114-
err := constructsql.AssertRowsAffected(sqlResult{affectedRowsErr: errors.New("some error")}, "update", 1)
113+
err := constructsql.AssertRowsAffected("update", 1)(sqlResult{affectedRowsErr: errors.New("some error")}, nil)
114+
require.Error(t, err)
115+
})
116+
117+
t.Run("returns previous error", func(t *testing.T) {
118+
err := constructsql.AssertRowsAffected("update", 1)(sqlResult{}, errors.New("some error"))
115119
require.Error(t, err)
116120
})
117121
}

0 commit comments

Comments
 (0)