rust-postgres/README.md

297 lines
9.9 KiB
Markdown
Raw Normal View History

2014-08-15 06:05:11 +00:00
# Rust-Postgres
2013-09-03 06:19:03 +00:00
A native PostgreSQL driver for Rust.
2015-09-19 18:06:51 +00:00
[Documentation](https://sfackler.github.io/rust-postgres/doc/v0.10.0/postgres)
2013-09-30 04:21:00 +00:00
2015-03-25 03:02:23 +00:00
[![Build Status](https://travis-ci.org/sfackler/rust-postgres.png?branch=master)](https://travis-ci.org/sfackler/rust-postgres) [![Latest Version](https://img.shields.io/crates/v/postgres.svg)](https://crates.io/crates/postgres)
2013-10-08 06:03:05 +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):
```toml
# Cargo.toml
[dependencies]
2015-09-19 18:06:51 +00:00
postgres = "0.10"
```
2014-08-15 06:05:11 +00:00
## Overview
2013-09-03 06:19:03 +00:00
Rust-Postgres is a pure-Rust frontend for the popular PostgreSQL database. It
exposes a high level interface in the vein of JDBC or Go's `database/sql`
package.
```rust
extern crate postgres;
2013-10-01 07:01:54 +00:00
2014-11-17 21:46:33 +00:00
use postgres::{Connection, SslMode};
2013-09-03 06:19:03 +00:00
struct Person {
id: i32,
2014-05-26 03:39:06 +00:00
name: String,
2014-04-08 16:59:45 +00:00
data: Option<Vec<u8>>
2013-09-03 06:19:03 +00:00
}
fn main() {
2014-11-17 21:46:33 +00:00
let conn = Connection::connect("postgres://postgres@localhost", &SslMode::None)
2014-11-01 23:38:52 +00:00
.unwrap();
2013-09-03 06:19:03 +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(),
2013-09-03 06:19:03 +00:00
data: None
};
2015-02-08 03:52:45 +00:00
conn.execute("INSERT INTO person (name, data) VALUES ($1, $2)",
&[&me.name, &me.data]).unwrap();
2013-09-03 06:19:03 +00:00
2015-02-08 03:52:45 +00:00
let stmt = conn.prepare("SELECT id, name, data FROM person").unwrap();
2014-11-25 20:44:42 +00:00
for row in stmt.query(&[]).unwrap() {
2013-09-03 06:19:03 +00:00
let person = Person {
id: row.get(0),
name: row.get(1),
2015-02-08 03:52:45 +00:00
data: row.get(2)
2013-09-03 06:19:03 +00:00
};
2013-10-01 07:01:54 +00:00
println!("Found person {}", person.name);
2013-09-03 06:19:03 +00:00
}
}
```
2014-08-15 06:05:11 +00:00
## Requirements
2015-09-19 05:55:32 +00:00
* **Rust** - Rust-Postgres is developed against the 1.2 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
2014-11-01 23:31:06 +00:00
let conn = try!(Connection::connect("postgres://user:pass@host:port/database?arg1=val1&arg2=val2",
2014-11-17 21:52:59 +00:00
&SslMode::None));
2013-09-03 06:19:03 +00:00
```
`pass` may be omitted if not needed. `port` defaults to `5432` and `database`
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
2015-02-28 04:04:08 +00:00
Unix domain sockets can be used as well by activating the `unix_socket` feature.
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.
```rust
2014-11-17 21:52:59 +00:00
let conn = try!(Connection::connect("postgres://postgres@%2Frun%2Fpostgres", &SslMode::None));
```
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
### Statement Preparation
2013-09-03 06:19:03 +00:00
Prepared statements can have parameters, represented as `$n` where `n` is an
index into the parameter array starting from 1:
```rust
2014-03-28 04:20:04 +00:00
let stmt = try!(conn.prepare("SELECT * FROM foo WHERE bar = $1 AND baz = $2"));
2013-09-03 06:19:03 +00:00
```
2014-08-15 06:05:11 +00:00
### Querying
A prepared statement can be executed with the `query` and `execute` methods.
2013-09-03 06:19:03 +00:00
Both methods take an array of parameters to bind to the query represented as
`&ToSql` trait objects. `execute` returns the number of rows affected by the
2013-09-03 06:19:03 +00:00
query (or 0 if not applicable):
2013-09-03 06:23:58 +00:00
```rust
2014-05-19 04:23:53 +00:00
let stmt = try!(conn.prepare("UPDATE foo SET bar = $1 WHERE baz = $2"));
let updates = try!(stmt.execute(&[&1i32, &"biz"]));
2013-09-03 06:19:03 +00:00
println!("{} rows were updated", updates);
```
2013-11-06 05:31:24 +00:00
`query` returns an iterator over the rows returned from the database. The
2013-12-03 03:53:40 +00:00
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
2014-03-28 04:20:04 +00:00
let stmt = try!(conn.prepare("SELECT bar, baz FROM foo"));
2014-11-25 20:44:42 +00:00
for row in try!(stmt.query(&[])) {
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);
}
```
2014-11-01 23:38:52 +00:00
In addition, `Connection` has a utility `execute` method which is useful if a
statement is only going to be executed once:
2013-09-03 06:19:03 +00:00
```rust
2014-03-28 04:20:04 +00:00
let updates = try!(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);
```
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
2014-03-28 04:20:04 +00:00
let trans = try!(conn.transaction());
try!(trans.execute(...));
let stmt = try!(trans.prepare(...));
2013-09-03 06:19:03 +00:00
2013-12-05 05:32:13 +00:00
if the_coast_is_clear {
trans.set_commit();
2013-09-03 06:19:03 +00:00
}
2013-12-05 05:32:13 +00:00
2014-07-26 05:42:24 +00:00
try!(trans.finish());
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>
<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>
<td>VARCHAR, CHAR(n), TEXT, CITEXT</td>
2013-09-03 06:19:03 +00:00
</tr>
<tr>
2014-04-08 16:59:45 +00:00
<td>[u8]/Vec&lt;u8&gt;</td>
2013-09-03 06:19:03 +00:00
<td>BYTEA</td>
</tr>
<tr>
<td>
<a href="https://github.com/rust-lang/rustc-serialize">serialize::json::Json</a>
2015-04-13 04:56:40 +00:00
and
<a href="https://github.com/erickt/serde">serde::json::Value</a>
(<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>
<a href="https://github.com/rust-lang/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-07-21 06:16:50 +00:00
<a href="https://github.com/rust-lang/time">time::Timespec</a>,
<a href="https://github.com/lifthrasiir/rust-chrono">chrono::DateTime&lt;UTC&gt;</a>,
<a href="https://github.com/lifthrasiir/rust-chrono">chrono::DateTime&lt;Local&gt;</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&lt;FixedOffset&gt;</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>
<tr>
<td>
<a href="https://github.com/rust-lang/uuid">uuid::Uuid</a>
(<a href="#optional-features">optional</a>)
</td>
<td>UUID</td>
</tr>
2013-12-05 05:20:48 +00:00
<tr>
2015-05-15 04:05:25 +00:00
<td>HashMap&lt;String, Option&lt;String&gt;&gt;</td>
2013-12-05 05:20:48 +00:00
<td>HSTORE</td>
</tr>
2013-09-03 06:19:03 +00:00
</tbody>
</table>
More conversions can be defined by implementing the `ToSql` and `FromSql`
traits.
2015-06-25 07:04:56 +00:00
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.
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
2015-04-13 04:57:57 +00:00
[postgres-large-object](https://github.com/sfackler/rust-postgres-large-object) crate.
## Optional features
2015-02-28 18:38:18 +00:00
### Unix socket connections
Support for connections through Unix domain sockets is provided optionally by
the `unix_socket` feature. It is only available on "unixy" platforms such as
OSX, BSD and Linux.
### UUID type
2014-11-17 19:10:26 +00:00
[UUID](http://www.postgresql.org/docs/9.4/static/datatype-uuid.html) support is
2015-04-13 04:48:38 +00:00
provided optionally by the `uuid` feature, which adds `ToSql` and `FromSql`
implementations for `uuid`'s `Uuid` type.
### JSON/JSONB types
[JSON and JSONB](http://www.postgresql.org/docs/9.4/static/datatype-json.html)
2015-04-13 04:48:38 +00:00
support is provided optionally by the `rustc-serialize` feature, which adds
2015-04-13 05:17:38 +00:00
`ToSql` and `FromSql` implementations for `rustc-serialize`'s `Json` type, and
the `serde` feature, which adds implementations for `serde`'s `json::Value`
2015-04-13 04:48:38 +00:00
type.
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)
2015-04-13 04:48:38 +00:00
support is provided optionally by the `time` feature, which adds `ToSql` and
2015-05-14 05:21:40 +00:00
`FromSql` implementations for `time`'s `Timespec` type, or the `chrono`
feature, which adds `ToSql` and `FromSql` implementations for `chrono`'s
`DateTime`, `NaiveDateTime`, `NaiveDate` and `NaiveTime` types.