1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
#![allow(dead_code, unused, clippy::type_complexity)]
//! Example Rust seed script for Prax
//!
//! This file demonstrates how to create a Rust seed script.
//! To use this in your project:
//!
//! 1. Copy this file to your project root or `prax/` directory
//! 2. Add a [[bin]] entry to your Cargo.toml:
//! ```toml
//! [[bin]]
//! name = "seed"
//! path = "seed.rs" # or "prax/seed.rs"
//! ```
//! 3. Run: `prax db seed`
//!
//! Or run directly: `cargo run --bin seed`
use std::env;
// In a real project, you would import from your generated client:
// use crate::generated::*;
// For this example, we'll use prax-query directly
fn main() {
// Initialize logging
prax_query::logging::init();
// Get database URL from environment
let database_url = env::var("DATABASE_URL").unwrap_or_else(|_| {
eprintln!("Error: DATABASE_URL environment variable not set");
eprintln!("Set it with: export DATABASE_URL=postgres://user:pass@localhost/db");
std::process::exit(1);
});
// Get environment
let environment = env::var("PRAX_ENV").unwrap_or_else(|_| "development".to_string());
println!("🌱 Prax Database Seeder");
println!(" Environment: {}", environment);
println!(" Database: {}", mask_url(&database_url));
println!();
// In a real seed script, you would use the generated Prax client:
//
// ```rust
// use tokio;
// use your_app::generated::*;
//
// #[tokio::main]
// async fn main() -> Result<(), Box<dyn std::error::Error>> {
// let client = PraxClient::new(&database_url).await?;
//
// // Create admin user
// let admin = client.user().create(
// user::email::set("admin@example.com".to_string()),
// user::name::set("Admin User".to_string()),
// vec![user::role::set(Role::Admin)],
// ).exec().await?;
// println!("Created admin user: {:?}", admin);
//
// // Create sample posts
// for i in 1..=5 {
// client.post().create(
// post::title::set(format!("Sample Post {}", i)),
// post::author::connect(user::id::equals(admin.id)),
// vec![
// post::content::set(format!("Content for post {}", i)),
// post::published::set(i % 2 == 0),
// ],
// ).exec().await?;
// }
// println!("Created 5 sample posts");
//
// Ok(())
// }
// ```
// For this example, we just demonstrate the structure
println!("📦 Seeding users...");
seed_users();
println!("📝 Seeding posts...");
seed_posts();
println!("💬 Seeding comments...");
seed_comments();
println!();
println!("✅ Database seeded successfully!");
println!(" Created 5 users");
println!(" Created 5 posts");
println!(" Created 4 comments");
}
fn seed_users() {
let users = vec![
("admin@example.com", "Admin User", "ADMIN"),
("john@example.com", "John Doe", "USER"),
("jane@example.com", "Jane Smith", "USER"),
("bob@example.com", "Bob Wilson", "USER"),
("alice@example.com", "Alice Brown", "MODERATOR"),
];
for (email, name, role) in users {
println!(" + {} ({}) - {}", name, email, role);
}
}
fn seed_posts() {
let posts = vec![
("Welcome to Prax", true),
("Getting Started Guide", true),
("My First Post", true),
("Draft Post", false),
("Tips and Tricks", true),
];
for (title, published) in posts {
let status = if published { "published" } else { "draft" };
println!(" + {} [{}]", title, status);
}
}
fn seed_comments() {
let comments = vec![
("Great post!", "post #1"),
("Thanks for sharing!", "post #1"),
("Very helpful guide.", "post #2"),
("Welcome John!", "post #3"),
];
for (content, post) in comments {
println!(" + \"{}\" on {}", content, post);
}
}
fn mask_url(url: &str) -> String {
// Simple URL masking - hide password portion
if let Some(at_pos) = url.find('@')
&& let Some(scheme_end) = url.find("://")
{
let scheme = &url[..scheme_end + 3];
let after_at = &url[at_pos..];
// Check if there's a password (contains :)
let user_info = &url[scheme_end + 3..at_pos];
if user_info.contains(':')
&& let Some(colon_pos) = user_info.find(':')
{
let user = &user_info[..colon_pos];
return format!("{}{}:****{}", scheme, user, after_at);
}
}
// No password found, return truncated URL
if url.len() > 50 {
format!("{}...", &url[..50])
} else {
url.to_string()
}
}