Added more docs

pgx-vs-pq
Jack Christensen 2013-07-15 08:14:32 -05:00
parent 0de2a7897a
commit 1d1d836207
4 changed files with 68 additions and 7 deletions

View File

@ -131,6 +131,15 @@ func (c *Connection) Close() (err error) {
return c.txMsg('X', c.getBuf())
}
// SelectFunc executes sql and for each row returned calls onDataRow. sql can be
// either a prepared statement name or an SQL string. arguments will be sanitized
// before being interpolated into sql strings. arguments should be referenced
// positionally from the sql string as $1, $2, etc.
//
// SelectFunc calls onDataRow as the rows are received. This means that it does not
// need to simultaneously store the entire result set in memory. It also means that
// it is possible to process some rows and then for an error to occur. Callers
// should be aware of this possibility.
func (c *Connection) SelectFunc(sql string, onDataRow func(*DataRowReader) error, arguments ...interface{}) (err error) {
var fields []FieldDescription
@ -169,6 +178,10 @@ func (c *Connection) SelectFunc(sql string, onDataRow func(*DataRowReader) error
}
}
// SelectRows executes sql and returns a slice of maps representing the found rows.
// sql can be either a prepared statement name or an SQL string. arguments will be
// sanitized before being interpolated into sql strings. arguments should be referenced
// positionally from the sql string as $1, $2, etc.
func (c *Connection) SelectRows(sql string, arguments ...interface{}) (rows []map[string]interface{}, err error) {
rows = make([]map[string]interface{}, 0, 8)
onDataRow := func(r *DataRowReader) error {
@ -179,6 +192,11 @@ func (c *Connection) SelectRows(sql string, arguments ...interface{}) (rows []ma
return
}
// SelectRow executes sql and returns a map representing the found row.
// sql can be either a prepared statement name or an SQL string. arguments will be
// sanitized before being interpolated into sql strings. arguments should be referenced
// positionally from the sql string as $1, $2, etc.
//
// Returns a NotSingleRowError if exactly one row is not found
func (c *Connection) SelectRow(sql string, arguments ...interface{}) (row map[string]interface{}, err error) {
var numRowsFound int64
@ -195,6 +213,11 @@ func (c *Connection) SelectRow(sql string, arguments ...interface{}) (row map[st
return
}
// SelectValue executes sql and returns a single value. sql can be either a prepared
// statement name or an SQL string. arguments will be sanitized before being
// interpolated into sql strings. arguments should be referenced positionally from
// the sql string as $1, $2, etc.
//
// Returns a UnexpectedColumnCountError if exactly one column is not found
// Returns a NotSingleRowError if exactly one row is not found
func (c *Connection) SelectValue(sql string, arguments ...interface{}) (v interface{}, err error) {
@ -218,6 +241,11 @@ func (c *Connection) SelectValue(sql string, arguments ...interface{}) (v interf
return
}
// SelectValues executes sql and returns a slice of values. sql can be either a prepared
// statement name or an SQL string. arguments will be sanitized before being
// interpolated into sql strings. arguments should be referenced positionally from
// the sql string as $1, $2, etc.
//
// Returns a UnexpectedColumnCountError if exactly one column is not found
func (c *Connection) SelectValues(sql string, arguments ...interface{}) (values []interface{}, err error) {
values = make([]interface{}, 0, 8)
@ -233,6 +261,8 @@ func (c *Connection) SelectValues(sql string, arguments ...interface{}) (values
return
}
// Prepare creates a prepared statement with name and sql. sql can contain placeholders
// for bound parameters. These placeholders are referenced positional as $1, $2, etc.
func (c *Connection) Prepare(name, sql string) (err error) {
// parse
buf := c.getBuf()
@ -299,6 +329,7 @@ func (c *Connection) Prepare(name, sql string) (err error) {
}
}
// Deallocate released a prepared statement
func (c *Connection) Deallocate(name string) (err error) {
delete(c.preparedStatements, name)
_, err = c.Execute("deallocate " + c.QuoteIdentifier(name))
@ -403,6 +434,9 @@ func (c *Connection) sendPreparedQuery(ps *preparedStatement, arguments ...inter
}
// Execute executes sql. sql can be either a prepared statement name or an SQL string.
// arguments will be sanitized before being interpolated into sql strings. arguments
// should be referenced positionally from the sql string as $1, $2, etc.
func (c *Connection) Execute(sql string, arguments ...interface{}) (commandTag string, err error) {
if err = c.sendQuery(sql, arguments...); err != nil {
return
@ -430,10 +464,24 @@ func (c *Connection) Execute(sql string, arguments ...interface{}) (commandTag s
}
}
// Transaction runs f in a transaction. f should return true if the transaction
// should be committed or false if it should be rolled back. Return value committed
// is if the transaction was committed or not. committed should be checked separately
// from err as an explicit rollback is not an error. Transaction will use the default
// isolation level for the current connection. To use a specific isolation level see
// TransactionIso
func (c *Connection) Transaction(f func() bool) (committed bool, err error) {
return c.transaction("", f)
}
// TransactionIso is the same as Transaction except it takes an isoLevel argument that
// it uses as the transaction isolation level.
//
// Valid isolation levels are:
// serializable
// repeatable read
// read committed
// read uncommitted
func (c *Connection) TransactionIso(isoLevel string, f func() bool) (committed bool, err error) {
return c.transaction(isoLevel, f)
}

View File

@ -6,8 +6,9 @@ type ConnectionPool struct {
MaxConnections int
}
// options: options used by Connect
// MaxConnections: max simultaneous connections to use (currently all are immediately connected)
// NewConnectionPool creates a new ConnectionPool. options are passed through to
// Connect directly. MaxConnections is max simultaneous connections to use
// (currently all are immediately connected).
func NewConnectionPool(parameters ConnectionParameters, MaxConnections int) (p *ConnectionPool, err error) {
p = new(ConnectionPool)
p.connectionChannel = make(chan *Connection, MaxConnections)
@ -27,11 +28,13 @@ func NewConnectionPool(parameters ConnectionParameters, MaxConnections int) (p *
return
}
// Acquire takes exclusive use of a connection until it is released.
func (p *ConnectionPool) Acquire() (c *Connection) {
c = <-p.connectionChannel
return
}
// Release gives up use of a connection.
func (p *ConnectionPool) Release(c *Connection) {
if c.txStatus != 'I' {
c.Execute("rollback")
@ -39,6 +42,7 @@ func (p *ConnectionPool) Release(c *Connection) {
p.connectionChannel <- c
}
// Close ends the use of a connection by closing all underlying connections.
func (p *ConnectionPool) Close() {
for i := 0; i < p.MaxConnections; i++ {
c := <-p.connectionChannel
@ -46,7 +50,7 @@ func (p *ConnectionPool) Close() {
}
}
// Acquires a connection, delegates the call to that connection, and releases the connection
// SelectFunc acquires a connection, delegates the call to that connection, and releases the connection
func (p *ConnectionPool) SelectFunc(sql string, onDataRow func(*DataRowReader) error, arguments ...interface{}) (err error) {
c := p.Acquire()
defer p.Release(c)
@ -54,7 +58,7 @@ func (p *ConnectionPool) SelectFunc(sql string, onDataRow func(*DataRowReader) e
return c.SelectFunc(sql, onDataRow, arguments...)
}
// Acquires a connection, delegates the call to that connection, and releases the connection
// SelectRows acquires a connection, delegates the call to that connection, and releases the connection
func (p *ConnectionPool) SelectRows(sql string, arguments ...interface{}) (rows []map[string]interface{}, err error) {
c := p.Acquire()
defer p.Release(c)
@ -62,7 +66,7 @@ func (p *ConnectionPool) SelectRows(sql string, arguments ...interface{}) (rows
return c.SelectRows(sql, arguments...)
}
// Acquires a connection, delegates the call to that connection, and releases the connection
// SelectRow acquires a connection, delegates the call to that connection, and releases the connection
func (p *ConnectionPool) SelectRow(sql string, arguments ...interface{}) (row map[string]interface{}, err error) {
c := p.Acquire()
defer p.Release(c)
@ -70,7 +74,7 @@ func (p *ConnectionPool) SelectRow(sql string, arguments ...interface{}) (row ma
return c.SelectRow(sql, arguments...)
}
// Acquires a connection, delegates the call to that connection, and releases the connection
// SelectValue acquires a connection, delegates the call to that connection, and releases the connection
func (p *ConnectionPool) SelectValue(sql string, arguments ...interface{}) (v interface{}, err error) {
c := p.Acquire()
defer p.Release(c)
@ -78,7 +82,7 @@ func (p *ConnectionPool) SelectValue(sql string, arguments ...interface{}) (v in
return c.SelectValue(sql, arguments...)
}
// Acquires a connection, delegates the call to that connection, and releases the connection
// SelectValues acquires a connection, delegates the call to that connection, and releases the connection
func (p *ConnectionPool) SelectValues(sql string, arguments ...interface{}) (values []interface{}, err error) {
c := p.Acquire()
defer p.Release(c)

View File

@ -1,5 +1,6 @@
package pgx
// DataRowReader is used by SelectFunc to process incoming rows.
type DataRowReader struct {
mr *MessageReader
fields []FieldDescription
@ -19,6 +20,7 @@ func newDataRowReader(mr *MessageReader, fields []FieldDescription) (r *DataRowR
return
}
// ReadValue returns the next value from the current row.
func (r *DataRowReader) ReadValue() interface{} {
fieldDescription := r.fields[r.currentFieldIdx]
r.currentFieldIdx++

View File

@ -10,16 +10,23 @@ import (
var literalPattern *regexp.Regexp = regexp.MustCompile(`\$\d+`)
// QuoteString escapes and quotes a string making it safe for interpolation
// into an SQL string.
func (c *Connection) QuoteString(input string) (output string) {
output = "'" + strings.Replace(input, "'", "''", -1) + "'"
return
}
// QuoteIdentifier escapes and quotes an identifier making it safe for
// interpolation into an SQL string
func (c *Connection) QuoteIdentifier(input string) (output string) {
output = `"` + strings.Replace(input, `"`, `""`, -1) + `"`
return
}
// SanitizeSql substitutely args positionaly into sql. Placeholder values are
// $ prefixed integers like $1, $2, $3, etc. args are sanitized and quoted as
// appropriate.
func (c *Connection) SanitizeSql(sql string, args ...interface{}) (output string) {
replacer := func(match string) (replacement string) {
n, _ := strconv.ParseInt(match[1:], 10, 0)