• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

stephenafamo / bob / 14894663959

07 May 2025 10:44PM UTC coverage: 41.359% (-0.1%) from 41.458%
14894663959

push

github

web-flow
Merge pull request #408 from stephenafamo/testing

Improve testing

64 of 132 new or added lines in 8 files covered. (48.48%)

1 existing line in 1 file now uncovered.

7397 of 17885 relevant lines covered (41.36%)

212.5 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

27.94
/stdlib.go
1
package bob
2

3
import (
4
        "context"
5
        "database/sql"
6
        "database/sql/driver"
7

8
        "github.com/stephenafamo/scan"
9
        "github.com/stephenafamo/scan/stdscan"
10
)
11

12
// NewQueryer wraps an [stdscan.Queryer] and makes it a [scan.Queryer]
13
func NewQueryer[T stdscan.Queryer](wrapped T) scan.Queryer {
×
14
        return commonQueryer[T]{wrapped: wrapped}
×
15
}
×
16

17
type commonQueryer[T stdscan.Queryer] struct {
18
        wrapped T
19
}
20

21
// QueryContext executes a query that returns rows, typically a SELECT. The args are for any placeholder parameters in the query.
22
func (q commonQueryer[T]) QueryContext(ctx context.Context, query string, args ...any) (scan.Rows, error) {
4✔
23
        return q.wrapped.QueryContext(ctx, query, args...)
4✔
24
}
4✔
25

26
// StdInterface is an interface that *sql.DB, *sql.Tx and *sql.Conn satisfy
27
type StdInterface interface {
28
        stdscan.Queryer
29
        ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error)
30
        PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
31
}
32

33
// New wraps an stdInterface to make it comply with Queryer
34
// It also includes a number of other methods that are often used with
35
// *sql.DB, *sql.Tx and *sql.Conn
36
func New[T StdInterface](wrapped T) common[T] {
2✔
37
        return common[T]{commonQueryer[T]{wrapped: wrapped}}
2✔
38
}
2✔
39

40
type common[T StdInterface] struct {
41
        commonQueryer[T]
42
}
43

44
// PrepareContext creates a prepared statement for later queries or executions
45
func (c common[T]) PrepareContext(ctx context.Context, query string) (StdPrepared, error) {
×
46
        s, err := c.wrapped.PrepareContext(ctx, query)
×
47
        return StdPrepared{s}, err
×
48
}
×
49

50
// ExecContext executes a query without returning any rows. The args are for any placeholder parameters in the query.
51
func (q common[T]) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) {
4✔
52
        return q.wrapped.ExecContext(ctx, query, args...)
4✔
53
}
4✔
54

55
// Open works just like [sql.Open], but converts the returned [*sql.DB] to [DB]
56
func Open(driverName string, dataSource string) (DB, error) {
2✔
57
        db, err := sql.Open(driverName, dataSource)
2✔
58
        return NewDB(db), err
2✔
59
}
2✔
60

61
// OpenDB works just like [sql.OpenDB], but converts the returned [*sql.DB] to [DB]
62
func OpenDB(c driver.Connector) DB {
×
63
        return NewDB(sql.OpenDB(c))
×
64
}
×
65

66
// NewDB wraps an [*sql.DB] and returns a type that implements [Queryer] but still
67
// retains the expected methods used by *sql.DB
68
// This is useful when an existing *sql.DB is used in other places in the codebase
69
func NewDB(db *sql.DB) DB {
2✔
70
        return DB{common: New(db)}
2✔
71
}
2✔
72

73
// DB is similar to *sql.DB but implement [Queryer]
74
type DB struct {
75
        common[*sql.DB]
76
}
77

78
// PingContext verifies a connection to the database is still alive, establishing a connection if necessary.
79
func (d DB) PingContext(ctx context.Context) error {
×
80
        return d.wrapped.PingContext(ctx)
×
81
}
×
82

83
// Close works the same as [*sql.DB.Close]
84
func (d DB) Close() error {
2✔
85
        return d.wrapped.Close()
2✔
86
}
2✔
87

88
// BeginTx is similar to [*sql.DB.BeginTx], but return a transaction that
89
// implements [Queryer]
NEW
90
func (d DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (Transaction, error) {
×
91
        tx, err := d.wrapped.BeginTx(ctx, opts)
×
92
        if err != nil {
×
93
                return Tx{}, err
×
94
        }
×
95

96
        return NewTx(tx), nil
×
97
}
98

99
// NewTx wraps an [*sql.Tx] and returns a type that implements [Queryer] but still
100
// retains the expected methods used by *sql.Tx
101
// This is useful when an existing *sql.Tx is used in other places in the codebase
102
func NewTx(tx *sql.Tx) Tx {
×
103
        return Tx{New(tx)}
×
104
}
×
105

106
// Tx is similar to *sql.Tx but implements [Queryer]
107
type Tx struct {
108
        common[*sql.Tx]
109
}
110

111
// Commit works the same as [*sql.Tx.Commit]
112
func (t Tx) Commit() error {
×
113
        return t.wrapped.Commit()
×
114
}
×
115

116
// Rollback works the same as [*sql.Tx.Rollback]
117
func (t Tx) Rollback() error {
×
118
        return t.wrapped.Rollback()
×
119
}
×
120

NEW
121
func (tx Tx) StmtContext(ctx context.Context, stmt StdPrepared) StdPrepared {
×
122
        return StdPrepared{tx.wrapped.StmtContext(ctx, stmt.Stmt)}
×
123
}
×
124

125
// NewConn wraps an [*sql.Conn] and returns a type that implements [Queryer]
126
// This is useful when an existing *sql.Conn is used in other places in the codebase
127
func NewConn(conn *sql.Conn) Conn {
×
128
        return Conn{New(conn)}
×
129
}
×
130

131
// Conn is similar to *sql.Conn but implements [Queryer]
132
type Conn struct {
133
        common[*sql.Conn]
134
}
135

136
// PingContext verifies a connection to the database is still alive, establishing a connection if necessary.
137
func (c Conn) PingContext(ctx context.Context) error {
×
138
        return c.wrapped.PingContext(ctx)
×
139
}
×
140

141
// Close works the same as [*sql.Conn.Close]
142
func (c Conn) Close() error {
×
143
        return c.wrapped.Close()
×
144
}
×
145

146
// BeginTx is similar to [*sql.Conn.BeginTx], but return a transaction that
147
// implements [Queryer]
NEW
148
func (c Conn) BeginTx(ctx context.Context, opts *sql.TxOptions) (Transaction, error) {
×
149
        tx, err := c.wrapped.BeginTx(ctx, opts)
×
150
        if err != nil {
×
151
                return Tx{}, err
×
152
        }
×
153

154
        return NewTx(tx), nil
×
155
}
156

157
type StdPrepared struct {
158
        *sql.Stmt
159
}
160

161
func (s StdPrepared) QueryContext(ctx context.Context, args ...any) (scan.Rows, error) {
×
162
        return s.Stmt.QueryContext(ctx, args...)
×
163
}
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc