diff --git a/Cargo.lock b/Cargo.lock index 91b0306..d6086e7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -583,10 +583,11 @@ dependencies = [ "clap", "config", "futures", - "json", "reqwest", "rocket", "rusqlite", + "serde 1.0.132", + "serde_json", "tokio", ] @@ -632,12 +633,6 @@ dependencies = [ "wasm-bindgen", ] -[[package]] -name = "json" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "078e285eafdfb6c4b434e0d31e8cfcb5115b651496faca5749b88fafd4f23bfd" - [[package]] name = "lazy_static" version = "1.4.0" diff --git a/Cargo.toml b/Cargo.toml index cee35db..ae49bb3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,7 @@ rocket = { version = "0.5.0-rc.1", features = ["json"] } reqwest = "0.11" rusqlite = "0.25.3" futures = "0.3" -json = "0.12" config = "0.11" tokio = { version = "1", features = ["full"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" diff --git a/src/database.rs b/src/database.rs index 7394dce..4c705e9 100644 --- a/src/database.rs +++ b/src/database.rs @@ -1,11 +1,15 @@ use std::fs; use reqwest; -use rusqlite::Connection; +use rusqlite::{Connection, Transaction}; use rusqlite::params; +use serde_json::Value; +use serde_json::json; +use serde_json; use crate::language::Language; -use crate::entry::WiktionaryEntries; +use crate::entry::{WiktionaryEntries, WiktionaryEntry}; +use crate::entry::Form; /// A database of Wiktionary entries pub struct WordDb { @@ -24,64 +28,147 @@ impl WordDb { } pub fn clean_tables(&mut self, lang: &Language) { - let mut connection = self.connect(); - let transaction = connection.transaction().unwrap(); + let mut conn = self.connect(); + let transaction = conn.transaction().unwrap(); - transaction.execute(&format!("DROP TABLE IF EXISTS {}_words", &lang.code), []).unwrap(); - transaction.execute(&format!("DROP TABLE IF EXISTS {}_types", &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 {}_types ( + CREATE TABLE {0}_types ( id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, name TINYTEXT UNIQUE NOT NULL )", &lang.code), []).unwrap(); for type_ in &lang.types { transaction.execute(&format!(" - INSERT INTO {}_types ( name ) + INSERT INTO {0}_types ( name ) VALUES ( ? )", &lang.code), [type_]).unwrap(); } transaction.execute(&format!(" - CREATE TABLE {}_words ( + 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 {}_types (id) - )", &lang.code, &lang.code), []).unwrap(); + REFERENCES {0}_types (id) + )", &lang.code), []).unwrap(); transaction.execute(&format!(" CREATE INDEX word_index - ON {}_words (word) + ON {0}_words (word) ", &lang.code), []).unwrap(); transaction.commit().unwrap(); } - pub fn insert_entries(&mut self, lang: &Language, entries: WiktionaryEntries) { - let mut connection = self.connect(); - let transaction = connection.transaction().unwrap(); + pub fn insert_entry(&self, transaction: &Transaction, lang: &Language, entry: &WiktionaryEntry) { + transaction.execute(&format!(" + INSERT INTO {0}_words ( word, content, type_id ) + VALUES ( + ?, ?, + (SELECT id FROM {0}_types WHERE name = ?) + )", &lang.code), + params![entry.word, + entry.parsed_json.to_string(), + entry.type_] + ).unwrap(); + } - for entry in entries { - transaction.execute(&format!(" - INSERT INTO {}_words ( word, content, type_id ) - VALUES ( - ?, ?, - (SELECT id FROM {}_types WHERE name = ?) - )", &lang.code, &lang.code), - params![entry.word, - entry.parsed_json.to_string(), - entry.type_] - ).unwrap(); + pub fn insert_entries(&mut self, lang: &Language, entries: &WiktionaryEntries) { + let mut conn = self.connect(); + let transaction = conn.transaction().unwrap(); + + for entry in entries.iter() { + self.insert_entry(&transaction, lang, entry); } transaction.commit().unwrap(); } + /// Generate missing "form-of" entries + pub fn generate_entries(&mut self, lang: &Language, entries: &WiktionaryEntries) { + let mut conn = self.connect(); + let transaction = conn.transaction().unwrap(); + + let mut statement = transaction.prepare(&format!( + "SELECT {0}_words.content + FROM {0}_words + JOIN {0}_types + ON {0}_types.id = {0}_words.type_id + WHERE {0}_words.word = ? + AND {0}_types.name = ?", &lang.code) + ).unwrap(); + + for entry in entries.iter() { + if let Some(forms) = entry.parsed_json["forms"].as_array() { + let mut forms_vec: Vec