mirror of
https://git.ethanthesleepy.one/ethanaobrien/ew
synced 2026-01-12 00:02:38 +08:00
Don't lock database operations to a single thread
This commit is contained in:
@@ -25,8 +25,8 @@ pub struct Live {
|
|||||||
pub master_pass: i64,
|
pub master_pass: i64,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_tables(conn: &SQLite) {
|
fn setup_tables(conn: &rusqlite::Connection) {
|
||||||
conn.lock_and_exec("CREATE TABLE IF NOT EXISTS lives (
|
conn.execute_batch("CREATE TABLE IF NOT EXISTS lives (
|
||||||
live_id INT NOT NULL PRIMARY KEY,
|
live_id INT NOT NULL PRIMARY KEY,
|
||||||
normal_failed BIGINT NOT NULL,
|
normal_failed BIGINT NOT NULL,
|
||||||
normal_pass BIGINT NOT NULL,
|
normal_pass BIGINT NOT NULL,
|
||||||
@@ -36,11 +36,11 @@ fn setup_tables(conn: &SQLite) {
|
|||||||
expert_pass BIGINT NOT NULL,
|
expert_pass BIGINT NOT NULL,
|
||||||
master_failed BIGINT NOT NULL,
|
master_failed BIGINT NOT NULL,
|
||||||
master_pass BIGINT NOT NULL
|
master_pass BIGINT NOT NULL
|
||||||
)", params!());
|
);
|
||||||
conn.lock_and_exec("CREATE TABLE IF NOT EXISTS scores (
|
CREATE TABLE IF NOT EXISTS scores (
|
||||||
live_id INT NOT NULL PRIMARY KEY,
|
live_id INT NOT NULL PRIMARY KEY,
|
||||||
score_data TEXT NOT NULL
|
score_data TEXT NOT NULL
|
||||||
)", params!());
|
);").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_live_score(id: i64, uid: i64, score: i64) {
|
fn update_live_score(id: i64, uid: i64, score: i64) {
|
||||||
|
|||||||
@@ -11,11 +11,11 @@ lazy_static! {
|
|||||||
static ref CACHED_DATA: Mutex<Option<JsonValue>> = Mutex::new(None);
|
static ref CACHED_DATA: Mutex<Option<JsonValue>> = Mutex::new(None);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_tables(conn: &SQLite) {
|
fn setup_tables(conn: &rusqlite::Connection) {
|
||||||
conn.lock_and_exec("CREATE TABLE IF NOT EXISTS scores (
|
conn.execute_batch("CREATE TABLE IF NOT EXISTS scores (
|
||||||
event_id INT NOT NULL PRIMARY KEY,
|
event_id INT NOT NULL PRIMARY KEY,
|
||||||
score_data TEXT NOT NULL
|
score_data TEXT NOT NULL
|
||||||
)", params!());
|
);").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn live_completed(event_id: u32, uid: i64, score: i64, star_level: i64) {
|
pub fn live_completed(event_id: u32, uid: i64, score: i64, star_level: i64) {
|
||||||
|
|||||||
@@ -22,12 +22,12 @@ lazy_static! {
|
|||||||
static ref DATABASE: SQLite = SQLite::new("gree.db", setup_tables);
|
static ref DATABASE: SQLite = SQLite::new("gree.db", setup_tables);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_tables(conn: &SQLite) {
|
fn setup_tables(conn: &rusqlite::Connection) {
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS users (
|
conn.execute_batch("CREATE TABLE IF NOT EXISTS users (
|
||||||
cert TEXT NOT NULL,
|
cert TEXT NOT NULL,
|
||||||
uuid TEXT NOT NULL,
|
uuid TEXT NOT NULL,
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY
|
user_id BIGINT NOT NULL PRIMARY KEY
|
||||||
)");
|
);").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_cert(uid: i64, cert: &str) {
|
fn update_cert(uid: i64, cert: &str) {
|
||||||
|
|||||||
@@ -17,62 +17,63 @@ lazy_static! {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn setup_tables(conn: &SQLite) {
|
fn setup_tables(conn: &rusqlite::Connection) {
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS tokens (
|
conn.execute_batch("
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
CREATE TABLE IF NOT EXISTS tokens (
|
||||||
token TEXT NOT NULL
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
)");
|
token TEXT NOT NULL
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS migration (
|
);
|
||||||
token TEXT NOT NULL PRIMARY KEY,
|
CREATE TABLE IF NOT EXISTS migration (
|
||||||
password TEXT NOT NULL
|
token TEXT NOT NULL PRIMARY KEY,
|
||||||
)");
|
password TEXT NOT NULL
|
||||||
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS userdata (
|
CREATE TABLE IF NOT EXISTS userdata (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
userdata TEXT NOT NULL,
|
userdata TEXT NOT NULL,
|
||||||
friend_request_disabled INT NOT NULL
|
friend_request_disabled INT NOT NULL
|
||||||
)");
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS userhome (
|
CREATE TABLE IF NOT EXISTS userhome (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
userhome TEXT NOT NULL
|
userhome TEXT NOT NULL
|
||||||
)");
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS missions (
|
CREATE TABLE IF NOT EXISTS missions (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
missions TEXT NOT NULL
|
missions TEXT NOT NULL
|
||||||
)");
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS loginbonus (
|
CREATE TABLE IF NOT EXISTS loginbonus (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
loginbonus TEXT NOT NULL
|
loginbonus TEXT NOT NULL
|
||||||
)");
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS sifcards (
|
CREATE TABLE IF NOT EXISTS sifcards (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
sifcards TEXT NOT NULL
|
sifcards TEXT NOT NULL
|
||||||
)");
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS friends (
|
CREATE TABLE IF NOT EXISTS friends (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
friends TEXT NOT NULL
|
friends TEXT NOT NULL
|
||||||
)");
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS chats (
|
CREATE TABLE IF NOT EXISTS chats (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
chats TEXT NOT NULL
|
chats TEXT NOT NULL
|
||||||
)");
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS event (
|
CREATE TABLE IF NOT EXISTS event (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
event TEXT NOT NULL
|
event TEXT NOT NULL
|
||||||
)");
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS eventloginbonus (
|
CREATE TABLE IF NOT EXISTS eventloginbonus (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
eventloginbonus TEXT NOT NULL
|
eventloginbonus TEXT NOT NULL
|
||||||
)");
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS server_data (
|
CREATE TABLE IF NOT EXISTS server_data (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
server_data TEXT NOT NULL
|
server_data TEXT NOT NULL
|
||||||
)");
|
);
|
||||||
conn.create_store_v2("CREATE TABLE IF NOT EXISTS webui (
|
CREATE TABLE IF NOT EXISTS webui (
|
||||||
user_id BIGINT NOT NULL PRIMARY KEY,
|
user_id BIGINT NOT NULL PRIMARY KEY,
|
||||||
token TEXT NOT NULL,
|
token TEXT NOT NULL,
|
||||||
last_login BIGINT NOT NULL
|
last_login BIGINT NOT NULL
|
||||||
)");
|
);
|
||||||
|
").unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn acc_exists(uid: i64) -> bool {
|
fn acc_exists(uid: i64) -> bool {
|
||||||
|
|||||||
43
src/sql.rs
43
src/sql.rs
@@ -1,45 +1,29 @@
|
|||||||
use rusqlite::{Connection, params, ToSql};
|
use rusqlite::{Connection, params, ToSql};
|
||||||
use std::sync::Mutex;
|
|
||||||
use json::{JsonValue, array};
|
use json::{JsonValue, array};
|
||||||
|
|
||||||
use crate::router::clear_rate::Live;
|
use crate::router::clear_rate::Live;
|
||||||
|
|
||||||
macro_rules! lock_onto_mutex {
|
|
||||||
($mutex:expr) => {{
|
|
||||||
loop {
|
|
||||||
match $mutex.lock() {
|
|
||||||
Ok(value) => {
|
|
||||||
break value;
|
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
$mutex.clear_poison();
|
|
||||||
std::thread::sleep(std::time::Duration::from_millis(10));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}};
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct SQLite {
|
pub struct SQLite {
|
||||||
engine: Mutex<Connection>
|
path: String
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SQLite {
|
impl SQLite {
|
||||||
pub fn new(path: &str, setup: fn(&SQLite)) -> SQLite {
|
pub fn new(path: &str, setup: fn(&Connection)) -> SQLite {
|
||||||
let conn = Connection::open(crate::get_data_path(path)).unwrap();
|
|
||||||
conn.execute("PRAGMA foreign_keys = ON;", ()).unwrap();
|
|
||||||
let instance = SQLite {
|
let instance = SQLite {
|
||||||
engine: Mutex::new(conn)
|
path: crate::get_data_path(path)
|
||||||
};
|
};
|
||||||
setup(&instance);
|
let conn = Connection::open(&instance.path).unwrap();
|
||||||
|
conn.busy_timeout(std::time::Duration::from_secs(10)).unwrap();
|
||||||
|
conn.execute("PRAGMA foreign_keys = ON;", ()).unwrap();
|
||||||
|
setup(&conn);
|
||||||
instance
|
instance
|
||||||
}
|
}
|
||||||
pub fn lock_and_exec(&self, command: &str, args: &[&dyn ToSql]) {
|
pub fn lock_and_exec(&self, command: &str, args: &[&dyn ToSql]) {
|
||||||
let conn = lock_onto_mutex!(self.engine);
|
let conn = Connection::open(&self.path).unwrap();
|
||||||
conn.execute(command, args).unwrap();
|
conn.execute(command, args).unwrap();
|
||||||
}
|
}
|
||||||
pub fn lock_and_select(&self, command: &str, args: &[&dyn ToSql]) -> Result<String, rusqlite::Error> {
|
pub fn lock_and_select(&self, command: &str, args: &[&dyn ToSql]) -> Result<String, rusqlite::Error> {
|
||||||
let conn = lock_onto_mutex!(self.engine);
|
let conn = Connection::open(&self.path).unwrap();
|
||||||
let mut stmt = conn.prepare(command)?;
|
let mut stmt = conn.prepare(command)?;
|
||||||
stmt.query_row(args, |row| {
|
stmt.query_row(args, |row| {
|
||||||
match row.get::<usize, i64>(0) {
|
match row.get::<usize, i64>(0) {
|
||||||
@@ -49,7 +33,7 @@ impl SQLite {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn lock_and_select_all(&self, command: &str, args: &[&dyn ToSql]) -> Result<JsonValue, rusqlite::Error> {
|
pub fn lock_and_select_all(&self, command: &str, args: &[&dyn ToSql]) -> Result<JsonValue, rusqlite::Error> {
|
||||||
let conn = lock_onto_mutex!(self.engine);
|
let conn = Connection::open(&self.path).unwrap();
|
||||||
let mut stmt = conn.prepare(command)?;
|
let mut stmt = conn.prepare(command)?;
|
||||||
let map = stmt.query_map(args, |row| {
|
let map = stmt.query_map(args, |row| {
|
||||||
match row.get::<usize, i64>(0) {
|
match row.get::<usize, i64>(0) {
|
||||||
@@ -62,13 +46,13 @@ impl SQLite {
|
|||||||
let res = val?;
|
let res = val?;
|
||||||
match res.clone().parse::<i64>() {
|
match res.clone().parse::<i64>() {
|
||||||
Ok(v) => rv.push(v).unwrap(),
|
Ok(v) => rv.push(v).unwrap(),
|
||||||
Err(_) => rv.push(res).unwrap()
|
Err(_) => rv.push(res).unwrap()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Ok(rv)
|
Ok(rv)
|
||||||
}
|
}
|
||||||
pub fn get_live_data(&self, id: i64) -> Result<Live, rusqlite::Error> {
|
pub fn get_live_data(&self, id: i64) -> Result<Live, rusqlite::Error> {
|
||||||
let conn = lock_onto_mutex!(self.engine);
|
let conn = Connection::open(&self.path).unwrap();
|
||||||
let mut stmt = conn.prepare("SELECT * FROM lives WHERE live_id=?1")?;
|
let mut stmt = conn.prepare("SELECT * FROM lives WHERE live_id=?1")?;
|
||||||
stmt.query_row(params!(id), |row| {
|
stmt.query_row(params!(id), |row| {
|
||||||
Ok(Live {
|
Ok(Live {
|
||||||
@@ -84,7 +68,4 @@ impl SQLite {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn create_store_v2(&self, table: &str) {
|
|
||||||
self.lock_and_exec(table, params!());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user