From c6bf85bd633b79c6c0d1a573c69486af995f7427 Mon Sep 17 00:00:00 2001 From: Jack Christensen Date: Tue, 30 Jul 2013 17:53:59 -0500 Subject: [PATCH] Add more docs and explanation --- README.md | 128 ++++++++++++++++++++++++++++++++++++++++++-- value_transcoder.go | 2 +- 2 files changed, 125 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ccc2e914..f9901c9d 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,131 @@ PostgreSQL client library for Go -## Usage +## Description -TODO +Pgx is a database connection library designed specifically for PostgreSQL. +There are features of PostgreSQL that are difficult or impossible to use with +the standard Go library SQL interface. This library trades conformity with the +standard interface for ease of use and the power that is available when +working directly with PostgreSQL. -## Development +## Features + +Below are some of the standout features of pgx. + +### Simple Query Interface + +Pgx has easy to use functions for common query operations like SelectValue, +SelectValues, SelectRow, and SelectRows. These can be easier to use than the +standard Scan interface. These directly return interface{}, []interface{}, +map[string]interface{}, and []map[string]interface{} respectively. SelectFunc +offers custom row by row processing. + + if widgets, err := conn.SelectRows("select * from widgets where type=$1", type); err != nil { + // do something with widgets + } + + +### Prepared Statements + +Prepared statements are easy to use in pgx. Just call Prepare with the name of +the statement and the SQL. To execute a prepared statement just pass the name +of the statement into a Select* or Execute command as the SQL text. It will +automatically detect that it is the name of a prepared statement and execute +it. + +```go +if err := conn.Prepare("getTime", "select now()"); err == nil { + // handle err +} +if time, err := conn.SelectValue("getTime"); err != nil { + // do something with time +} +``` + +Prepared statements will use the binary transmission format for types that +have a binary transcoder available (this can substantially reduce overhead +when using the bytea type). + +### Explicit Connection Pool + +Connection pool usage is explicit and configurable. The standard Go SQL +interface automatically uses a connection pool, and does not provide a way to +control the maximum number of connections (hopefully soon to change -- +https://code.google.com/p/go/issues/detail?id=4805). In pgx, a connection can +be created and managed directly, or a connection pool with a configurable +maximum connections can be used. Also, the connection pool offers an after +connect hook that allows every connection to be automatically setup before +being made available in the connection pool. This is especially useful to +ensure all connections have the same prepared statements available or to +change any other connection settings. + +It also delegates Select* and Execute functions to an automatically checked +out and released connection so you can have as much or as little control of +the connection pool as you need.. + +```go +if widgets, err := pool.SelectRows("select * from widgets where type=$1", type); err != nil { + // do something with widgets +} +``` + +### Transactions + +Transactions are are used by passing a function to the Transaction function. +This function ensures that the transaction is committed or rolled back +automatically. The TransactionIso variant creates a transaction with a +specified isolation level. + +```go +committed, err := conn.TransactionIso("serializable", func() bool { + // do something with transaction + return true // return true to commit / false to rollback +}) +``` + +### Listen / Notify + +Pgx can listen to the PostgreSQL notification system with the +WaitForNotification function. It takes a maximum time to wait for a +notification. + +```go +if notification, err := conn.WaitForNotification(time.Second); err != nil { + // do something with notification +} +``` + +### Custom Transcoder Support + +Pgx includes transcoders for the common data types like integers, floats, +strings, dates, and times that have direct mappings between Go and SQL. +Transcoders can be added for additional types like point, hstore, numeric, +etc. that do not have direct mappings in Go. Pgx has a map of PostgreSQL OID's +to transcoders. All that is needed to add or change how a data type is to set +that OID's transcoder. See example_value_transcoder_test.go for an example of +a custom transcoder for the PostgreSQL point type. + +### SelectValueTo + +There are some cases where go is used as an HTTP server that is directly +relaying single values from PostgreSQL (such as JSON r binary blobs). +SelectValueTo copies the single returned value directly from PostgreSQL to a +io.Writer. This can be faster especially when the values are at least many KB +in size. + +### Null Mapping + +As pgx uses interface{} for all values SQL nulls are mapped to nil. This +eliminates the need for wrapping values in structs that include a boolean for +the null possibility. On the downside, this does present difficulties dealing +with complex types such as arrays. pgx directly maps a Go []int32 to a +PostgreSQL int4[]. The problem is the PostgreSQL array can include nulls, but +the Go slice cannot. Because of this array transcoding should be considered +experimental. On the plus side, because of the pluggable transcoder support, +an application that wished to handle arrays (or any types) differently can +easily override the default transcoding (so even using a strict with value and +null fields would simply be a matter of changing transcoders). ## Testing @@ -28,7 +148,7 @@ then you are done. ### Connection and Authentication Test Environment -Comple the normal test environment setup and also do the following. +Complete the normal test environment setup and also do the following. Run the following SQL: diff --git a/value_transcoder.go b/value_transcoder.go index 26dc6298..ec78e7b6 100644 --- a/value_transcoder.go +++ b/value_transcoder.go @@ -123,7 +123,7 @@ func init() { var arrayEl *regexp.Regexp = regexp.MustCompile(`[{,](?:"((?:[^"\\]|\\.)*)"|(NULL)|([^,}]+))`) -// SplitArrayText +// SplitArrayText is used by array transcoders to split array text into elements func SplitArrayText(text string) (elements []string) { matches := arrayEl.FindAllStringSubmatch(text, -1) elements = make([]string, 0, len(matches))