Added more docs
This commit is contained in:
@@ -131,6 +131,15 @@ func (c *Connection) Close() (err error) {
|
|||||||
return c.txMsg('X', c.getBuf())
|
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) {
|
func (c *Connection) SelectFunc(sql string, onDataRow func(*DataRowReader) error, arguments ...interface{}) (err error) {
|
||||||
var fields []FieldDescription
|
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) {
|
func (c *Connection) SelectRows(sql string, arguments ...interface{}) (rows []map[string]interface{}, err error) {
|
||||||
rows = make([]map[string]interface{}, 0, 8)
|
rows = make([]map[string]interface{}, 0, 8)
|
||||||
onDataRow := func(r *DataRowReader) error {
|
onDataRow := func(r *DataRowReader) error {
|
||||||
@@ -179,6 +192,11 @@ func (c *Connection) SelectRows(sql string, arguments ...interface{}) (rows []ma
|
|||||||
return
|
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
|
// Returns a NotSingleRowError if exactly one row is not found
|
||||||
func (c *Connection) SelectRow(sql string, arguments ...interface{}) (row map[string]interface{}, err error) {
|
func (c *Connection) SelectRow(sql string, arguments ...interface{}) (row map[string]interface{}, err error) {
|
||||||
var numRowsFound int64
|
var numRowsFound int64
|
||||||
@@ -195,6 +213,11 @@ func (c *Connection) SelectRow(sql string, arguments ...interface{}) (row map[st
|
|||||||
return
|
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 UnexpectedColumnCountError if exactly one column is not found
|
||||||
// Returns a NotSingleRowError if exactly one row 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) {
|
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
|
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
|
// Returns a UnexpectedColumnCountError if exactly one column is not found
|
||||||
func (c *Connection) SelectValues(sql string, arguments ...interface{}) (values []interface{}, err error) {
|
func (c *Connection) SelectValues(sql string, arguments ...interface{}) (values []interface{}, err error) {
|
||||||
values = make([]interface{}, 0, 8)
|
values = make([]interface{}, 0, 8)
|
||||||
@@ -233,6 +261,8 @@ func (c *Connection) SelectValues(sql string, arguments ...interface{}) (values
|
|||||||
return
|
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) {
|
func (c *Connection) Prepare(name, sql string) (err error) {
|
||||||
// parse
|
// parse
|
||||||
buf := c.getBuf()
|
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) {
|
func (c *Connection) Deallocate(name string) (err error) {
|
||||||
delete(c.preparedStatements, name)
|
delete(c.preparedStatements, name)
|
||||||
_, err = c.Execute("deallocate " + c.QuoteIdentifier(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) {
|
func (c *Connection) Execute(sql string, arguments ...interface{}) (commandTag string, err error) {
|
||||||
if err = c.sendQuery(sql, arguments...); err != nil {
|
if err = c.sendQuery(sql, arguments...); err != nil {
|
||||||
return
|
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) {
|
func (c *Connection) Transaction(f func() bool) (committed bool, err error) {
|
||||||
return c.transaction("", f)
|
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) {
|
func (c *Connection) TransactionIso(isoLevel string, f func() bool) (committed bool, err error) {
|
||||||
return c.transaction(isoLevel, f)
|
return c.transaction(isoLevel, f)
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-7
@@ -6,8 +6,9 @@ type ConnectionPool struct {
|
|||||||
MaxConnections int
|
MaxConnections int
|
||||||
}
|
}
|
||||||
|
|
||||||
// options: options used by Connect
|
// NewConnectionPool creates a new ConnectionPool. options are passed through to
|
||||||
// MaxConnections: max simultaneous connections to use (currently all are immediately connected)
|
// Connect directly. MaxConnections is max simultaneous connections to use
|
||||||
|
// (currently all are immediately connected).
|
||||||
func NewConnectionPool(parameters ConnectionParameters, MaxConnections int) (p *ConnectionPool, err error) {
|
func NewConnectionPool(parameters ConnectionParameters, MaxConnections int) (p *ConnectionPool, err error) {
|
||||||
p = new(ConnectionPool)
|
p = new(ConnectionPool)
|
||||||
p.connectionChannel = make(chan *Connection, MaxConnections)
|
p.connectionChannel = make(chan *Connection, MaxConnections)
|
||||||
@@ -27,11 +28,13 @@ func NewConnectionPool(parameters ConnectionParameters, MaxConnections int) (p *
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Acquire takes exclusive use of a connection until it is released.
|
||||||
func (p *ConnectionPool) Acquire() (c *Connection) {
|
func (p *ConnectionPool) Acquire() (c *Connection) {
|
||||||
c = <-p.connectionChannel
|
c = <-p.connectionChannel
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Release gives up use of a connection.
|
||||||
func (p *ConnectionPool) Release(c *Connection) {
|
func (p *ConnectionPool) Release(c *Connection) {
|
||||||
if c.txStatus != 'I' {
|
if c.txStatus != 'I' {
|
||||||
c.Execute("rollback")
|
c.Execute("rollback")
|
||||||
@@ -39,6 +42,7 @@ func (p *ConnectionPool) Release(c *Connection) {
|
|||||||
p.connectionChannel <- c
|
p.connectionChannel <- c
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Close ends the use of a connection by closing all underlying connections.
|
||||||
func (p *ConnectionPool) Close() {
|
func (p *ConnectionPool) Close() {
|
||||||
for i := 0; i < p.MaxConnections; i++ {
|
for i := 0; i < p.MaxConnections; i++ {
|
||||||
c := <-p.connectionChannel
|
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) {
|
func (p *ConnectionPool) SelectFunc(sql string, onDataRow func(*DataRowReader) error, arguments ...interface{}) (err error) {
|
||||||
c := p.Acquire()
|
c := p.Acquire()
|
||||||
defer p.Release(c)
|
defer p.Release(c)
|
||||||
@@ -54,7 +58,7 @@ func (p *ConnectionPool) SelectFunc(sql string, onDataRow func(*DataRowReader) e
|
|||||||
return c.SelectFunc(sql, onDataRow, arguments...)
|
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) {
|
func (p *ConnectionPool) SelectRows(sql string, arguments ...interface{}) (rows []map[string]interface{}, err error) {
|
||||||
c := p.Acquire()
|
c := p.Acquire()
|
||||||
defer p.Release(c)
|
defer p.Release(c)
|
||||||
@@ -62,7 +66,7 @@ func (p *ConnectionPool) SelectRows(sql string, arguments ...interface{}) (rows
|
|||||||
return c.SelectRows(sql, arguments...)
|
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) {
|
func (p *ConnectionPool) SelectRow(sql string, arguments ...interface{}) (row map[string]interface{}, err error) {
|
||||||
c := p.Acquire()
|
c := p.Acquire()
|
||||||
defer p.Release(c)
|
defer p.Release(c)
|
||||||
@@ -70,7 +74,7 @@ func (p *ConnectionPool) SelectRow(sql string, arguments ...interface{}) (row ma
|
|||||||
return c.SelectRow(sql, arguments...)
|
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) {
|
func (p *ConnectionPool) SelectValue(sql string, arguments ...interface{}) (v interface{}, err error) {
|
||||||
c := p.Acquire()
|
c := p.Acquire()
|
||||||
defer p.Release(c)
|
defer p.Release(c)
|
||||||
@@ -78,7 +82,7 @@ func (p *ConnectionPool) SelectValue(sql string, arguments ...interface{}) (v in
|
|||||||
return c.SelectValue(sql, arguments...)
|
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) {
|
func (p *ConnectionPool) SelectValues(sql string, arguments ...interface{}) (values []interface{}, err error) {
|
||||||
c := p.Acquire()
|
c := p.Acquire()
|
||||||
defer p.Release(c)
|
defer p.Release(c)
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
package pgx
|
package pgx
|
||||||
|
|
||||||
|
// DataRowReader is used by SelectFunc to process incoming rows.
|
||||||
type DataRowReader struct {
|
type DataRowReader struct {
|
||||||
mr *MessageReader
|
mr *MessageReader
|
||||||
fields []FieldDescription
|
fields []FieldDescription
|
||||||
@@ -19,6 +20,7 @@ func newDataRowReader(mr *MessageReader, fields []FieldDescription) (r *DataRowR
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ReadValue returns the next value from the current row.
|
||||||
func (r *DataRowReader) ReadValue() interface{} {
|
func (r *DataRowReader) ReadValue() interface{} {
|
||||||
fieldDescription := r.fields[r.currentFieldIdx]
|
fieldDescription := r.fields[r.currentFieldIdx]
|
||||||
r.currentFieldIdx++
|
r.currentFieldIdx++
|
||||||
|
|||||||
@@ -10,16 +10,23 @@ import (
|
|||||||
|
|
||||||
var literalPattern *regexp.Regexp = regexp.MustCompile(`\$\d+`)
|
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) {
|
func (c *Connection) QuoteString(input string) (output string) {
|
||||||
output = "'" + strings.Replace(input, "'", "''", -1) + "'"
|
output = "'" + strings.Replace(input, "'", "''", -1) + "'"
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// QuoteIdentifier escapes and quotes an identifier making it safe for
|
||||||
|
// interpolation into an SQL string
|
||||||
func (c *Connection) QuoteIdentifier(input string) (output string) {
|
func (c *Connection) QuoteIdentifier(input string) (output string) {
|
||||||
output = `"` + strings.Replace(input, `"`, `""`, -1) + `"`
|
output = `"` + strings.Replace(input, `"`, `""`, -1) + `"`
|
||||||
return
|
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) {
|
func (c *Connection) SanitizeSql(sql string, args ...interface{}) (output string) {
|
||||||
replacer := func(match string) (replacement string) {
|
replacer := func(match string) (replacement string) {
|
||||||
n, _ := strconv.ParseInt(match[1:], 10, 0)
|
n, _ := strconv.ParseInt(match[1:], 10, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user