Skip to content

Commit 55c0674

Browse files
committed
Fill out README
1 parent a677f62 commit 55c0674

2 files changed

Lines changed: 235 additions & 1 deletion

File tree

README.md

Lines changed: 221 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,222 @@
1-
rust-postgres
1+
Rust-Postgres
22
=============
3+
A native PostgreSQL driver for Rust.
4+
5+
Overview
6+
========
7+
Rust-Postgres is a pure-Rust frontend for the popular PostgreSQL database. It
8+
exposes a high level interface in the vein of JDBC or Go's `database/sql`
9+
package.
10+
```rust
11+
extern mod postgres;
12+
13+
use postgres::PostgresConnection;
14+
use postgres::types::ToSql;
15+
16+
#[deriving(ToStr)]
17+
struct Person {
18+
id: i32,
19+
name: ~str,
20+
awesome: bool,
21+
data: Option<~[u8]>
22+
}
23+
24+
fn main() {
25+
let conn = PostgresConnection::connect("postgres://postgres@127.0.0.1");
26+
27+
conn.update("CREATE TABLE person (
28+
id SERIAL PRIMARY KEY,
29+
name VARCHAR NOT NULL,
30+
awesome BOOL NOT NULL,
31+
data BYTEA
32+
)", []);
33+
let me = Person {
34+
id: 0,
35+
name: ~"Steven",
36+
awesome: true,
37+
data: None
38+
};
39+
conn.update("INSERT INTO person (name, awesome, data)
40+
VALUES ($1, $2, $3)",
41+
[&me.name as &ToSql, &me.awesome as &ToSql,
42+
&me.data as &ToSql]);
43+
44+
let stmt = conn.prepare("SELECT id, name, awesome, data FROM person");
45+
for row in stmt.query([]) {
46+
let person = Person {
47+
id: row[0],
48+
name: row[1],
49+
awesome: row[2],
50+
data: row[3]
51+
};
52+
println!("Found person {}", person.to_str());
53+
}
54+
}
55+
```
56+
57+
Requirements
58+
============
59+
60+
* **Rust** - Rust-Postgres is developed against the *master* branch of the Rust
61+
repository. It will most likely not build against the releases on
62+
http://www.rust-lang.org.
63+
64+
* **PostgreSQL 7.4 or later** - Rust-Postgres speaks version 3 of the
65+
PostgreSQL protocol, which corresponds to versions 7.4 and later. If your
66+
version of Postgres was compiled in the last decade, you should be okay.
67+
68+
Usage
69+
=====
70+
71+
Connecting
72+
----------
73+
Connect to a Postgres server using the standard URI format:
74+
```rust
75+
let conn = PostgresConnection::connect("postgres://user:pass@host:port/database?arg1=val1&arg2=val2");
76+
```
77+
As the Rust standard library currently lacks DNS lookup functionality, `host`
78+
must currently be an IP address.
79+
80+
`pass` may be omitted if not needed. `port` defaults to `5432` and `database`
81+
defaults to the value of `user` if not specified. The driver supports `trust`,
82+
`password` and `md5` authentication.
83+
84+
Statement Preparation
85+
---------------------
86+
Prepared statements can have parameters, represented as `$n` where `n` is an
87+
index into the parameter array starting from 1:
88+
```rust
89+
let stmt = conn.prepare("SELECT * FROM foo WHERE bar = $1 AND baz = $2");
90+
```
91+
92+
Querying
93+
--------
94+
A prepared statement can be executed with the `query` and `update` methods.
95+
Both methods take an array of parameters to bind to the query represented as
96+
`&ToSql` trait objects. `update` returns the number of rows affected by the
97+
query (or 0 if not applicable):
98+
```
99+
let stmt = conn.prepare("UPDATE foo SET bar = $1 WHERE baz = $2");
100+
let updates = stmt.update([&1i32 as &ToSql, & &"biz" as &ToSql]);
101+
println!("{} rows were updated", updates);
102+
```
103+
`query` returns a result iterator. Fields of each row in the result can be
104+
accessed either by its index or their column name:
105+
```rust
106+
let stmt = conn.prepare("SELECT bar, baz FROM foo");
107+
for row in stmt.query([]) {
108+
let bar: i32 = row[0];
109+
let baz: ~str = row["baz"];
110+
println!("bar: {}, baz: {}", bar, baz);
111+
}
112+
```
113+
In addition, `PostgresConnection` has a utility `update` method which is useful
114+
if a statement is only going to be executed once:
115+
```rust
116+
let updates = conn.update("UPDATE foo SET bar = $1 WHERE baz = $2",
117+
[&1i32 as &ToSql, & &"biz" as &ToSql]);
118+
println!("{} rows were updated", updates);
119+
```
120+
121+
Transactions
122+
------------
123+
Transactions are encapsulated by the `in_transaction` method. `in_transaction`
124+
takes a closure which is passed a `PostgresTransaction` object which has the
125+
functionality of a `PostgresConnection` as well as methods to control the
126+
result of the transaction:
127+
```rust
128+
do conn.in_transaction |trans| {
129+
trans.update(...);
130+
let stmt = trans.prepare(...);
131+
132+
if a_bad_thing_happened {
133+
trans.set_rollback();
134+
}
135+
136+
if the_coast_is_clear {
137+
trans.set_commit();
138+
}
139+
}
140+
```
141+
A transaction will commit by default. Transactions cannot currently be nested.
142+
143+
Error Handling
144+
--------------
145+
The methods described above will fail if there is an error. For each of these
146+
methods, there is a second variant prefixed with `try_` which returns a
147+
`Result`:
148+
```rust
149+
match conn.try_update(query) {
150+
Ok(updates) => println!("{} rows were updated", updates),
151+
Err(err) => println!("An error occurred: {}", err.to_str())
152+
}
153+
```
154+
155+
Type Correspondence
156+
-------------------
157+
Rust-Postgres enforces a strict correspondence between Rust types and Postgres
158+
types. The driver currently natively supports the following conversions:
159+
160+
<table>
161+
<thead>
162+
<tr>
163+
<td>Rust Type</td>
164+
<td>Postgres Type</td>
165+
</tr>
166+
</thead>
167+
<tbody>
168+
<tr>
169+
<td>bool</td>
170+
<td>BOOL</td>
171+
</tr>
172+
<tr>
173+
<td>i8</td>
174+
<td>"char"</td>
175+
</tr>
176+
<tr>
177+
<td>i16</td>
178+
<td>SMALLINT</td>
179+
</tr>
180+
<tr>
181+
<td>i32</td>
182+
<td>INT</td>
183+
</tr>
184+
<tr>
185+
<td>i64</td>
186+
<td>BIGINT</td>
187+
</tr>
188+
<tr>
189+
<td>f32</td>
190+
<td>FLOAT4</td>
191+
</tr>
192+
<tr>
193+
<td>f64</td>
194+
<td>FLOAT8</td>
195+
</tr>
196+
<tr>
197+
<td>str</td>
198+
<td>VARCHAR, CHAR(n), TEXT</td>
199+
</tr>
200+
<tr>
201+
<td>[u8]</td>
202+
<td>BYTEA</td>
203+
</tr>
204+
<tr>
205+
<td>extra::json::Json</td>
206+
<td>JSON</td>
207+
</tr>
208+
<tr>
209+
<td>extra::uuid::Uuid</td>
210+
<td>UUID</td>
211+
</tr>
212+
</tbody>
213+
</table>
214+
215+
More conversions can be defined by implementing the `ToSql` and `FromSql`
216+
traits.
217+
218+
Development
219+
===========
220+
Rust-Postgres is still under active development, so don't be surprised if APIs
221+
change and things break. If something's not working properly, file an issue or
222+
submit a pull request!

src/types.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,13 @@ to_option_impl!(FLOAT4OID, f32)
195195
to_conversions_impl!(FLOAT8OID, f64, write_be_f64_)
196196
to_option_impl!(FLOAT8OID, f64)
197197

198+
impl ToSql for ~str {
199+
fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
200+
check_oid!(VARCHAROID | TEXTOID | BPCHAROID, ty)
201+
(Text, Some(self.as_bytes().to_owned()))
202+
}
203+
}
204+
198205
impl<'self> ToSql for &'self str {
199206
fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
200207
check_oid!(VARCHAROID | TEXTOID | BPCHAROID, ty)
@@ -205,6 +212,13 @@ impl<'self> ToSql for &'self str {
205212
to_option_impl!(VARCHAROID | TEXTOID | BPCHAROID, ~str)
206213
to_option_impl!(self, VARCHAROID | TEXTOID | BPCHAROID, &'self str)
207214

215+
impl ToSql for ~[u8] {
216+
fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
217+
check_oid!(BYTEAOID, ty)
218+
(Binary, Some(self.to_owned()))
219+
}
220+
}
221+
208222
impl<'self> ToSql for &'self [u8] {
209223
fn to_sql(&self, ty: Oid) -> (Format, Option<~[u8]>) {
210224
check_oid!(BYTEAOID, ty)

0 commit comments

Comments
 (0)