11 // TODO(kr): many databases—Postgres in particular—report the
12 // execution time of each query or statement as measured on the
13 // database backend. Find a way to record that timing info in
16 const maxArgsLogLen = 20 // bytes
18 func logQuery(ctx context.Context, query string, args interface{}) {
20 if len(s) > maxArgsLogLen {
21 s = s[:maxArgsLogLen-3] + "..."
23 log.Printkv(ctx, "query", query, "args", s)
26 type logDriver struct {
30 // LogDriver returns a Driver that logs each query
31 // before forwarding it to d.
32 func LogDriver(d driver.Driver) driver.Driver {
36 func (ld *logDriver) Open(name string) (driver.Conn, error) {
37 c, err := ld.driver.Open(name)
38 return &logConn{c}, err
45 func (lc *logConn) Prepare(query string) (driver.Stmt, error) {
46 stmt, err := lc.Conn.Prepare(query)
47 return &logStmt{query, stmt}, err
50 func (lc *logConn) Exec(query string, args []driver.Value) (driver.Result, error) {
51 execer, ok := lc.Conn.(driver.Execer)
53 return nil, driver.ErrSkip
55 logQuery(context.Background(), query, args)
56 return execer.Exec(query, args)
59 func (lc *logConn) Query(query string, args []driver.Value) (driver.Rows, error) {
60 queryer, ok := lc.Conn.(driver.Queryer)
62 return nil, driver.ErrSkip
64 logQuery(context.Background(), query, args)
65 return queryer.Query(query, args)
68 // TODO(kr): implement context variants
69 // (but don't bother until lib/pq does first).
70 //func (lc *logConn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error)
71 //func (lc *logConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error)
72 //func (lc *logConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error)
79 func (ls *logStmt) Exec(args []driver.Value) (driver.Result, error) {
80 logQuery(context.Background(), ls.query, args)
81 return ls.Stmt.Exec(args)
84 func (ls *logStmt) Query(args []driver.Value) (driver.Rows, error) {
85 logQuery(context.Background(), ls.query, args)
86 return ls.Stmt.Query(args)