You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
2.2 KiB
80 lines
2.2 KiB
use crate::word::Word;
|
|
|
|
use derive_more::From;
|
|
use rusqlite::{params, Connection, Result};
|
|
use std::path::PathBuf;
|
|
|
|
pub struct Database {
|
|
conn: Connection,
|
|
pub last_word_id: i64,
|
|
}
|
|
|
|
#[derive(From, Debug)]
|
|
pub enum DatabaseCreationError {
|
|
RusqliteError(rusqlite::Error),
|
|
IoError(std::io::Error),
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub enum DatabaseType {
|
|
#[default]
|
|
InMemory,
|
|
OnDisk(String),
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct DatabaseSettings {
|
|
pub db_type: DatabaseType,
|
|
}
|
|
|
|
impl Database {
|
|
pub fn new(settings: DatabaseSettings) -> Result<Self, DatabaseCreationError> {
|
|
let conn = match settings.db_type {
|
|
DatabaseType::InMemory => Connection::open_in_memory(),
|
|
DatabaseType::OnDisk(path) => Connection::open(PathBuf::from(path)),
|
|
}?;
|
|
conn.execute(
|
|
"CREATE TABLE IF NOT EXISTS word (
|
|
id INTEGER PRIMARY KEY,
|
|
word TEXT,
|
|
reading TEXT,
|
|
timestamp DATETIME DEFAULT CURRENT_TIMESTAMP
|
|
)",
|
|
params![],
|
|
)?;
|
|
let last_word_id = match conn
|
|
.prepare("SELECT id FROM word ORDER BY id DESC LIMIT 1")?
|
|
.query_map(params![], |row| row.get(0))?
|
|
.collect::<Result<Vec<i64>>>()?
|
|
.first()
|
|
{
|
|
Some(id) => *id,
|
|
None => 0, // first database entry is id 1
|
|
};
|
|
Ok(Self { conn, last_word_id })
|
|
}
|
|
|
|
pub fn load_words_before(&self, before_id: i64) -> Result<Vec<Word>> {
|
|
self.conn
|
|
.prepare("SELECT id, word, reading, timestamp FROM word WHERE id < ? ORDER BY id DESC LIMIT 10")?
|
|
.query_map(params![before_id], |row| {
|
|
Ok(Word {
|
|
id: row.get(0)?,
|
|
word: row.get(1)?,
|
|
reading: row.get(2)?,
|
|
timestamp: row.get(3)?,
|
|
})
|
|
})?
|
|
.collect::<Result<Vec<Word>>>()
|
|
}
|
|
|
|
pub fn add_word(&mut self, word: &Word) -> Result<()> {
|
|
self.conn.execute(
|
|
"INSERT INTO word (word, reading) VALUES (?1, ?2)",
|
|
params![word.word, word.reading,],
|
|
)?;
|
|
self.last_word_id += 1;
|
|
Ok(())
|
|
}
|
|
}
|