sfrs/src/tokens.rs
Peter Cai 2eaf7d24e0
enable busy_timeout for SQLite
although we have a global RwLock for database access, it still can fail
due to disk sync delays. Though unlikely, it has happened once or twice
during testing. Let's just enable busy_timeout to avoid this issue.
Since we have RwLock anyway, a busy_timeout should not be much of a
problem.

Unfortunately this has to be enabled via implementing our own wrapper
trait.
2020-02-23 12:51:26 +08:00

51 lines
1.6 KiB
Rust

use crate::schema::tokens;
use crate::schema::tokens::dsl::*;
use crate::{SqliteLike, lock_db_write, lock_db_read};
use chrono::NaiveDateTime;
use diesel::prelude::*;
use std::sync::{RwLockReadGuard, RwLockWriteGuard};
use uuid::Uuid;
#[derive(Queryable, Insertable)]
#[table_name = "tokens"]
pub struct Token {
id: String,
uid: i32,
timestamp: Option<NaiveDateTime>
}
impl Token {
// Return user id if any
pub fn find_token_by_id(db: &impl SqliteLike, tid: &str) -> Option<i32> {
(lock_db_read!() as Result<RwLockReadGuard<()>, String>).ok()
.and_then(|_| {
tokens.filter(id.eq(tid))
.load::<Token>(db)
.ok()
.and_then(|mut v| {
if !v.is_empty() {
Some(v.remove(0).uid)
} else {
None
}
})
})
}
// Create a new token for a user
pub fn create_token(db: &impl SqliteLike, user: i32) -> Option<String> {
let tid = Uuid::new_v4().to_hyphenated().to_string();
(lock_db_write!() as Result<RwLockWriteGuard<()>, String>).ok()
.and_then(|_| {
diesel::insert_into(tokens::table)
.values(Token {
id: tid.clone(),
uid: user,
timestamp: None // There's default value from SQLite
})
.execute(db)
.ok()
.map(|_| tid)
})
}
}