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
|
use rusqlite::Connection;
pub fn init_db() -> Connection {
let db_path = std::env::var("SERVER_DB").unwrap_or_else(|_| "server.db".to_string());
let conn = Connection::open(&db_path).unwrap();
conn.execute(
"CREATE TABLE IF NOT EXISTS users (
username TEXT PRIMARY KEY,
hashed_password TEXT NOT NULL,
account_id INTEGER UNIQUE,
balance INTEGER DEFAULT 1000
)",
[],
).unwrap();
// Add column if not exists (for migration)
let _ = conn.execute("ALTER TABLE users ADD COLUMN account_id INTEGER UNIQUE", []);
let _ = conn.execute("ALTER TABLE users ADD COLUMN balance INTEGER DEFAULT 1000", []);
conn
}
pub fn add_user(conn: &Connection, username: &str, hashed_password: &str) -> Result<(), Box<dyn std::error::Error>> {
loop {
let account_id: u32 = rand::random::<u32>();
match conn.execute(
"INSERT INTO users (username, hashed_password, account_id, balance) VALUES (?1, ?2, ?3, ?4)",
[username, hashed_password, &account_id.to_string(), "1000"],
) {
Ok(_) => break,
Err(_) => continue, // Retry if account_id conflict
}
}
Ok(())
}
pub fn get_hashed_password(conn: &Connection, username: &str) -> Option<String> {
let mut stmt = conn.prepare("SELECT hashed_password FROM users WHERE username = ?1").unwrap();
let mut rows = stmt.query([username]).unwrap();
if let Ok(Some(row)) = rows.next() {
row.get(0).ok()
} else {
None
}
}
pub fn get_account_id(conn: &Connection, username: &str) -> Option<u32> {
let mut stmt = conn.prepare("SELECT account_id FROM users WHERE username = ?1").unwrap();
let mut rows = stmt.query([username]).unwrap();
if let Ok(Some(row)) = rows.next() {
Some(row.get::<_, u32>(0).ok()?)
} else {
None
}
}
pub fn get_balance(conn: &Connection, username: &str) -> Option<i64> {
let mut stmt = conn.prepare("SELECT balance FROM users WHERE username = ?1").unwrap();
let mut rows = stmt.query([username]).unwrap();
if let Ok(Some(row)) = rows.next() {
Some(row.get::<_, i64>(0).ok()?)
} else {
None
}
}
|