package dbc import ( "context" "database/sql" "time" ) type connOrTx interface { executer queryPerformer } type executer interface { // Exec executes a query and does not expect any result. Exec(ctx context.Context, query string, args ...interface{}) ExecResult ExecNamed(ctx context.Context, query string, arg interface{}) ExecResult } type queryPerformer interface { // Query executes a query and returns a result object that can later be used // to retrieve values. Query(ctx context.Context, query string, args ...interface{}) Rows QueryNamed(ctx context.Context, query string, arg interface{}) Rows } type stdConnOrTx interface { ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) } type caller struct { db stdConnOrTx cb *callbacks } func (c *caller) Exec(ctx context.Context, query string, args ...interface{}) ExecResult { c.cb.callBefore(ctx, query) startedAt := time.Now() res, err := c.db.ExecContext(ctx, query, args...) c.cb.callAfter(ctx, query, time.Since(startedAt), err) return &execResult{ db: c, err: err, res: res, } } func (c *caller) ExecNamed(ctx context.Context, query string, arg interface{}) ExecResult { params, err := newNamedParams(arg) if err != nil { return &execResult{err: err} } preparedQuery, args, err := prepareNamedQuery(query, params) if err != nil { return &execResult{err: err} } return c.Exec(ctx, preparedQuery, args...) } func (c *caller) Query(ctx context.Context, query string, args ...interface{}) Rows { c.cb.callBefore(ctx, query) startedAt := time.Now() r, err := c.db.QueryContext(ctx, query, args...) c.cb.callAfter(ctx, query, time.Since(startedAt), err) return &rows{ err: err, rows: r, } } func (c *caller) QueryNamed(ctx context.Context, query string, arg interface{}) Rows { params, err := newNamedParams(arg) if err != nil { return &rows{err: err} } preparedQuery, args, err := prepareNamedQuery(query, params) if err != nil { return &rows{err: err} } return c.Query(ctx, preparedQuery, args...) }