[822] | 1 | /*
|
---|
| 2 | Package pq is a pure Go Postgres driver for the database/sql package.
|
---|
| 3 |
|
---|
| 4 | In most cases clients will use the database/sql package instead of
|
---|
| 5 | using this package directly. For example:
|
---|
| 6 |
|
---|
| 7 | import (
|
---|
| 8 | "database/sql"
|
---|
| 9 |
|
---|
| 10 | _ "github.com/lib/pq"
|
---|
| 11 | )
|
---|
| 12 |
|
---|
| 13 | func main() {
|
---|
| 14 | connStr := "user=pqgotest dbname=pqgotest sslmode=verify-full"
|
---|
| 15 | db, err := sql.Open("postgres", connStr)
|
---|
| 16 | if err != nil {
|
---|
| 17 | log.Fatal(err)
|
---|
| 18 | }
|
---|
| 19 |
|
---|
| 20 | age := 21
|
---|
| 21 | rows, err := db.Query("SELECT name FROM users WHERE age = $1", age)
|
---|
| 22 | …
|
---|
| 23 | }
|
---|
| 24 |
|
---|
| 25 | You can also connect to a database using a URL. For example:
|
---|
| 26 |
|
---|
| 27 | connStr := "postgres://pqgotest:password@localhost/pqgotest?sslmode=verify-full"
|
---|
| 28 | db, err := sql.Open("postgres", connStr)
|
---|
| 29 |
|
---|
| 30 |
|
---|
| 31 | Connection String Parameters
|
---|
| 32 |
|
---|
| 33 |
|
---|
| 34 | Similarly to libpq, when establishing a connection using pq you are expected to
|
---|
| 35 | supply a connection string containing zero or more parameters.
|
---|
| 36 | A subset of the connection parameters supported by libpq are also supported by pq.
|
---|
| 37 | Additionally, pq also lets you specify run-time parameters (such as search_path or work_mem)
|
---|
| 38 | directly in the connection string. This is different from libpq, which does not allow
|
---|
| 39 | run-time parameters in the connection string, instead requiring you to supply
|
---|
| 40 | them in the options parameter.
|
---|
| 41 |
|
---|
| 42 | For compatibility with libpq, the following special connection parameters are
|
---|
| 43 | supported:
|
---|
| 44 |
|
---|
| 45 | * dbname - The name of the database to connect to
|
---|
| 46 | * user - The user to sign in as
|
---|
| 47 | * password - The user's password
|
---|
| 48 | * host - The host to connect to. Values that start with / are for unix
|
---|
| 49 | domain sockets. (default is localhost)
|
---|
| 50 | * port - The port to bind to. (default is 5432)
|
---|
| 51 | * sslmode - Whether or not to use SSL (default is require, this is not
|
---|
| 52 | the default for libpq)
|
---|
| 53 | * fallback_application_name - An application_name to fall back to if one isn't provided.
|
---|
| 54 | * connect_timeout - Maximum wait for connection, in seconds. Zero or
|
---|
| 55 | not specified means wait indefinitely.
|
---|
| 56 | * sslcert - Cert file location. The file must contain PEM encoded data.
|
---|
| 57 | * sslkey - Key file location. The file must contain PEM encoded data.
|
---|
| 58 | * sslrootcert - The location of the root certificate file. The file
|
---|
| 59 | must contain PEM encoded data.
|
---|
| 60 |
|
---|
| 61 | Valid values for sslmode are:
|
---|
| 62 |
|
---|
| 63 | * disable - No SSL
|
---|
| 64 | * require - Always SSL (skip verification)
|
---|
| 65 | * verify-ca - Always SSL (verify that the certificate presented by the
|
---|
| 66 | server was signed by a trusted CA)
|
---|
| 67 | * verify-full - Always SSL (verify that the certification presented by
|
---|
| 68 | the server was signed by a trusted CA and the server host name
|
---|
| 69 | matches the one in the certificate)
|
---|
| 70 |
|
---|
| 71 | See http://www.postgresql.org/docs/current/static/libpq-connect.html#LIBPQ-CONNSTRING
|
---|
| 72 | for more information about connection string parameters.
|
---|
| 73 |
|
---|
| 74 | Use single quotes for values that contain whitespace:
|
---|
| 75 |
|
---|
| 76 | "user=pqgotest password='with spaces'"
|
---|
| 77 |
|
---|
| 78 | A backslash will escape the next character in values:
|
---|
| 79 |
|
---|
| 80 | "user=space\ man password='it\'s valid'"
|
---|
| 81 |
|
---|
| 82 | Note that the connection parameter client_encoding (which sets the
|
---|
| 83 | text encoding for the connection) may be set but must be "UTF8",
|
---|
| 84 | matching with the same rules as Postgres. It is an error to provide
|
---|
| 85 | any other value.
|
---|
| 86 |
|
---|
| 87 | In addition to the parameters listed above, any run-time parameter that can be
|
---|
| 88 | set at backend start time can be set in the connection string. For more
|
---|
| 89 | information, see
|
---|
| 90 | http://www.postgresql.org/docs/current/static/runtime-config.html.
|
---|
| 91 |
|
---|
| 92 | Most environment variables as specified at http://www.postgresql.org/docs/current/static/libpq-envars.html
|
---|
| 93 | supported by libpq are also supported by pq. If any of the environment
|
---|
| 94 | variables not supported by pq are set, pq will panic during connection
|
---|
| 95 | establishment. Environment variables have a lower precedence than explicitly
|
---|
| 96 | provided connection parameters.
|
---|
| 97 |
|
---|
| 98 | The pgpass mechanism as described in http://www.postgresql.org/docs/current/static/libpq-pgpass.html
|
---|
| 99 | is supported, but on Windows PGPASSFILE must be specified explicitly.
|
---|
| 100 |
|
---|
| 101 |
|
---|
| 102 | Queries
|
---|
| 103 |
|
---|
| 104 |
|
---|
| 105 | database/sql does not dictate any specific format for parameter
|
---|
| 106 | markers in query strings, and pq uses the Postgres-native ordinal markers,
|
---|
| 107 | as shown above. The same marker can be reused for the same parameter:
|
---|
| 108 |
|
---|
| 109 | rows, err := db.Query(`SELECT name FROM users WHERE favorite_fruit = $1
|
---|
| 110 | OR age BETWEEN $2 AND $2 + 3`, "orange", 64)
|
---|
| 111 |
|
---|
| 112 | pq does not support the LastInsertId() method of the Result type in database/sql.
|
---|
| 113 | To return the identifier of an INSERT (or UPDATE or DELETE), use the Postgres
|
---|
| 114 | RETURNING clause with a standard Query or QueryRow call:
|
---|
| 115 |
|
---|
| 116 | var userid int
|
---|
| 117 | err := db.QueryRow(`INSERT INTO users(name, favorite_fruit, age)
|
---|
| 118 | VALUES('beatrice', 'starfruit', 93) RETURNING id`).Scan(&userid)
|
---|
| 119 |
|
---|
| 120 | For more details on RETURNING, see the Postgres documentation:
|
---|
| 121 |
|
---|
| 122 | http://www.postgresql.org/docs/current/static/sql-insert.html
|
---|
| 123 | http://www.postgresql.org/docs/current/static/sql-update.html
|
---|
| 124 | http://www.postgresql.org/docs/current/static/sql-delete.html
|
---|
| 125 |
|
---|
| 126 | For additional instructions on querying see the documentation for the database/sql package.
|
---|
| 127 |
|
---|
| 128 |
|
---|
| 129 | Data Types
|
---|
| 130 |
|
---|
| 131 |
|
---|
| 132 | Parameters pass through driver.DefaultParameterConverter before they are handled
|
---|
| 133 | by this package. When the binary_parameters connection option is enabled,
|
---|
| 134 | []byte values are sent directly to the backend as data in binary format.
|
---|
| 135 |
|
---|
| 136 | This package returns the following types for values from the PostgreSQL backend:
|
---|
| 137 |
|
---|
| 138 | - integer types smallint, integer, and bigint are returned as int64
|
---|
| 139 | - floating-point types real and double precision are returned as float64
|
---|
| 140 | - character types char, varchar, and text are returned as string
|
---|
| 141 | - temporal types date, time, timetz, timestamp, and timestamptz are
|
---|
| 142 | returned as time.Time
|
---|
| 143 | - the boolean type is returned as bool
|
---|
| 144 | - the bytea type is returned as []byte
|
---|
| 145 |
|
---|
| 146 | All other types are returned directly from the backend as []byte values in text format.
|
---|
| 147 |
|
---|
| 148 |
|
---|
| 149 | Errors
|
---|
| 150 |
|
---|
| 151 |
|
---|
| 152 | pq may return errors of type *pq.Error which can be interrogated for error details:
|
---|
| 153 |
|
---|
| 154 | if err, ok := err.(*pq.Error); ok {
|
---|
| 155 | fmt.Println("pq error:", err.Code.Name())
|
---|
| 156 | }
|
---|
| 157 |
|
---|
| 158 | See the pq.Error type for details.
|
---|
| 159 |
|
---|
| 160 |
|
---|
| 161 | Bulk imports
|
---|
| 162 |
|
---|
| 163 | You can perform bulk imports by preparing a statement returned by pq.CopyIn (or
|
---|
| 164 | pq.CopyInSchema) in an explicit transaction (sql.Tx). The returned statement
|
---|
| 165 | handle can then be repeatedly "executed" to copy data into the target table.
|
---|
| 166 | After all data has been processed you should call Exec() once with no arguments
|
---|
| 167 | to flush all buffered data. Any call to Exec() might return an error which
|
---|
| 168 | should be handled appropriately, but because of the internal buffering an error
|
---|
| 169 | returned by Exec() might not be related to the data passed in the call that
|
---|
| 170 | failed.
|
---|
| 171 |
|
---|
| 172 | CopyIn uses COPY FROM internally. It is not possible to COPY outside of an
|
---|
| 173 | explicit transaction in pq.
|
---|
| 174 |
|
---|
| 175 | Usage example:
|
---|
| 176 |
|
---|
| 177 | txn, err := db.Begin()
|
---|
| 178 | if err != nil {
|
---|
| 179 | log.Fatal(err)
|
---|
| 180 | }
|
---|
| 181 |
|
---|
| 182 | stmt, err := txn.Prepare(pq.CopyIn("users", "name", "age"))
|
---|
| 183 | if err != nil {
|
---|
| 184 | log.Fatal(err)
|
---|
| 185 | }
|
---|
| 186 |
|
---|
| 187 | for _, user := range users {
|
---|
| 188 | _, err = stmt.Exec(user.Name, int64(user.Age))
|
---|
| 189 | if err != nil {
|
---|
| 190 | log.Fatal(err)
|
---|
| 191 | }
|
---|
| 192 | }
|
---|
| 193 |
|
---|
| 194 | _, err = stmt.Exec()
|
---|
| 195 | if err != nil {
|
---|
| 196 | log.Fatal(err)
|
---|
| 197 | }
|
---|
| 198 |
|
---|
| 199 | err = stmt.Close()
|
---|
| 200 | if err != nil {
|
---|
| 201 | log.Fatal(err)
|
---|
| 202 | }
|
---|
| 203 |
|
---|
| 204 | err = txn.Commit()
|
---|
| 205 | if err != nil {
|
---|
| 206 | log.Fatal(err)
|
---|
| 207 | }
|
---|
| 208 |
|
---|
| 209 |
|
---|
| 210 | Notifications
|
---|
| 211 |
|
---|
| 212 |
|
---|
| 213 | PostgreSQL supports a simple publish/subscribe model over database
|
---|
| 214 | connections. See http://www.postgresql.org/docs/current/static/sql-notify.html
|
---|
| 215 | for more information about the general mechanism.
|
---|
| 216 |
|
---|
| 217 | To start listening for notifications, you first have to open a new connection
|
---|
| 218 | to the database by calling NewListener. This connection can not be used for
|
---|
| 219 | anything other than LISTEN / NOTIFY. Calling Listen will open a "notification
|
---|
| 220 | channel"; once a notification channel is open, a notification generated on that
|
---|
| 221 | channel will effect a send on the Listener.Notify channel. A notification
|
---|
| 222 | channel will remain open until Unlisten is called, though connection loss might
|
---|
| 223 | result in some notifications being lost. To solve this problem, Listener sends
|
---|
| 224 | a nil pointer over the Notify channel any time the connection is re-established
|
---|
| 225 | following a connection loss. The application can get information about the
|
---|
| 226 | state of the underlying connection by setting an event callback in the call to
|
---|
| 227 | NewListener.
|
---|
| 228 |
|
---|
| 229 | A single Listener can safely be used from concurrent goroutines, which means
|
---|
| 230 | that there is often no need to create more than one Listener in your
|
---|
| 231 | application. However, a Listener is always connected to a single database, so
|
---|
| 232 | you will need to create a new Listener instance for every database you want to
|
---|
| 233 | receive notifications in.
|
---|
| 234 |
|
---|
| 235 | The channel name in both Listen and Unlisten is case sensitive, and can contain
|
---|
| 236 | any characters legal in an identifier (see
|
---|
| 237 | http://www.postgresql.org/docs/current/static/sql-syntax-lexical.html#SQL-SYNTAX-IDENTIFIERS
|
---|
| 238 | for more information). Note that the channel name will be truncated to 63
|
---|
| 239 | bytes by the PostgreSQL server.
|
---|
| 240 |
|
---|
| 241 | You can find a complete, working example of Listener usage at
|
---|
| 242 | https://godoc.org/github.com/lib/pq/example/listen.
|
---|
| 243 |
|
---|
| 244 |
|
---|
| 245 | Kerberos Support
|
---|
| 246 |
|
---|
| 247 |
|
---|
| 248 | If you need support for Kerberos authentication, add the following to your main
|
---|
| 249 | package:
|
---|
| 250 |
|
---|
| 251 | import "github.com/lib/pq/auth/kerberos"
|
---|
| 252 |
|
---|
| 253 | func init() {
|
---|
| 254 | pq.RegisterGSSProvider(func() (pq.Gss, error) { return kerberos.NewGSS() })
|
---|
| 255 | }
|
---|
| 256 |
|
---|
| 257 | This package is in a separate module so that users who don't need Kerberos
|
---|
| 258 | don't have to download unnecessary dependencies.
|
---|
| 259 |
|
---|
| 260 | When imported, additional connection string parameters are supported:
|
---|
| 261 |
|
---|
| 262 | * krbsrvname - GSS (Kerberos) service name when constructing the
|
---|
| 263 | SPN (default is `postgres`). This will be combined with the host
|
---|
| 264 | to form the full SPN: `krbsrvname/host`.
|
---|
| 265 | * krbspn - GSS (Kerberos) SPN. This takes priority over
|
---|
| 266 | `krbsrvname` if present.
|
---|
| 267 | */
|
---|
| 268 | package pq
|
---|