use torm::*;
use chrono::Utc;
#[tokio::main]
async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("🚀 TORM - Tokio ORM Demo (Simplified Dependencies)\n");
println!("📡 Database connection example");
println!("========================");
demonstrate_database_connection().await?;
println!();
println!("🔑 Simplified UUID generation");
println!("========================");
demonstrate_simplified_uuid()?;
println!();
println!("⚠️ Simplified error handling");
println!("========================");
demonstrate_simplified_error()?;
println!();
println!("💾 Simplified LRU cache");
println!("========================");
demonstrate_simplified_cache()?;
println!();
println!("🏊 Simple connection pool");
println!("========================");
demonstrate_connection_pool().await?;
println!();
println!("🔨 Query builder example");
println!("========================");
demonstrate_query_builder();
println!();
println!("🗄️ Pure Rust SQL Engine");
println!("========================");
demonstrate_sql_engine().await?;
println!();
println!("🎉 All demos completed successfully!");
println!();
println!("📚 Simplified dependencies benefits:");
println!(" ✅ Reduced external dependencies");
println!(" ✅ Custom implementations for critical components");
println!(" ✅ Pure Rust SQL engine (no rusqlite)");
println!(" ✅ Better control over functionality and performance");
println!(" ✅ Faster compilation with fewer dependencies");
println!(" ✅ Smaller binary size");
println!();
println!("📦 Remaining dependencies:");
println!(" • tokio - Async runtime (essential)");
println!(" • serde/serde_json - Serialization (essential)");
println!(" • chrono - Time handling (essential)");
println!(" • uuid - UUID generation (essential)");
Ok(())
}
async fn demonstrate_database_connection() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("SQLite connection:");
let dsn = Dsn::new(DBDriver::SQLite, "demo.db");
println!(" DSN: {}", dsn.build());
let db = Database::sqlite(":memory:").await?;
println!(" ✅ Connected to in-memory SQLite (pure Rust engine)");
println!(" DB type: {:?}", db.db_type());
println!(" Connected: {}", db.is_connected());
db.close().await?;
println!();
println!("MySQL connection example:");
let mysql_dsn = Dsn::new(DBDriver::MySQL, "mydb")
.with_host("localhost")
.with_port(3306)
.with_username("user")
.with_password("password");
println!(" DSN: {}", mysql_dsn.build());
println!();
println!("PostgreSQL connection example:");
let pg_dsn = Dsn::new(DBDriver::PostgreSQL, "mydb")
.with_host("localhost")
.with_port(5432)
.with_username("user")
.with_password("password");
println!(" DSN: {}", pg_dsn.build());
Ok(())
}
fn demonstrate_simplified_uuid() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("Generating UUIDs:");
let uuid1 = SimpleUuid::new_v4();
let uuid2 = SimpleUuid::new_v4();
let uuid3 = SimpleUuid::new_v4();
println!(" UUID 1: {}", uuid1);
println!(" UUID 2: {}", uuid2);
println!(" UUID 3: {}", uuid3);
println!(" All unique: {}", uuid1 != uuid2 && uuid2 != uuid3 && uuid1 != uuid3);
println!();
println!("ID Generator:");
let generator = IdGenerator::new();
let id1 = generator.generate();
let id2 = generator.generate();
println!(" ID 1: {}", id1);
println!(" ID 2: {}", id2);
println!(" ID 3: {}", generator.with_prefix("user_").generate());
println!();
println!("Simple IDs:");
let simple_gen = IdGenerator::new().with_simple_id();
println!(" Simple ID: {}", simple_gen.generate());
println!(" Prefixed: {}", simple_gen.with_prefix("order_").generate());
Ok(())
}
fn demonstrate_simplified_error() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("Error handling without thiserror:");
let not_found = SimpleError::NotFound;
println!(" NotFound: {}", not_found);
let custom = SimpleError::custom("Something went wrong");
println!(" Custom: {}", custom);
let invalid_query = SimpleError::invalid_query("Invalid WHERE clause");
println!(" InvalidQuery: {}", invalid_query);
let connection_error = SimpleError::connection_error("Could not connect to database");
println!(" ConnectionError: {}", connection_error);
println!();
println!("Using SimpleResult:");
let success: SimpleResult<i32> = Ok(42);
println!(" Success: {:?}", success);
let failure: SimpleResult<i32> = Err(SimpleError::NotFound);
println!(" Failure: {:?}", failure);
Ok(())
}
fn demonstrate_simplified_cache() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("LRU cache:");
let mut cache: SimpleLruCache<&str, &str> = SimpleLruCache::new(3);
cache.put("key1", "value1");
cache.put("key2", "value2");
cache.put("key3", "value3");
println!(" Initial size: {}", cache.len());
println!(" key1: {:?}", cache.get(&"key1"));
println!(" key2: {:?}", cache.get(&"key2"));
println!(" key3: {:?}", cache.get(&"key3"));
println!();
println!(" Adding key4 (should evict oldest):");
cache.put("key4", "value4");
println!(" key1: {:?}", cache.get(&"key1")); println!(" key4: {:?}", cache.get(&"key4"));
println!();
println!(" Current capacity: {}", cache.capacity());
println!(" Current size: {}", cache.len());
cache.resize(2);
println!(" After resize to 2:");
println!(" New size: {}", cache.len());
cache.clear();
println!(" After clear: {}", cache.is_empty());
Ok(())
}
async fn demonstrate_connection_pool() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("Simple connection pool implementation:");
let connections = vec![1, 2, 3, 4, 5];
let pool = SimplePool::new(connections);
let status = pool.status();
println!(" Total connections: {}", status.total_connections);
println!(" Idle connections: {}", status.idle_connections);
println!(" Active connections: {}", status.active_connections);
println!(" Utilization: {:.1}%", status.utilization_rate() * 100.0);
println!();
println!(" Getting a connection from pool:");
match pool.get().await {
Ok(conn) => {
println!(" Got: {}", conn);
let status = pool.status();
println!(" After get - idle: {}, active: {}", status.idle_connections, status.active_connections);
pool.put(conn);
let status = pool.status();
println!(" After put - idle: {}, active: {}", status.idle_connections, status.active_connections);
}
Err(e) => println!(" Error: {}", e),
}
println!();
println!("Pool features:");
println!(" • Connection reuse");
println!(" • Timeout handling");
println!(" • No external deadpool dependency");
Ok(())
}
async fn demonstrate_sql_engine() -> std::result::Result<(), Box<dyn std::error::Error>> {
println!("Pure Rust SQL engine (no rusqlite):");
let db = Database::sqlite(":memory:").await?;
db.execute("CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, age INTEGER)", &[]).await?;
println!(" ✅ Created users table");
db.execute("INSERT INTO users VALUES (1, 'Alice', 25)", &[]).await?;
db.execute("INSERT INTO users VALUES (2, 'Bob', 30)", &[]).await?;
db.execute("INSERT INTO users VALUES (3, 'Charlie', 35)", &[]).await?;
println!(" ✅ Inserted 3 users");
let result = db.query("SELECT * FROM users", &[]).await?;
println!(" ✅ Query returned {} rows", result.rows.len());
for row in &result.rows {
println!(" Row: {:?}", row);
}
let affected = db.execute("UPDATE users SET age = 26 WHERE id = 1", &[]).await?;
println!(" ✅ Updated {} row(s)", affected);
let _count = db.execute("SELECT COUNT(*) FROM users", &[]).await?;
println!(" ✅ Count query executed");
let affected = db.execute("DELETE FROM users WHERE age > 32", &[]).await?;
println!(" ✅ Deleted {} row(s)", affected);
let mut transaction = db.begin_transaction().await?;
transaction.execute("INSERT INTO users VALUES (4, 'Dave', 40)", &[]).await?;
transaction.commit().await?;
println!(" ✅ Transaction committed");
db.close().await?;
println!(" ✅ Database closed");
Ok(())
}
fn demonstrate_query_builder() {
println!("Query builder examples:");
let (sql, bindings) = QueryBuilder::new("users")
.where_eq("email", "john@example.com")
.limit(1)
.build();
println!(" Basic query:");
println!(" SQL: {}", sql);
println!(" Bindings: {:?}", bindings);
let (sql, bindings) = QueryBuilder::new("users")
.where_eq("status", "active")
.where_gt("age", 18)
.where_like("name", "John%")
.order_by("created_at", "DESC")
.limit(10)
.build();
println!();
println!(" Complex query:");
println!(" SQL: {}", sql);
println!(" Bindings: {:?}", bindings);
let (sql, bindings) = QueryBuilder::new("users")
.where_in("id", vec![SqlValue::I32(1), SqlValue::I32(2), SqlValue::I32(3)])
.build();
println!();
println!(" IN query:");
println!(" SQL: {}", sql);
println!(" Bindings: {:?}", bindings);
let (sql, bindings) = QueryBuilder::new("users")
.where_between("age", 18, 65)
.build();
println!();
println!(" BETWEEN query:");
println!(" SQL: {}", sql);
println!(" Bindings: {:?}", bindings);
}
#[derive(Debug, Clone)]
pub struct User {
pub id: String,
pub name: String,
pub email: String,
pub age: Option<i32>,
pub status: String,
pub timestamps: torm::orm::model::Timestamps,
}
impl User {
pub fn new(name: &str, email: &str) -> Self {
let generator = IdGenerator::new().with_prefix("user_");
Self {
id: generator.generate(),
name: name.to_string(),
email: email.to_string(),
age: None,
status: "active".to_string(),
timestamps: torm::orm::model::Timestamps::new(),
}
}
pub fn with_age(mut self, age: i32) -> Self {
self.age = Some(age);
self
}
pub fn with_status(mut self, status: &str) -> Self {
self.status = status.to_string();
self
}
}
#[async_trait::async_trait]
impl Model for User {
fn table_name() -> &'static str {
"users"
}
fn id(&self) -> Option<String> {
if self.id.is_empty() {
None
} else {
Some(self.id.clone())
}
}
fn set_id(&mut self, id: String) {
self.id = id;
}
fn created_at(&self) -> Option<chrono::DateTime<Utc>> {
self.timestamps.created_at
}
fn updated_at(&self) -> Option<chrono::DateTime<Utc>> {
self.timestamps.updated_at
}
fn deleted_at(&self) -> Option<chrono::DateTime<Utc>> {
self.timestamps.deleted_at
}
fn set_created_at(&mut self, timestamp: chrono::DateTime<Utc>) {
self.timestamps.created_at = Some(timestamp);
}
fn set_updated_at(&mut self, timestamp: chrono::DateTime<Utc>) {
self.timestamps.updated_at = Some(timestamp);
}
fn set_deleted_at(&mut self, timestamp: Option<chrono::DateTime<Utc>>) {
self.timestamps.deleted_at = timestamp;
}
}