Giter VIP home page Giter VIP logo

rust-postgres's Introduction

Rust-Postgres

A native PostgreSQL driver for Rust.

Documentation is available at http://www.rust-ci.org/sfackler/rust-postgres/doc/postgres/.

Build Status

Overview

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.

extern crate postgres;
extern crate time;

use time::Timespec;

use postgres::{PostgresConnection, NoSsl};
use postgres::types::ToSql;

struct Person {
    id: i32,
    name: String,
    time_created: Timespec,
    data: Option<Vec<u8>>
}

fn main() {
    let conn = PostgresConnection::connect("postgres://postgres@localhost",
                                           &NoSsl).unwrap();

    conn.execute("CREATE TABLE person (
                    id              SERIAL PRIMARY KEY,
                    name            VARCHAR NOT NULL,
                    time_created    TIMESTAMP NOT NULL,
                    data            BYTEA
                  )", []).unwrap();
    let me = Person {
        id: 0,
        name: "Steven".to_string(),
        time_created: time::get_time(),
        data: None
    };
    conn.execute("INSERT INTO person (name, time_created, data)
                    VALUES ($1, $2, $3)",
                 [&me.name, &me.time_created, &me.data]).unwrap();

    let stmt = conn.prepare("SELECT id, name, time_created, data FROM person")
            .unwrap();
    for row in stmt.query([]).unwrap() {
        let person = Person {
            id: row.get(0u),
            name: row.get(1u),
            time_created: row.get(2u),
            data: row.get(3u)
        };
        println!("Found person {}", person.name);
    }
}

Requirements

  • Rust - Rust-Postgres is developed against the master branch of the Rust repository. It will most likely not build against the versioned releases on http://www.rust-lang.org.

  • 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.

Usage

Connecting

Connect to a Postgres server using the standard URI format:

let conn = try!(PostgresConnection::connect("postgres://user:pass@host:port/database?arg1=val1&arg2=val2",
                                            &NoSsl));

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.

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.

let conn = try!(PosgresConnection::connect("postgres://postgres@%2Frun%2Fpostgres", &NoSsl));

Paths which contain non-UTF8 characters can be handled in a different manner; see the documentation for details.

Statement Preparation

Prepared statements can have parameters, represented as $n where n is an index into the parameter array starting from 1:

let stmt = try!(conn.prepare("SELECT * FROM foo WHERE bar = $1 AND baz = $2"));

Querying

A prepared statement can be executed with the query and execute methods. 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 query (or 0 if not applicable):

let stmt = try!(conn.prepare("UPDATE foo SET bar = $1 WHERE baz = $2"));
let updates = try!(stmt.execute([&1i32, &"biz"]));
println!("{} rows were updated", updates);

query returns an iterator over 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.

let stmt = try!(conn.prepare("SELECT bar, baz FROM foo"));
for row in try!(stmt.query([])) {
    let bar: i32 = row.get(0u);
    let baz: String = row.get("baz");
    println!("bar: {}, baz: {}", bar, baz);
}

In addition, PostgresConnection has a utility execute method which is useful if a statement is only going to be executed once:

let updates = try!(conn.execute("UPDATE foo SET bar = $1 WHERE baz = $2",
                                [&1i32, &"biz"]));
println!("{} rows were updated", updates);

Transactions

The transaction method will start a new transaction. It returns a PostgresTransaction object which has the functionality of a PostgresConnection as well as methods to control the result of the transaction:

let trans = try!(conn.transaction());
try!(trans.execute(...));
let stmt = try!(trans.prepare(...));

if the_coast_is_clear {
    trans.set_commit();
}

try!(trans.finish());

The transaction will be active until the PostgresTransaction object falls out of scope. A transaction will roll back by default. Nested transactions are supported via savepoints.

Connection Pooling

A very basic fixed-size connection pool is provided in the pool module. A single pool can be shared across tasks and get_connection will block until a connection is available.

let pool = try!(PostgresConnectionPool::new("postgres://postgres@localhost",
                                            NoSsl, 5));

for _ in range(0, 10) {
    let pool = pool.clone();
    spawn(proc() {
        let conn = pool.get_connection();
        conn.query(...).unwrap();
    })
}

Type Correspondence

Rust-Postgres enforces a strict correspondence between Rust types and Postgres types. The driver currently supports the following conversions:

Rust Type Postgres Type
bool BOOL
i8 "char"
i16 SMALLINT, SMALLSERIAL
i32 INT, SERIAL
i64 BIGINT, BIGSERIAL
f32 REAL
f64 DOUBLE PRECISION
str/String VARCHAR, CHAR(n), TEXT
[u8]/Vec<u8> BYTEA
serialize::json::Json JSON
time::Timespec TIMESTAMP, TIMESTAMP WITH TIME ZONE
types::range::Range<i32> INT4RANGE
types::range::Range<i64> INT8RANGE
types::range::Range<Timespec> TSRANGE, TSTZRANGE
types::array::ArrayBase<Option<bool>> BOOL[], BOOL[][], ...
types::array::ArrayBase<Option<Vec<u8>>> BYTEA[], BYTEA[][], ...
types::array::ArrayBase<Option<i8>> "char"[], "char"[][], ...
types::array::ArrayBase<Option<i16>> INT2[], INT2[][], ...
types::array::ArrayBase<Option<i32>> INT4[], INT4[][], ...
types::array::ArrayBase<Option<String>> TEXT[], CHAR(n)[], VARCHAR[], TEXT[][], ...
types::array::ArrayBase<Option<Json>> JSON[], JSON[][], ...
types::array::ArrayBase<Option<i64>> INT8[], INT8[][], ...
types::array::ArrayBase<Option<Timespec>> TIMESTAMP[], TIMESTAMPTZ[], TIMESTAMP[][], ...
types::array::ArrayBase<Option<f32>> FLOAT4[], FLOAT4[][], ...
types::array::ArrayBase<Option<f64>> FLOAT8[], FLOAT8[][], ...
types::array::ArrayBase<Option<Range<i32>>> INT4RANGE[], INT4RANGE[][], ...
types::array::ArrayBase<Option<Range<Timespec>>> TSRANGE[], TSTZRANGE[], TSRANGE[][], ...
types::array::ArrayBase<Option<Range<i64>>> INT8RANGE[], INT8RANGE[][], ...
std::collections::HashMap<String, Option<String>> HSTORE

More conversions can be defined by implementing the ToSql and FromSql traits.

Development

Like Rust itself, Rust-Postgres is still in the early stages of development, so don't be surprised if APIs change and things break. If something's not working properly, file an issue or submit a pull request!

rust-postgres's People

Contributors

sfackler avatar alexcrichton avatar jsanders avatar radford avatar zr40 avatar mikedilger avatar wunki avatar johto avatar

Watchers

Daniel Fagnan avatar James Cloos avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.