modulepackage
0.7.2
Repository: https://github.com/shogo82148/go-sql-proxy.git
Documentation: pkg.go.dev
# README
go-sql-proxy
The proxy package is a proxy driver for the database/sql package. You can hook SQL executions. It supports Go 1.8 or laster.
SYNOPSIS
Use Ready‐Made SQL tracer
proxy.RegisterTracer
is a shortcut for registering a SQL query tracer.
package main
import (
"context"
"database/sql"
"github.com/shogo82148/go-sql-proxy"
)
func main() {
proxy.RegisterTracer()
db, _ := sql.Open("origin:trace", "data source")
db.Exec("CREATE TABLE t1 (id INTEGER PRIMARY KEY)")
// STDERR: main.go:14: Exec: CREATE TABLE t1 (id INTEGER PRIMARY KEY); args = [] (0s)
}
Use proxy.NewTraceProxy
to change the log output destination.
logger := New(os.Stderr, "", LstdFlags)
tracer := NewTraceProxy(&another.Driver{}, logger)
sql.Register("origin:trace", tracer)
db, err := sql.Open("origin:tracer", "data source")
Use with the context package
From Go version 1.8 onward, database/sql supports the context package. You can register your hooks into the context.
package main
import (
"context"
"database/sql"
"github.com/shogo82148/go-sql-proxy"
)
var tracer = proxy.NewTraceHooks(proxy.TracerOptions{})
func main() {
proxy.RegisterProxy()
db, _ := sql.Open("origin:proxy", "data source")
// The tracer is enabled in this context.
ctx := proxy.WithHooks(context.Background(), tracer)
db.ExecContext(ctx, "CREATE TABLE t1 (id INTEGER PRIMARY KEY)")
}
Create your own hooks
First, register new proxy driver.
hooks := &proxy.HooksContext{
// Hook functions here(Open, Exec, Query, etc.)
// See godoc for more details
}
sql.Register("new-proxy-name", proxy.NewProxyContext(&origin.Driver{}, hooks))
And then, open new database handle with the registered proxy driver.
db, err := sql.Open("new-proxy-name", "data source")
EXAMPLES
EXAMPLE: SQL tracer
package main
import (
"context"
"database/sql"
"database/sql/driver"
"log"
"github.com/mattn/go-sqlite3"
"github.com/shogo82148/go-sql-proxy"
)
func main() {
sql.Register("sqlite3-proxy", proxy.NewProxyContext(&sqlite3.SQLiteDriver{}, &proxy.HooksContext{
Open: func(_ context.Context, _ interface{}, conn *proxy.Conn) error {
log.Println("Open")
return nil
},
Exec: func(_ context.Context, _ interface{}, stmt *proxy.Stmt, args []driver.NamedValue, result driver.Result) error {
log.Printf("Exec: %s; args = %v\n", stmt.QueryString, args)
return nil
},
Query: func(_ context.Context, _ interface{}, stmt *proxy.Stmt, args []driver.NamedValue, rows driver.Rows) error {
log.Printf("Query: %s; args = %v\n", stmt.QueryString, args)
return nil
},
Begin: func(_ context.Context, _ interface{}, conn *proxy.Conn) error {
log.Println("Begin")
return nil
},
Commit: func(_ context.Context, _ interface{}, tx *proxy.Tx) error {
log.Println("Commit")
return nil
},
Rollback: func(_ context.Context, _ interface{}, tx *proxy.Tx) error {
log.Println("Rollback")
return nil
},
}))
db, err := sql.Open("sqlite3-proxy", ":memory:")
if err != nil {
log.Fatalf("Open filed: %v", err)
}
defer db.Close()
_, err = db.Exec(
"CREATE TABLE t1 (id INTEGER PRIMARY KEY)",
)
if err != nil {
log.Fatal(err)
}
}
EXAMPLE: elapsed time logger
package main
import (
"context"
"database/sql"
"database/sql/driver"
"log"
"time"
"github.com/mattn/go-sqlite3"
"github.com/shogo82148/go-sql-proxy"
)
func main() {
sql.Register("sqlite3-proxy", proxy.NewProxyContext(&sqlite3.SQLiteDriver{}, &proxy.HooksContext{
PreExec: func(_ context.Context, _ *proxy.Stmt, _ []driver.NamedValue) (interface{}, error) {
// The first return value(time.Now()) is passed to both `Hooks.Exec` and `Hook.ExecPost` callbacks.
return time.Now(), nil
},
PostExec: func(_ context.Context, ctx interface{}, stmt *proxy.Stmt, args []driver.NamedValue, _ driver.Result, _ error) error {
// The `ctx` parameter is the return value supplied from the `Hooks.PreExec` method, and may be nil.
log.Printf("Query: %s; args = %v (%s)\n", stmt.QueryString, args, time.Since(ctx.(time.Time)))
return nil
},
}))
db, err := sql.Open("sqlite3-proxy", ":memory:")
if err != nil {
log.Fatalf("Open filed: %v", err)
}
defer db.Close()
_, err = db.Exec(
"CREATE TABLE t1 (id INTEGER PRIMARY KEY)",
)
if err != nil {
log.Fatal(err)
}
}
LICENSE
This software is released under the MIT License, see LICENSE file.
godoc
See godoc for more information.
# Functions
NewConnector creates new proxied Connector.
NewProxy creates new Proxy driver.
NewProxyContext creates new Proxy driver.
NewTraceHooks creates new HooksContext which trace SQL queries.
NewTraceProxy generates a proxy that logs queries.
NewTraceProxyWithFilter generates a proxy that logs queries.
RegisterProxy creates proxies that do not anything by default, and registers the proxies as sql driver.
RegisterTracer creates proxies that log queries from the sql drivers already registered, and registers the proxies as sql driver.
WithHooks returns a copy of parent context in which the hooks associated.
# Variables
DefaultPackageFilter ignores some database util package.
# Structs
Conn adds hook points into "database/sql/driver".Conn.
Connector adds hook points into "database/sql/driver".Connector.
Hooks is callback functions for the proxy.
HooksContext is callback functions with context.Context for the proxy.
Proxy is a sql driver.
Stmt adds hook points into "database/sql/driver".Stmt.
TracerOptions holds the tracing option.
Tx adds hook points into "database/sql/driver".Tx.
# Type aliases
PackageFilter is an implementation of Filter.