Skip to main content

basic_usage/
basic_usage.rs

1use torm::*;
2use chrono::Utc;
3
4#[tokio::main]
5async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
6    println!("🚀 TORM - Tokio ORM Demo (Simplified Dependencies)\n");
7
8    // 1. Database connection example
9    println!("📡 Database connection example");
10    println!("========================");
11    demonstrate_database_connection().await?;
12    println!();
13
14    // 2. Simplified UUID generation
15    println!("🔑 Simplified UUID generation");
16    println!("========================");
17    demonstrate_simplified_uuid()?;
18    println!();
19
20    // 3. Simplified error handling
21    println!("⚠️  Simplified error handling");
22    println!("========================");
23    demonstrate_simplified_error()?;
24    println!();
25
26    // 4. Simplified LRU cache
27    println!("💾 Simplified LRU cache");
28    println!("========================");
29    demonstrate_simplified_cache()?;
30    println!();
31
32    // 5. Connection pool
33    println!("🏊 Simple connection pool");
34    println!("========================");
35    demonstrate_connection_pool().await?;
36    println!();
37
38    // 6. Query builder example
39    println!("🔨 Query builder example");
40    println!("========================");
41    demonstrate_query_builder();
42    println!();
43
44    // 7. Pure Rust SQL engine example
45    println!("🗄️  Pure Rust SQL Engine");
46    println!("========================");
47    demonstrate_sql_engine().await?;
48    println!();
49
50    println!("🎉 All demos completed successfully!");
51    println!();
52    println!("📚 Simplified dependencies benefits:");
53    println!("  ✅ Reduced external dependencies");
54    println!("  ✅ Custom implementations for critical components");
55    println!("  ✅ Pure Rust SQL engine (no rusqlite)");
56    println!("  ✅ Better control over functionality and performance");
57    println!("  ✅ Faster compilation with fewer dependencies");
58    println!("  ✅ Smaller binary size");
59    println!();
60    println!("📦 Remaining dependencies:");
61    println!("  • tokio - Async runtime (essential)");
62    println!("  • serde/serde_json - Serialization (essential)");
63    println!("  • chrono - Time handling (essential)");
64    println!("  • uuid - UUID generation (essential)");
65
66    Ok(())
67}
68
69async fn demonstrate_database_connection() -> std::result::Result<(), Box<dyn std::error::Error>> {
70    println!("SQLite connection:");
71    let dsn = Dsn::new(DBDriver::SQLite, "demo.db");
72    println!("  DSN: {}", dsn.build());
73    
74    // Test actual SQLite connection with pure Rust engine
75    let db = Database::sqlite(":memory:").await?;
76    println!("  ✅ Connected to in-memory SQLite (pure Rust engine)");
77    println!("  DB type: {:?}", db.db_type());
78    println!("  Connected: {}", db.is_connected());
79    db.close().await?;
80    
81    println!();
82    println!("MySQL connection example:");
83    let mysql_dsn = Dsn::new(DBDriver::MySQL, "mydb")
84        .with_host("localhost")
85        .with_port(3306)
86        .with_username("user")
87        .with_password("password");
88    println!("  DSN: {}", mysql_dsn.build());
89    
90    println!();
91    println!("PostgreSQL connection example:");
92    let pg_dsn = Dsn::new(DBDriver::PostgreSQL, "mydb")
93        .with_host("localhost")
94        .with_port(5432)
95        .with_username("user")
96        .with_password("password");
97    println!("  DSN: {}", pg_dsn.build());
98
99    Ok(())
100}
101
102fn demonstrate_simplified_uuid() -> std::result::Result<(), Box<dyn std::error::Error>> {
103    println!("Generating UUIDs:");
104    
105    // Generate multiple UUIDs
106    let uuid1 = SimpleUuid::new_v4();
107    let uuid2 = SimpleUuid::new_v4();
108    let uuid3 = SimpleUuid::new_v4();
109    
110    println!("  UUID 1: {}", uuid1);
111    println!("  UUID 2: {}", uuid2);
112    println!("  UUID 3: {}", uuid3);
113    println!("  All unique: {}", uuid1 != uuid2 && uuid2 != uuid3 && uuid1 != uuid3);
114    
115    println!();
116    println!("ID Generator:");
117    let generator = IdGenerator::new();
118    let id1 = generator.generate();
119    let id2 = generator.generate();
120    
121    println!("  ID 1: {}", id1);
122    println!("  ID 2: {}", id2);
123    println!("  ID 3: {}", generator.with_prefix("user_").generate());
124    
125    println!();
126    println!("Simple IDs:");
127    let simple_gen = IdGenerator::new().with_simple_id();
128    println!("  Simple ID: {}", simple_gen.generate());
129    println!("  Prefixed: {}", simple_gen.with_prefix("order_").generate());
130
131    Ok(())
132}
133
134fn demonstrate_simplified_error() -> std::result::Result<(), Box<dyn std::error::Error>> {
135    println!("Error handling without thiserror:");
136    
137    // Create different error types
138    let not_found = SimpleError::NotFound;
139    println!("  NotFound: {}", not_found);
140    
141    let custom = SimpleError::custom("Something went wrong");
142    println!("  Custom: {}", custom);
143    
144    let invalid_query = SimpleError::invalid_query("Invalid WHERE clause");
145    println!("  InvalidQuery: {}", invalid_query);
146    
147    let connection_error = SimpleError::connection_error("Could not connect to database");
148    println!("  ConnectionError: {}", connection_error);
149    
150    println!();
151    println!("Using SimpleResult:");
152    let success: SimpleResult<i32> = Ok(42);
153    println!("  Success: {:?}", success);
154    
155    let failure: SimpleResult<i32> = Err(SimpleError::NotFound);
156    println!("  Failure: {:?}", failure);
157
158    Ok(())
159}
160
161fn demonstrate_simplified_cache() -> std::result::Result<(), Box<dyn std::error::Error>> {
162    println!("LRU cache:");
163    
164    let mut cache: SimpleLruCache<&str, &str> = SimpleLruCache::new(3);
165    
166    // Add items
167    cache.put("key1", "value1");
168    cache.put("key2", "value2");
169    cache.put("key3", "value3");
170    
171    println!("  Initial size: {}", cache.len());
172    println!("  key1: {:?}", cache.get(&"key1"));
173    println!("  key2: {:?}", cache.get(&"key2"));
174    println!("  key3: {:?}", cache.get(&"key3"));
175    
176    // Test LRU eviction
177    println!();
178    println!("  Adding key4 (should evict oldest):");
179    cache.put("key4", "value4");
180    println!("  key1: {:?}", cache.get(&"key1")); // Should be None
181    println!("  key4: {:?}", cache.get(&"key4")); // Should be Some
182    
183    // Test capacity
184    println!();
185    println!("  Current capacity: {}", cache.capacity());
186    println!("  Current size: {}", cache.len());
187    
188    // Resize
189    cache.resize(2);
190    println!("  After resize to 2:");
191    println!("  New size: {}", cache.len());
192    
193    // Cleanup
194    cache.clear();
195    println!("  After clear: {}", cache.is_empty());
196
197    Ok(())
198}
199
200async fn demonstrate_connection_pool() -> std::result::Result<(), Box<dyn std::error::Error>> {
201    println!("Simple connection pool implementation:");
202    
203    // Create a pool with pre-created connections
204    let connections = vec![1, 2, 3, 4, 5];
205    let pool = SimplePool::new(connections);
206    let status = pool.status();
207    
208    println!("  Total connections: {}", status.total_connections);
209    println!("  Idle connections: {}", status.idle_connections);
210    println!("  Active connections: {}", status.active_connections);
211    println!("  Utilization: {:.1}%", status.utilization_rate() * 100.0);
212    
213    // Test getting a connection
214    println!();
215    println!("  Getting a connection from pool:");
216    match pool.get().await {
217        Ok(conn) => {
218            println!("    Got: {}", conn);
219            let status = pool.status();
220            println!("    After get - idle: {}, active: {}", status.idle_connections, status.active_connections);
221            pool.put(conn);
222            let status = pool.status();
223            println!("    After put - idle: {}, active: {}", status.idle_connections, status.active_connections);
224        }
225        Err(e) => println!("    Error: {}", e),
226    }
227    
228    println!();
229    println!("Pool features:");
230    println!("  • Connection reuse");
231    println!("  • Timeout handling");
232    println!("  • No external deadpool dependency");
233
234    Ok(())
235}
236
237async fn demonstrate_sql_engine() -> std::result::Result<(), Box<dyn std::error::Error>> {
238    println!("Pure Rust SQL engine (no rusqlite) + typed model:");
239    
240    let db = Database::sqlite(":memory:").await?;
241    
242    // 依据模型自动建表(零 SqlValue)
243    db.auto_migrate::<Product>().await?;
244    println!("  ✅ Created products table from model schema");
245    
246    // 通过模型 create 插入
247    let mut products = vec![
248        Product { id: 0, name: "Apple".to_string(), price: 5 },
249        Product { id: 0, name: "Banana".to_string(), price: 3 },
250        Product { id: 0, name: "Cherry".to_string(), price: 9 },
251    ];
252    for p in &mut products {
253        db.create(p).await?;
254    }
255    println!("  ✅ Inserted {} products", products.len());
256    
257    // 查询并映射回类型
258    let all: Vec<Product> = db.all::<Product>().await?;
259    println!("  ✅ Query returned {} rows", all.len());
260    for p in &all {
261        println!("    - {} price={}", p.name, p.price);
262    }
263    
264    // 更新(返回影响行数)
265    let affected = db.update(&mut products[0], &[("price", 6)]).await?;
266    println!("  ✅ Updated {} row(s)", affected);
267    
268    // 计数
269    let count = db.all::<Product>().await?.len();
270    println!("  ✅ Count = {}", count);
271    
272    // 删除(使用已回填主键的模型实例)
273    let affected = db.delete(&mut products[2]).await?;
274    println!("  ✅ Deleted {} row(s)", affected);
275    
276    db.close().await?;
277    println!("  ✅ Database closed");
278
279    Ok(())
280}
281
282fn demonstrate_query_builder() {
283    println!("Query builder examples:");
284    
285    // Basic query
286    let (sql, bindings) = QueryBuilder::new("users")
287        .where_eq("email", "john@example.com")
288        .limit(1)
289        .build();
290    println!("  Basic query:");
291    println!("    SQL: {}", sql);
292    println!("    Bindings: {:?}", bindings);
293
294    // Complex query
295    let (sql, bindings) = QueryBuilder::new("users")
296        .where_eq("status", "active")
297        .where_gt("age", 18)
298        .where_like("name", "John%")
299        .order_by("created_at", "DESC")
300        .limit(10)
301        .build();
302    println!();
303    println!("  Complex query:");
304    println!("    SQL: {}", sql);
305    println!("    Bindings: {:?}", bindings);
306
307    // IN query
308    let (sql, bindings) = QueryBuilder::new("users")
309        .where_in("id", vec![1, 2, 3])
310        .build();
311    println!();
312    println!("  IN query:");
313    println!("    SQL: {}", sql);
314    println!("    Bindings: {:?}", bindings);
315
316    // BETWEEN query
317    let (sql, bindings) = QueryBuilder::new("users")
318        .where_between("age", 18, 65)
319        .build();
320    println!();
321    println!("  BETWEEN query:");
322    println!("    SQL: {}", sql);
323    println!("    Bindings: {:?}", bindings);
324}
325
326/// Product 模型:使用 `#[derive(Model)]`,由宏自动生成 schema 与字段映射。
327#[derive(Debug, Clone, Model)]
328#[model(table_name = "products")]
329pub struct Product {
330    pub id: i64,
331    pub name: String,
332    pub price: i64,
333}
334
335// User model with simplified UUID
336#[derive(Debug, Clone)]
337pub struct User {
338    pub id: String,
339    pub name: String,
340    pub email: String,
341    pub age: Option<i32>,
342    pub status: String,
343    pub timestamps: torm::orm::model::Timestamps,
344}
345
346impl User {
347    pub fn new(name: &str, email: &str) -> Self {
348        let generator = IdGenerator::new().with_prefix("user_");
349        Self {
350            id: generator.generate(),
351            name: name.to_string(),
352            email: email.to_string(),
353            age: None,
354            status: "active".to_string(),
355            timestamps: torm::orm::model::Timestamps::new(),
356        }
357    }
358
359    pub fn with_age(mut self, age: i32) -> Self {
360        self.age = Some(age);
361        self
362    }
363
364    pub fn with_status(mut self, status: &str) -> Self {
365        self.status = status.to_string();
366        self
367    }
368}
369
370#[async_trait::async_trait]
371impl Model for User {
372    fn table_name() -> &'static str {
373        "users"
374    }
375
376    fn id(&self) -> Option<String> {
377        if self.id.is_empty() {
378            None
379        } else {
380            Some(self.id.clone())
381        }
382    }
383
384    fn set_id(&mut self, id: String) {
385        self.id = id;
386    }
387
388    fn created_at(&self) -> Option<chrono::DateTime<Utc>> {
389        self.timestamps.created_at
390    }
391
392    fn updated_at(&self) -> Option<chrono::DateTime<Utc>> {
393        self.timestamps.updated_at
394    }
395
396    fn deleted_at(&self) -> Option<chrono::DateTime<Utc>> {
397        self.timestamps.deleted_at
398    }
399
400    fn set_created_at(&mut self, timestamp: chrono::DateTime<Utc>) {
401        self.timestamps.created_at = Some(timestamp);
402    }
403
404    fn set_updated_at(&mut self, timestamp: chrono::DateTime<Utc>) {
405        self.timestamps.updated_at = Some(timestamp);
406    }
407
408    fn set_deleted_at(&mut self, timestamp: Option<chrono::DateTime<Utc>>) {
409        self.timestamps.deleted_at = timestamp;
410    }
411}