Documentation ¶
Overview ¶
Package prep instruments instruments db connection with prepared statements. It allows you to benefit from the prepared SQL statements almost without any changes to your code.
Prep consists of two parts:
1. A command line tool that finds all SQL statements in your code
2. A package that instruments your code with prepared SQL statements using the found ones
Firstly you should generate a list of SQL statements used in your application
$ cat github.com/hexdigest/prepdemo/example.go func main() { db, err := sql.Open("mysql", "user:pass@tcp(localhost:3306)/mysql") if err != nil { panic(err) } const query = `SELECT CONCAT("Hello ", ?, "!")` var s string if err := db.QueryRow(query, "World").Scan(&s); err != nil { panic(err) } fmt.Println(s) }
Let's generate a list of the SQL statements used in your package:
$ prep -f github.com/hexdigest/prepdemo $ cat prepared_statements.go //go:generate prep -f github.com/hexdigest/prepdemo package main var prepStatements = []string{ "SELECT CONCAT(\"Hello \", ?, \"!\")", }
Using prepared statements:
func main() { sqlDB, err := sql.Open("mysql", "root:root@tcp(localhost:3306)/mysql") if err != nil { panic(err) } db, err := prep.NewConnection(sqlDB, prepStatements) if err != nil { panic(err) } const query = `SELECT CONCAT("Hello ", ?, "!")` var s string if err := db.QueryRow(query, "World").Scan(&s); err != nil { panic(err) } fmt.Println(s) }
Take a look at the line:
db, err := prep.NewConnection(sqlDB, prepStatements)
It instruments your connection with prepared statements found by the generator. The generated code already contains //go:generate instruction, so in order to update the statements list you can simply run:
$ go generate
Some synthetic benchmarks:
$ go test -bench=. BenchmarkPostgresWithoutPreparedStatements-4 20000 59941 ns/op 1183 B/op 32 allocs/op BenchmarkPostgresWithPreparedStatements-4 50000 41560 ns/op 1021 B/op 26 allocs/op BenchmarkMySQLWithoutPreparedStatements-4 50000 26454 ns/op 827 B/op 23 allocs/op BenchmarkMySQLWithPreparedStatements-4 200000 9509 ns/op 634 B/op 19 allocs/op PASS ok github.com/hexdigest/prep 7.884s
Index ¶
- type Connection
- func (c *Connection) Exec(query string, args ...interface{}) (sql.Result, error)
- func (c *Connection) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
- func (c *Connection) Prepare(query string) (*sql.Stmt, error)
- func (c *Connection) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error)
- func (c *Connection) Query(query string, args ...interface{}) (*sql.Rows, error)
- func (c *Connection) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
- func (c *Connection) QueryRow(query string, args ...interface{}) *sql.Row
- func (c *Connection) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
- type Connector
- type PreparedStatement
- type Querier
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Connection ¶
type Connection struct { Querier // contains filtered or unexported fields }
Connection is a wrapper for Connector instrumented with prepared SQL statements
func NewConnection ¶
func NewConnection(c Connector, statements []string) (*Connection, error)
NewConnection creates prepared statements for all statements in the given list and returns an implementation of the Connector interface instrumented with prepared statements
func (*Connection) Exec ¶
func (c *Connection) Exec(query string, args ...interface{}) (sql.Result, error)
Exec implements executer
func (*Connection) ExecContext ¶
func (c *Connection) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
ExecContext implements executerWithContext
func (*Connection) Prepare ¶
func (c *Connection) Prepare(query string) (*sql.Stmt, error)
Prepare implements preparer
func (*Connection) PrepareContext ¶
PrepareContext implements preparerWithContext
func (*Connection) Query ¶
func (c *Connection) Query(query string, args ...interface{}) (*sql.Rows, error)
Query implements querier
func (*Connection) QueryContext ¶
func (c *Connection) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)
QueryContext implements querierWithContext
func (*Connection) QueryRow ¶
func (c *Connection) QueryRow(query string, args ...interface{}) *sql.Row
QueryRow implements rowQuerier
func (*Connection) QueryRowContext ¶
func (c *Connection) QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row
QueryRowContext implements querierWithContext
type Connector ¶
type Connector interface { Querier // contains filtered or unexported methods }
Connector contains all exportable methods of the database/sql.DB
type PreparedStatement ¶
type PreparedStatement interface { Exec(args ...interface{}) (sql.Result, error) ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error) QueryRow(args ...interface{}) *sql.Row QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row Query(args ...interface{}) (*sql.Rows, error) QueryContext(ctx context.Context, args ...interface{}) (*sql.Rows, error) }
PreparedStatement is implemented by *sql.Stmt