2014-08-15 06:05:11 +00:00
# Rust-Postgres
2017-07-09 02:53:39 +00:00
[![CircleCI ](https://circleci.com/gh/sfackler/rust-postgres.svg?style=shield )](https://circleci.com/gh/sfackler/rust-postgres) [![Latest Version ](https://img.shields.io/crates/v/postgres.svg )](https://crates.io/crates/postgres)
2013-09-03 06:19:03 +00:00
A native PostgreSQL driver for Rust.
2017-04-12 16:03:55 +00:00
[Documentation ](https://docs.rs/postgres )
2013-09-30 04:21:00 +00:00
2014-12-14 20:43:53 +00:00
You can integrate Rust-Postgres into your project through the [releases on crates.io ](https://crates.io/crates/postgres ):
2014-11-07 06:54:57 +00:00
```toml
2014-12-07 20:56:41 +00:00
[dependencies]
2017-07-24 03:15:38 +00:00
postgres = "0.15"
2014-11-07 06:54:57 +00:00
```
2014-08-15 06:05:11 +00:00
## Overview
2015-12-06 20:10:54 +00:00
Rust-Postgres is a pure-Rust frontend for the popular PostgreSQL database.
2013-09-03 06:19:03 +00:00
```rust
2014-02-16 02:11:23 +00:00
extern crate postgres;
2013-10-01 07:01:54 +00:00
2016-10-10 05:04:23 +00:00
use postgres::{Connection, TlsMode};
2013-09-03 06:19:03 +00:00
struct Person {
id: i32,
2014-05-26 03:39:06 +00:00
name: String,
2016-06-01 15:40:27 +00:00
data: Option< Vec < u8 > >,
2013-09-03 06:19:03 +00:00
}
fn main() {
2017-07-09 02:40:03 +00:00
let conn = Connection::connect("postgres://postgres@localhost:5433", TlsMode::None).unwrap();
2013-12-29 03:27:20 +00:00
conn.execute("CREATE TABLE person (
2013-10-01 07:01:54 +00:00
id SERIAL PRIMARY KEY,
name VARCHAR NOT NULL,
data BYTEA
2014-11-25 20:44:42 +00:00
)", &[]).unwrap();
2013-09-03 06:19:03 +00:00
let me = Person {
id: 0,
2014-12-27 16:34:21 +00:00
name: "Steven".to_string(),
2016-06-01 15:40:27 +00:00
data: None,
2013-09-03 06:19:03 +00:00
};
2015-02-08 03:52:45 +00:00
conn.execute("INSERT INTO person (name, data) VALUES ($1, $2)",
& [& me.name, &me.data]).unwrap();
2015-12-06 20:10:54 +00:00
for row in & conn.query("SELECT id, name, data FROM person", & []).unwrap() {
2013-09-03 06:19:03 +00:00
let person = Person {
2014-10-26 06:43:59 +00:00
id: row.get(0),
name: row.get(1),
2016-06-01 15:40:27 +00:00
data: row.get(2),
2013-09-03 06:19:03 +00:00
};
2018-05-20 16:02:28 +00:00
println!("Found person {}: {}", person.id, person.name);
2013-09-03 06:19:03 +00:00
}
}
```
2014-08-15 06:05:11 +00:00
## Requirements
2017-07-09 17:33:04 +00:00
* **Rust** - Rust-Postgres is developed against the 1.18 release of Rust
2015-04-13 05:08:32 +00:00
available on http://www.rust-lang.org. It should also compile against more
2015-06-27 03:43:37 +00:00
recent releases.
2013-09-03 06:19:03 +00:00
* **PostgreSQL 7.4 or later** - Rust-Postgres speaks version 3 of the
PostgreSQL protocol, which corresponds to versions 7.4 and later. If your
version of Postgres was compiled in the last decade, you should be okay.
2014-08-15 06:05:11 +00:00
## Usage
2013-09-03 06:19:03 +00:00
2014-08-15 06:05:11 +00:00
### Connecting
2013-09-03 06:19:03 +00:00
Connect to a Postgres server using the standard URI format:
```rust
2017-02-15 06:46:19 +00:00
let conn = Connection::connect("postgres://user:pass@host:port/database?arg1=val1& arg2=val2",
TlsMode::None)?;
2013-09-03 06:19:03 +00:00
```
`pass` may be omitted if not needed. `port` defaults to `5432` and `database`
2013-11-06 06:04:12 +00:00
defaults to the value of `user` if not specified. The driver supports `trust` ,
`password` , and `md5` authentication.
2013-09-03 06:19:03 +00:00
2016-07-08 05:54:22 +00:00
Unix domain sockets can be used as well. The `host` portion of the URI should
be set to the absolute path to the directory containing the socket file. Since
`/` is a reserved character in URLs, the path should be URL encoded. If Postgres
stored its socket files in `/run/postgres` , the connection would then look like:
2014-05-15 05:23:57 +00:00
```rust
2017-02-15 06:46:19 +00:00
let conn = Connection::connect("postgres://postgres@%2Frun%2Fpostgres", TlsMode::None)?;
2014-05-15 05:23:57 +00:00
```
Paths which contain non-UTF8 characters can be handled in a different manner;
see the documentation for details.
2014-08-15 06:05:11 +00:00
### Querying
2015-12-07 00:46:06 +00:00
SQL statements can be executed with the `query` and `execute` methods. Both
methods take a query string as well as a slice of parameters to bind to the
query. The `i` th query parameter is specified in the query string by `$i` . Note
that query parameters are 1-indexed rather than the more common 0-indexing.
`execute` returns the number of rows affected by the query (or 0 if not
applicable):
2013-09-03 06:23:58 +00:00
```rust
2017-02-15 06:46:19 +00:00
let updates = conn.execute("UPDATE foo SET bar = $1 WHERE baz = $2", & [& 1i32, &"biz"])?;
2013-09-03 06:19:03 +00:00
println!("{} rows were updated", updates);
```
2015-12-07 00:46:06 +00:00
`query` returns an iterable object holding the rows returned from the database.
The fields in a row can be accessed either by their indices or their column
names, though access by index is more efficient. Unlike statement parameters,
result columns are zero-indexed.
2013-09-03 06:19:03 +00:00
```rust
2017-02-15 06:46:19 +00:00
for row in & conn.query("SELECT bar, baz FROM foo WHERE buz = $1", & [& 1i32])? {
2014-10-26 06:49:13 +00:00
let bar: i32 = row.get(0);
2014-07-24 16:11:53 +00:00
let baz: String = row.get("baz");
2013-09-03 06:19:03 +00:00
println!("bar: {}, baz: {}", bar, baz);
}
```
2015-12-07 00:46:06 +00:00
### Statement Preparation
If the same statement will be executed repeatedly (possibly with different
parameters), explicitly preparing it can improve performance:
2013-09-03 06:19:03 +00:00
```rust
2017-02-15 06:46:19 +00:00
let stmt = conn.prepare("UPDATE foo SET bar = $1 WHERE baz = $2")?;
2015-12-07 00:46:06 +00:00
for (bar, baz) in updates {
2017-02-15 06:46:19 +00:00
stmt.execute(& [bar, baz])?;
2015-12-07 00:46:06 +00:00
}
2013-09-03 06:19:03 +00:00
```
2014-08-15 06:05:11 +00:00
### Transactions
2013-10-14 01:58:31 +00:00
The `transaction` method will start a new transaction. It returns a
2014-11-01 23:31:06 +00:00
`Transaction` object which has the functionality of a
`Connection` as well as methods to control the result of the
2013-10-14 01:58:31 +00:00
transaction:
2013-09-03 06:19:03 +00:00
```rust
2017-02-15 06:46:19 +00:00
let trans = conn.transaction()?;
2015-12-07 01:20:47 +00:00
2017-02-15 06:46:19 +00:00
trans.execute(...)?;
let stmt = trans.prepare(...)?;
2015-12-07 01:20:47 +00:00
// ...
2013-09-03 06:19:03 +00:00
2017-02-15 06:46:19 +00:00
trans.commit()?;
2013-09-03 06:19:03 +00:00
```
2014-11-01 23:38:52 +00:00
The transaction will be active until the `Transaction` object falls out of
scope. A transaction will roll back by default. Nested transactions are
2013-10-14 01:58:31 +00:00
supported via savepoints.
2013-09-03 06:19:03 +00:00
2014-08-15 06:05:11 +00:00
### Type Correspondence
2013-09-03 06:19:03 +00:00
Rust-Postgres enforces a strict correspondence between Rust types and Postgres
2013-09-16 03:05:32 +00:00
types. The driver currently supports the following conversions:
2013-09-03 06:19:03 +00:00
< table >
< thead >
< tr >
2014-11-10 11:51:33 +00:00
< th > Rust Type< / th >
< th > Postgres Type< / th >
2013-09-03 06:19:03 +00:00
< / tr >
< / thead >
< tbody >
< tr >
< td > bool< / td >
< td > BOOL< / td >
< / tr >
< tr >
< td > i8< / td >
< td > "char"< / td >
< / tr >
< tr >
< td > i16< / td >
2013-11-06 05:35:07 +00:00
< td > SMALLINT, SMALLSERIAL< / td >
2013-09-03 06:19:03 +00:00
< / tr >
< tr >
< td > i32< / td >
2013-11-06 05:35:07 +00:00
< td > INT, SERIAL< / td >
2013-09-03 06:19:03 +00:00
< / tr >
2014-12-15 00:43:17 +00:00
< tr >
< td > u32< / td >
< td > OID< / td >
< / tr >
2013-09-03 06:19:03 +00:00
< tr >
< td > i64< / td >
2013-11-06 05:35:07 +00:00
< td > BIGINT, BIGSERIAL< / td >
2013-09-03 06:19:03 +00:00
< / tr >
< tr >
< td > f32< / td >
2013-11-06 05:35:07 +00:00
< td > REAL< / td >
2013-09-03 06:19:03 +00:00
< / tr >
< tr >
< td > f64< / td >
2013-11-06 05:35:07 +00:00
< td > DOUBLE PRECISION< / td >
2013-09-03 06:19:03 +00:00
< / tr >
< tr >
2014-05-26 22:21:15 +00:00
< td > str/String< / td >
2016-09-25 16:34:12 +00:00
< td > VARCHAR, CHAR(n), TEXT, CITEXT, NAME< / td >
2013-09-03 06:19:03 +00:00
< / tr >
< tr >
2014-04-08 16:59:45 +00:00
< td > [u8]/Vec< u8> < / td >
2013-09-03 06:19:03 +00:00
< td > BYTEA< / td >
< / tr >
< tr >
2015-02-08 03:20:18 +00:00
< td >
2019-07-10 20:08:56 +00:00
postgres::types::Json
2015-04-13 04:56:40 +00:00
and
2015-11-29 18:59:04 +00:00
< a href = "https://github.com/serde-rs/json" > serde_json::Value< / a >
2015-02-08 03:20:18 +00:00
(< a href = "#optional-features" > optional< / a > )
< / td >
2015-05-15 04:05:57 +00:00
< td > JSON, JSONB< / td >
2013-09-03 06:19:03 +00:00
< / tr >
2013-09-08 20:27:15 +00:00
< tr >
2015-02-08 03:55:05 +00:00
< td >
2015-11-18 18:28:57 +00:00
< a href = "https://github.com/rust-lang-deprecated/time" > time::Timespec< / a >
2015-05-14 05:21:40 +00:00
and
< a href = "https://github.com/lifthrasiir/rust-chrono" > chrono::NaiveDateTime< / a >
(< a href = "#optional-features" > optional< / a > )
< / td >
< td > TIMESTAMP< / td >
< / tr >
< tr >
< td >
2015-11-18 18:28:57 +00:00
< a href = "https://github.com/rust-lang-deprecated/time" > time::Timespec< / a > ,
2017-06-30 18:13:10 +00:00
< a href = "https://github.com/lifthrasiir/rust-chrono" > chrono::DateTime< Utc> < / a > ,
2015-07-21 06:16:50 +00:00
< a href = "https://github.com/lifthrasiir/rust-chrono" > chrono::DateTime< Local> < / a > ,
2015-05-14 05:21:40 +00:00
and
2015-07-21 06:16:50 +00:00
< a href = "https://github.com/lifthrasiir/rust-chrono" > chrono::DateTime< FixedOffset> < / a >
2015-05-14 05:21:40 +00:00
(< a href = "#optional-features" > optional< / a > )
< / td >
< td > TIMESTAMP WITH TIME ZONE< / td >
< / tr >
< tr >
< td >
< a href = "https://github.com/lifthrasiir/rust-chrono" > chrono::NaiveDate< / a >
(< a href = "#optional-features" > optional< / a > )
< / td >
< td > DATE< / td >
< / tr >
< tr >
< td >
< a href = "https://github.com/lifthrasiir/rust-chrono" > chrono::NaiveTime< / a >
2015-02-08 03:55:05 +00:00
(< a href = "#optional-features" > optional< / a > )
< / td >
2015-05-14 05:21:40 +00:00
< td > TIME< / td >
2013-09-08 20:27:15 +00:00
< / tr >
2014-11-07 06:54:57 +00:00
< tr >
< td >
2015-11-18 18:28:57 +00:00
< a href = "https://github.com/rust-lang-nursery/uuid" > uuid::Uuid< / a >
2014-11-07 06:54:57 +00:00
(< a href = "#optional-features" > optional< / a > )
< / td >
< td > UUID< / td >
< / tr >
2015-12-06 20:42:57 +00:00
< tr >
< td >
< a href = "https://github.com/contain-rs/bit-vec" > bit_vec::BitVec< / a >
(< a href = "#optional-features" > optional< / a > )
< / td >
< td > BIT, VARBIT< / td >
< / tr >
2013-12-05 05:20:48 +00:00
< tr >
2015-05-15 04:05:25 +00:00
< td > HashMap< String, Option< String> > < / td >
2013-12-05 05:20:48 +00:00
< td > HSTORE< / td >
< / tr >
2016-02-14 01:50:41 +00:00
< tr >
< td >
< a href = "https://github.com/abaumhauer/eui48" > eui48::MacAddress< / a >
(< a href = "#optional-features" > optional< / a > )
< / td >
< td > MACADDR< / td >
2017-03-10 23:33:43 +00:00
< /tr
< tr >
< td >
< a href = "https://github.com/georust/rust-geo" > geo::Point< f64> < / a >
(< a href = "#optional-features" > optional< / a > )
< / td >
< td > POINT< / td >
< / tr >
< tr >
< td >
< a href = "https://github.com/georust/rust-geo" > geo::Bbox< f64> < / a >
(< a href = "#optional-features" > optional< / a > )
< / td >
< td > BOX< / td >
2016-02-14 01:50:41 +00:00
< / tr >
2017-03-11 00:20:51 +00:00
< tr >
< td >
< a href = "https://github.com/georust/rust-geo" > geo::LineString< f64> < / a >
(< a href = "#optional-features" > optional< / a > )
< / td >
< td > PATH< / td >
< / tr >
2013-09-03 06:19:03 +00:00
< / tbody >
< / table >
2016-04-19 03:54:33 +00:00
`Option<T>` implements `FromSql` where `T: FromSql` and `ToSql` where `T:
ToSql`, and represents nullable Postgres values.
`&[T]` and `Vec<T>` implement `ToSql` where `T: ToSql` , and `Vec<T>`
additionally implements `FromSql` where `T: FromSql` , which represent
one-dimensional Postgres arrays.
2013-09-03 06:19:03 +00:00
More conversions can be defined by implementing the `ToSql` and `FromSql`
traits.
2016-02-22 04:30:05 +00:00
The [postgres-derive ](https://github.com/sfackler/rust-postgres-derive )
2016-02-22 04:29:05 +00:00
crate will synthesize `ToSql` and `FromSql` implementations for enum, domain,
and composite Postgres types.
2016-03-27 16:42:21 +00:00
Full support for array types is located in the
2014-12-25 05:06:47 +00:00
[postgres-array ](https://github.com/sfackler/rust-postgres-array ) crate.
2014-12-25 04:58:27 +00:00
2015-06-25 07:04:56 +00:00
Support for range types is located in the
2014-12-27 15:58:32 +00:00
[postgres-range ](https://github.com/sfackler/rust-postgres-range ) crate.
2015-06-25 07:04:56 +00:00
Support for the large object API is located in the
2016-02-22 04:29:05 +00:00
[postgres-large-object ](https://github.com/sfackler/rust-postgres-large-object )
crate.
2015-04-13 04:57:57 +00:00
2014-11-07 06:54:57 +00:00
## Optional features
### UUID type
2014-11-17 19:10:26 +00:00
[UUID ](http://www.postgresql.org/docs/9.4/static/datatype-uuid.html ) support is
2016-07-02 01:42:23 +00:00
provided optionally by the `with-uuid` feature, which adds `ToSql` and `FromSql`
2018-01-27 07:00:18 +00:00
implementations for `uuid` 's `Uuid` type. Requires `uuid` version 0.5.
2014-11-07 06:54:57 +00:00
2015-02-08 03:20:18 +00:00
### JSON/JSONB types
[JSON and JSONB ](http://www.postgresql.org/docs/9.4/static/datatype-json.html )
2019-07-10 20:08:56 +00:00
support is provided optionally by the `with-serde_json-1` feature, which adds
`ToSql` and `FromSql` implementations for `serde_json` 's `Value` type,
as well as adding a generic `Json<T>` type with those same implementations.
Requires `serde_json` version 1.0.
2015-02-08 03:20:18 +00:00
2015-05-14 05:21:40 +00:00
### TIMESTAMP/TIMESTAMPTZ/DATE/TIME types
2015-02-08 03:55:05 +00:00
2015-05-14 05:21:40 +00:00
[Date and Time ](http://www.postgresql.org/docs/9.1/static/datatype-datetime.html )
2016-07-02 01:42:23 +00:00
support is provided optionally by the `with-time` feature, which adds `ToSql`
and `FromSql` implementations for `time` 's `Timespec` type, or the `with-chrono`
2015-05-14 05:21:40 +00:00
feature, which adds `ToSql` and `FromSql` implementations for `chrono` 's
2018-01-27 07:00:18 +00:00
`DateTime` , `NaiveDateTime` , `NaiveDate` and `NaiveTime` types. Requires `time` version 0.1.14.
2015-12-06 20:42:57 +00:00
### BIT/VARBIT types
[BIT and VARBIT ](http://www.postgresql.org/docs/9.4/static/datatype-bit.html )
2016-07-02 01:42:23 +00:00
support is provided optionally by the `with-bit-vec` feature, which adds `ToSql`
2018-01-27 07:00:18 +00:00
and `FromSql` implementations for `bit-vec` 's `BitVec` type. Requires `bit-vec` version 0.4.
2016-02-14 01:57:59 +00:00
### MACADDR type
[MACADDR ](http://www.postgresql.org/docs/9.4/static/datatype-net-types.html#DATATYPE-MACADDR )
2016-07-02 01:42:23 +00:00
support is provided optionally by the `with-eui48` feature, which adds `ToSql`
2018-01-27 07:00:18 +00:00
and `FromSql` implementations for `eui48` 's `MacAddress` type. Requires `eui48` version 0.3.
2017-03-10 23:33:43 +00:00
### POINT type
[POINT ](https://www.postgresql.org/docs/9.4/static/datatype-geometric.html#AEN6799 )
2018-01-27 06:41:01 +00:00
support is provided optionally by the `with-geo` feature, which adds `ToSql` and `FromSql` implementations for `geo` 's `Point` type. Requires `geo` version 0.4.
2017-03-10 23:33:43 +00:00
### BOX type
[BOX ](https://www.postgresql.org/docs/9.4/static/datatype-geometric.html#AEN6883 )
2018-01-27 06:41:01 +00:00
support is provided optionally by the `with-geo` feature, which adds `ToSql` and `FromSql` implementations for `geo` 's `Bbox` type. Requires `geo` version 0.4.
2017-03-11 00:20:51 +00:00
### PATH type
[PATH ](https://www.postgresql.org/docs/9.4/static/datatype-geometric.html#AEN6912 )
support is provided optionally by the `with-geo` feature, which adds `ToSql` and `FromSql` implementations for `geo` 's `LineString` type.
2018-01-27 06:41:01 +00:00
Paths converted from LineString are always treated as "open" paths. Requires `geo` version 0.4. Use the
2017-03-11 00:20:51 +00:00
[pclose ](https://www.postgresql.org/docs/8.2/static/functions-geometry.html#FUNCTIONS-GEOMETRY-FUNC-TABLE )
geometric function to insert a closed path.
2018-01-29 00:42:36 +00:00
## See Also
- [r2d2-postgres ](https://github.com/sfackler/r2d2-postgres ) for connection pool support.