monoio-pg 0.1.10

High-performance asynchronous PostgreSQL driver for monoio
Documentation
# monoio-pg Manual

`monoio-pg` is a high-performance PostgreSQL driver designed specifically for the `monoio` asynchronous runtime. It leverages `io_uring` and a thread-per-core architecture to provide superior throughput and low latency.

## Table of Contents

- [Core Concepts]#core-concepts
- [Getting Started]#getting-started
- [Connection Management]#connection-management
- [Executing Queries]#executing-queries
- [Working with Rows]#working-with-rows
- [Error Handling]#error-handling
- [Examples]#examples

## Core Concepts

- **Thread-per-core**: `monoio-pg` is designed to run on `monoio`. Each thread manages its own events and connections, minimizing lock contention.
- **io_uring**: High-efficiency I/O subsystem on Linux, providing asynchronous system calls.
- **Extended Query Protocol**: `monoio-pg` uses the PostgreSQL extended query protocol, which is more robust and efficient than simple queries.

## Getting Started

Add `monoio-pg` and `monoio` to your `Cargo.toml`:

```toml
[dependencies]
monoio = { version = "0.2", features = ["macros"] }
monoio-pg = "0.1"
```

## Connection Management

### Direct Connection

You can connect directly to a PostgreSQL server using the `Client` struct.

```rust
use monoio_pg::Client;

let client = Client::connect(
    "127.0.0.1:5432",
    "postgres",
    Some("password"),
    Some("database_name")
).await?;
```

### Connection Pooling (Thread-local)

Since `monoio` is thread-per-core, the pool provided by `monoio-pg` is thread-local. This avoids sharing clients across threads, which is a key performance optimization.

```rust
use monoio_pg::Pool;

let pool = Pool::new(
    "127.0.0.1:5432",
    "postgres",
    Some("password"),
    Some("database_name")
);

// Get a client from the pool
let mut client = pool.get().await?;

// Use the client...

// Return the client to the pool
pool.put(client);
```

## Executing Queries

### `execute`

Use `execute` for queries that don't return rows (e.g., `INSERT`, `UPDATE`, `CREATE TABLE`).

```rust
client.execute("CREATE TABLE users (id SERIAL PRIMARY KEY, name TEXT)").await?;
```

### `query`

Use `query` for queries that return rows (e.g., `SELECT`).

```rust
let rows = client.query("SELECT id, name FROM users").await?;
```

## Working with Rows

`monoio-pg` provides a type-safe way to extract data from rows using the `get` method, which supports types implementing the `FromSql` trait from the `postgres-types` crate.

```rust
for row in rows {
    let id: i32 = row.get(0)?;
    let name: String = row.get(1)?;
    println!("User: {} (ID: {})", name, id);
}
```

Common supported types:
- `i32`, `i64`
- `String`, `&str`
- `bool`
- `Vec<u8>`
- `Option<T>` (for nullable columns)

## Error Handling

All database operations return a `Result<T, monoio_pg::Error>`.

```rust
use monoio_pg::Error;

match client.query("SELECT * FROM non_existent").await {
    Ok(_) => println!("Success"),
    Err(Error::Protocol(msg)) => eprintln!("Postgres Error: {}", msg),
    Err(e) => eprintln!("Other Error: {}", e),
}
```

## Examples

For more comprehensive examples, check the `examples/` directory in the repository.

### Basic SELECT

```rust
#[monoio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut client = Client::connect("127.0.0.1:5432", "postgres", None, None).await?;
    
    let rows = client.query("SELECT 'Hello Monoio'").await?;
    let greeting: String = rows[0].get(0)?;
    
    println!("{}", greeting);
    Ok(())
}
```