Ormer
Home
Quick Start
GitHub
  • 简体中文
  • English
Home
Quick Start
GitHub
  • 简体中文
  • English
  • Introduction to Ormer
  • Quick Start
  • Model Definition
  • Database Connection
  • Data Operations
  • Query Builder
  • Advanced Queries
  • Transaction Management
  • Connection Pool

Database Connection

Ormer supports multiple database backends with a unified connection interface.

Supported Databases

  • Turso (libSQL/SQLite) - Embedded database, suitable for development and lightweight applications
  • PostgreSQL - Powerful enterprise-grade relational database
  • MySQL - Popular open-source database

Enabling Database Features

Enable the required database features in Cargo.toml:

[dependencies]
ormer = { version = "0.1", features = ["turso"] }
# or
ormer = { version = "0.1", features = ["postgresql"] }
# or
ormer = { version = "0.1", features = ["mysql"] }
# or enable multiple simultaneously
ormer = { version = "0.1", features = ["turso", "postgresql", "mysql"] }

Connecting to Database

Basic Connection

Use the Database::connect() method to connect to a database:

use ormer::{Database, DbType};

// Turso/SQLite
let db = Database::connect(DbType::Turso, "file:test.db").await?;

// PostgreSQL
let db = Database::connect(
    DbType::PostgreSQL,
    "postgresql://user:password@localhost/dbname"
).await?;

// MySQL
let db = Database::connect(
    DbType::MySQL,
    "mysql://user:password@localhost/dbname"
).await?;

Connection String Formats

Turso/SQLite

// In-memory database (for testing)
"file::memory:"

// File database
"file:test.db"
"file:/path/to/database.db"

// Remote Turso database
"libsql://your-database-url.turso.io?authToken=your-token"

PostgreSQL

// Basic format
"postgresql://user:password@localhost/dbname"

// Full format
"postgresql://user:password@host:port/dbname?sslmode=require"

// Example
"postgresql://postgres:123456@localhost:5432/mydb"

MySQL

// Basic format
"mysql://user:password@localhost/dbname"

// Full format
"mysql://user:password@host:port/dbname"

// Example
"mysql://root:123456@localhost:3306/mydb"

Complete Examples

Turso/SQLite Example

use ormer::{Database, DbType, Model};

#[derive(Debug, Model)]
#[table = "users"]
struct User {
    #[primary(auto)]
    id: i32,
    name: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Connect to database
    let db = Database::connect(DbType::Turso, "file:test.db").await?;
    
    // Create table
    db.create_table::<User>().await?;
    
    // Use database...
    
    // Cleanup
    db.drop_table::<User>().await?;
    
    Ok(())
}

PostgreSQL Example

use ormer::{Database, DbType, Model};

#[derive(Debug, Model)]
#[table = "users"]
struct User {
    #[primary(auto)]
    id: i32,
    name: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Connect to PostgreSQL
    let db = Database::connect(
        DbType::PostgreSQL,
        "postgresql://postgres:password@localhost/mydb"
    ).await?;
    
    // Create table
    db.create_table::<User>().await?;
    
    // Use database...
    
    Ok(())
}

MySQL Example

use ormer::{Database, DbType, Model};

#[derive(Debug, Model)]
#[table = "users"]
struct User {
    #[primary(auto)]
    id: i32,
    name: String,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Connect to MySQL
    let db = Database::connect(
        DbType::MySQL,
        "mysql://root:password@localhost/mydb"
    ).await?;
    
    // Create table
    db.create_table::<User>().await?;
    
    // Use database...
    
    Ok(())
}

Multiple Database Support

If your application needs to connect to multiple databases, you can create multiple Database instances:

use ormer::{Database, DbType};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Primary database (PostgreSQL)
    let primary_db = Database::connect(
        DbType::PostgreSQL,
        "postgresql://user:pass@localhost/primary_db"
    ).await?;
    
    // Analytics database (MySQL)
    let analytics_db = Database::connect(
        DbType::MySQL,
        "mysql://user:pass@localhost/analytics_db"
    ).await?;
    
    // Cache database (SQLite)
    let cache_db = Database::connect(
        DbType::Turso,
        "file:cache.db"
    ).await?;
    
    // Use different database instances...
    
    Ok(())
}

Connection Pool

For production environments, it's recommended to use a connection pool to manage database connections:

use ormer::{Database, DbType, ConnectionPool};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Create connection pool
    let pool = Database::create_pool(DbType::PostgreSQL, "postgresql://user:pass@localhost/dbname")
        .max_size(10)  // Maximum connections
        .build()
        .await?;
    
    // Get connection from pool
    let conn = pool.get().await?;
    
    // Use connection...
    
    Ok(())
}

See Connection Pool Documentation for details.

Error Handling

Connection failures return an Error:

use ormer::{Database, DbType, Error};

async fn connect_db() -> Result<(), Error> {
    let db = Database::connect(DbType::PostgreSQL, "invalid-url")
        .await
        .map_err(|e| {
            eprintln!("Failed to connect: {}", e);
            e
        })?;
    
    Ok(())
}

Common errors:

  • Invalid connection string format
  • Database service not running
  • Authentication failure (wrong username/password)
  • Network issues
  • Database does not exist

In-Memory Database for Testing

Using an in-memory database for testing is very convenient:

#[cfg(test)]
mod tests {
    use ormer::{Database, DbType, Model};
    
    #[derive(Debug, Model)]
    #[table = "test_users"]
    struct TestUser {
        #[primary(auto)]
        id: i32,
        name: String,
    }
    
    #[tokio::test]
    async fn test_user_operations() {
        // Use in-memory database
        let db = Database::connect(DbType::Turso, "file::memory:").await.unwrap();
        
        db.create_table::<TestUser>().await.unwrap();
        
        // Test logic...
    }
}

Database Feature Check

Ormer checks at compile time whether at least one database feature is enabled:

compile_error!("At least one database feature must be enabled: turso, postgresql, or mysql");

If you see this error, make sure you have enabled at least one database feature in Cargo.toml.

Best Practices

1. Use Environment Variables for Connection Strings

use std::env;

let db_url = env::var("DATABASE_URL")
    .expect("DATABASE_URL must be set");

let db = Database::connect(DbType::PostgreSQL, &db_url).await?;

2. Establish Connection at Application Startup

struct AppState {
    db: Database,
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let db = Database::connect(DbType::PostgreSQL, &db_url).await?;
    let state = AppState { db };
    
    // Use state...
    
    Ok(())
}

3. Use Connection Pool in Production

// Recommended: Use connection pool
let pool = Database::create_pool(DbType::PostgreSQL, &db_url)
    .max_size(20)
    .build()
    .await?;

// Avoid: Creating new connection for each operation
let db = Database::connect(DbType::PostgreSQL, &db_url).await?;

4. Graceful Connection Closure

// Connection automatically closes when it goes out of scope
{
    let db = Database::connect(DbType::Turso, "file:test.db").await?;
    // Use database...
} // db is dropped here, connection closes
Prev
Model Definition
Next
Data Operations