diff --git a/src/database.rs b/src/database.rs index dfcae30..62c7594 100644 --- a/src/database.rs +++ b/src/database.rs @@ -13,6 +13,7 @@ use serde_json; use crate::language::Language; use crate::entry::{WiktionaryEntries, WiktionaryEntry}; use crate::entry::Form; +use crate::{MAJOR, MINOR, PATCH}; const DB_DIR: &str = "/usr/share/inflectived/"; const CACHE_DIR: &str = "/var/cache/"; @@ -38,7 +39,15 @@ impl WordDb { let mut conn = self.connect(); let transaction = conn.transaction().unwrap(); - if let Err(e) = transaction.execute(&format!("DROP TABLE IF EXISTS {0}_words", &lang.code), []) { + if let Err(e) = transaction.execute(" + CREATE TABLE IF NOT EXISTS langs ( + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + code TINYTEXT UNIQUE NOT NULL, + name TINYTEXT NOT NULL, + major INTEGER NOT NULL, + minor INTEGER NOT NULL, + patch INTEGER NOT NULL + )", []) { match e { SqliteFailure(f, _) => match f.code { ErrorCode::ReadOnly => { @@ -52,12 +61,15 @@ impl WordDb { } } + transaction.execute("DELETE FROM langs WHERE code = ?", [&lang.code]).unwrap(); + + transaction.execute(&format!("DROP TABLE IF EXISTS {0}_words", &lang.code), []).unwrap(); transaction.execute(&format!("DROP TABLE IF EXISTS {0}_types", &lang.code), []).unwrap(); transaction.execute(&format!(" CREATE TABLE {0}_types ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - name TINYTEXT UNIQUE NOT NULL + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + name TINYTEXT UNIQUE NOT NULL )", &lang.code), []).unwrap(); for type_ in &lang.types { @@ -70,12 +82,12 @@ impl WordDb { transaction.execute(&format!(" CREATE TABLE {0}_words ( - id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, - word TINYTEXT NOT NULL, - type_id INTEGER NOT NULL, - content MEDIUMTEXT NOT NULL, - FOREIGN KEY (type_id) - REFERENCES {0}_types (id) + id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, + word TINYTEXT NOT NULL, + type_id INTEGER NOT NULL, + content MEDIUMTEXT NOT NULL, + FOREIGN KEY (type_id) + REFERENCES {0}_types (id) )", &lang.code), []).unwrap(); transaction.execute(&format!(" @@ -83,6 +95,11 @@ impl WordDb { ON {0}_words (word) ", &lang.code), []).unwrap(); + transaction.execute(" + INSERT INTO langs (code, name, major, minor, patch) + VALUES (?, ?, ?, ?, ?) + ", params![&lang.code, &lang.name, MAJOR, MINOR, PATCH]).unwrap(); + transaction.commit().unwrap(); } diff --git a/src/language.rs b/src/language.rs index 00df930..ef4fedf 100644 --- a/src/language.rs +++ b/src/language.rs @@ -1,13 +1,15 @@ #[derive(Debug)] pub struct Language { pub code: String, + pub name: String, pub types: Vec } impl Language { - pub fn new(code: &str, types: Vec) -> Self { + pub fn new(code: &str, name: &str, types: Vec) -> Self { Self { code: String::from(code), + name: String::from(name), types } } diff --git a/src/main.rs b/src/main.rs index f28ec31..4c2eb23 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,11 +8,16 @@ use clap::{App, AppSettings, Arg, SubCommand}; mod database; mod language; mod entry; -mod routes; +mod views; use database::WordDb; use language::Language; + +const MAJOR: i32 = 0; +const MINOR: i32 = 1; +const PATCH: i32 = 0; + #[rocket::main] async fn main() { let matches = App::new("inflectived") @@ -51,7 +56,8 @@ async fn main() { let mut db = WordDb::new("inflectived.db"); - let lang = Language::new("polish", + let lang = Language::new("pl", + "Polish", vec![String::from("adj"), String::from("noun"), String::from("verb"), @@ -84,9 +90,10 @@ async fn main() { rocket::custom(figment) .manage(db) .mount("/static", FileServer::from("static/")) - .mount("/", routes![routes::get_entries, - routes::get_entries_like, - routes::frontend]) + .mount("/", routes![views::get_entries, + views::get_entries_like, + views::get_langs, + views::frontend]) .launch() .await.unwrap(); }, diff --git a/src/routes.rs b/src/views.rs similarity index 79% rename from src/routes.rs rename to src/views.rs index ddd5177..69024d0 100644 --- a/src/routes.rs +++ b/src/views.rs @@ -9,7 +9,7 @@ use rusqlite::params; use crate::database::WordDb; -#[get("/frontend")] +#[get("/")] pub fn frontend() -> Option> { match fs::read_to_string("static/index.html") { Ok(file) => Some(content::Html(file)), @@ -70,3 +70,22 @@ pub fn get_entries_like(db: &State, lang: &str, like: &str, limit: usize Json(words) } + +#[get("/langs?")] +pub fn get_langs(db: &State, installed: bool) -> Json> { + let conn = db.connect(); + + let mut langs: Vec = Vec::new(); + + if installed { + let mut statement = conn.prepare("SELECT name FROM langs").unwrap(); + + let mut rows = statement.query([]).unwrap(); + + while let Some(row) = rows.next().unwrap() { + langs.push(row.get(0).unwrap()); + } + } + + Json(langs) +}