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 println!("📡 Database connection example");
10 println!("========================");
11 demonstrate_database_connection().await?;
12 println!();
13
14 println!("🔑 Simplified UUID generation");
16 println!("========================");
17 demonstrate_simplified_uuid()?;
18 println!();
19
20 println!("⚠️ Simplified error handling");
22 println!("========================");
23 demonstrate_simplified_error()?;
24 println!();
25
26 println!("💾 Simplified LRU cache");
28 println!("========================");
29 demonstrate_simplified_cache()?;
30 println!();
31
32 println!("🏊 Simple connection pool");
34 println!("========================");
35 demonstrate_connection_pool().await?;
36 println!();
37
38 println!("🔨 Query builder example");
40 println!("========================");
41 demonstrate_query_builder();
42 println!();
43
44 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 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 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 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 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 println!();
178 println!(" Adding key4 (should evict oldest):");
179 cache.put("key4", "value4");
180 println!(" key1: {:?}", cache.get(&"key1")); println!(" key4: {:?}", cache.get(&"key4")); println!();
185 println!(" Current capacity: {}", cache.capacity());
186 println!(" Current size: {}", cache.len());
187
188 cache.resize(2);
190 println!(" After resize to 2:");
191 println!(" New size: {}", cache.len());
192
193 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 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 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 db.auto_migrate::<Product>().await?;
244 println!(" ✅ Created products table from model schema");
245
246 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 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 let affected = db.update(&mut products[0], &[("price", 6)]).await?;
266 println!(" ✅ Updated {} row(s)", affected);
267
268 let count = db.all::<Product>().await?.len();
270 println!(" ✅ Count = {}", count);
271
272 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 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 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 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 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#[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#[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}