database.rs (3077B)
1 use rusqlite::{Connection, Result}; 2 use std::fmt; 3 use std::time::{SystemTime, UNIX_EPOCH}; 4 5 #[derive(Debug)] 6 struct User { 7 username: String, 8 passhash: String, 9 } 10 11 #[derive(Debug)] 12 struct Qump { 13 id: u64, 14 contents: String, // use BLOB eventually? 15 } 16 17 impl Qump { 18 fn new(contents: &str) -> Qump { 19 return Qump { 20 id: 0, 21 contents: contents.to_string(), 22 }; 23 } 24 } 25 26 #[derive(Debug)] 27 enum QumpAction { 28 Add, 29 Edit, 30 Remove, 31 } 32 33 impl fmt::Display for QumpAction { 34 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 35 use QumpAction::*; 36 let s = match self { 37 Add => "add", 38 Edit => "edit", 39 Remove => "rm", 40 }; 41 write!(f, "{}", s)?; 42 Ok(()) 43 } 44 } 45 46 #[derive(Debug)] 47 struct Log { 48 qump_id: u64, 49 user: String, 50 timestamp: u64, // use BLOB eventually? 51 action: String, 52 } 53 54 #[derive(Debug)] 55 struct AccessKey { 56 key: String, 57 user: String, 58 expiration: u64, 59 } 60 61 struct DatabaseManager { 62 conn: Connection, 63 } 64 65 impl DatabaseManager { 66 fn init(path: &str) -> Result<DatabaseManager, rusqlite::Error> { 67 let conn = Connection::open(path)?; 68 conn.execute( 69 "create table if not exists qumps ( 70 id integer primary key, 71 contents text not null 72 )", 73 [], 74 )?; 75 conn.execute( 76 "create table if not exists users ( 77 id integer primary key, 78 username text not null, 79 password text not null 80 )", 81 [], 82 )?; 83 conn.execute( 84 "create table if not exists log ( 85 id integer primary key, 86 qump_id integer references qumps(id), 87 timestamp integer not null, 88 actions text not null 89 )", 90 // TODO: Index 'timestamp' and add 'user' var 91 [], 92 )?; 93 Ok(DatabaseManager { conn: conn }) 94 } 95 fn insert_qumps(&self, qumps: &[Qump]) -> Result<usize, rusqlite::Error> { 96 for q in qumps { 97 let ts = { 98 let now = SystemTime::now(); 99 now.duration_since(UNIX_EPOCH) 100 .expect("Error getting timestamp") 101 .as_millis() 102 }; 103 self.conn.execute( 104 "INSERT INTO qumps (contents) values (?1)", 105 &[&q.contents.to_string()], 106 )?; 107 let last_id: String = self.conn.last_insert_rowid().to_string(); 108 self.conn.execute( 109 "INSERT INTO log (qump_id, timestamp, actions) values (?1, ?2, ?3)", 110 &[&last_id, &ts.to_string(), &QumpAction::Add.to_string()], 111 )?; 112 } 113 Ok(qumps.len()) 114 } 115 fn remove_qumps(&self, qump_ids: &[u64]) {} 116 } 117 118 fn main() -> Result<()> { 119 let dbm = DatabaseManager::init("qumps.db").unwrap(); 120 let qumps: [Qump; 2] = [Qump::new("New qump"), Qump::new("New qump again!")]; 121 dbm.insert_qumps(&qumps)?; 122 Ok(()) 123 }