is init yet from Rust

This commit is contained in:
polv committed 2026-02-24 19:25:37 +07:00
1 parent 9b5ae1cd8b
commit dcfe074535
9 files changed
+38 -91

No files matched your search

-1
View File
@@ -1 +0,0 @@
+9 -49
View File
@@ -10,8 +10,6 @@ use std::{
use anyhow::Result; use anyhow::Result;
use rusqlite::Connection; use rusqlite::Connection;
use crate::models::Entry;
mod yomitan; mod yomitan;
pub use yomitan::YomitanRow; pub use yomitan::YomitanRow;
@@ -25,10 +23,13 @@ pub(crate) struct Database {
yomitan_attached: Arc<AtomicBool>, yomitan_attached: Arc<AtomicBool>,
} }
const USER_DBFILE: &str = "user.db";
pub(crate) const YOMITAN_DBFILE: &str = "yomitan.db";
impl Database { impl Database {
pub fn new(db_dir: impl AsRef<Path>) -> Result<Self> { pub fn new(db_dir: impl AsRef<Path>) -> Result<Self> {
let dir = db_dir.as_ref().to_path_buf(); let dir = db_dir.as_ref().to_path_buf();
let conn = Connection::open(dir.join("user.db"))?; let conn = Connection::open(dir.join(USER_DBFILE))?;
conn.execute_batch( conn.execute_batch(
r" r"
@@ -45,6 +46,10 @@ impl Database {
}) })
} }
pub fn is_yomitan_dbfile_exists(&self) -> bool {
self.dir.join(YOMITAN_DBFILE).exists()
}
pub fn yomitan(&self) -> Result<yomitan::YomitanDatabase> { pub fn yomitan(&self) -> Result<yomitan::YomitanDatabase> {
self.ensure_yomitan_attached()?; self.ensure_yomitan_attached()?;
Ok(yomitan::YomitanDatabase::new(self.clone())) Ok(yomitan::YomitanDatabase::new(self.clone()))
@@ -64,7 +69,7 @@ impl Database {
current_dir()?.join(dir) current_dir()?.join(dir)
}; };
let path = path let path = path
.join("yomitan.db") .join(YOMITAN_DBFILE)
.to_string_lossy() .to_string_lossy()
.replace(r"\", r"/"); .replace(r"\", r"/");
@@ -83,49 +88,4 @@ impl Database {
Ok(()) Ok(())
} }
pub fn init(&self) -> Result<()> {
let conn = self.conn.lock().unwrap();
conn.execute_batch(
"
CREATE TABLE IF NOT EXISTS entries (
id INTEGER PRIMARY KEY,
word TEXT NOT NULL,
definition TEXT NOT NULL
)",
)?;
Ok(())
}
pub fn insert_entry(&self, word: &str, definition: &str) -> Result<()> {
let conn = self.conn.lock().unwrap();
conn.execute(
"INSERT INTO entries (word, definition) VALUES (?, ?)",
[word, definition],
)?;
Ok(())
}
pub fn fetch_all_entries(&self) -> Result<Vec<Entry>> {
let conn = self.conn.lock().unwrap();
let mut stmt = conn.prepare("SELECT id, word, definition FROM entries")?;
let rows = stmt.query_map([], |row| {
Ok(Entry {
id: row.get(0)?,
word: row.get(1)?,
definition: row.get(2)?,
})
})?;
let mut entries = Vec::new();
for entry in rows {
entries.push(entry?);
}
Ok(entries)
}
} }
+3 -5
View File
@@ -1,11 +1,9 @@
mod api; mod db;
pub mod db;
mod error; mod error;
mod models; mod service;
pub mod service;
pub use db::{YomitanRow, YomitanZipImportProgress, YomitanZipImportResult};
pub use error::CJDicError; pub use error::CJDicError;
pub use models::*;
pub use service::AppService; pub use service::AppService;
pub fn add(left: u64, right: u64) -> u64 { pub fn add(left: u64, right: u64) -> u64 {
-8
View File
@@ -1,8 +0,0 @@
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entry {
pub id: i64,
pub word: String,
pub definition: String,
}
+7 -11
View File
@@ -3,9 +3,11 @@ use std::path::{Path, PathBuf};
use rusqlite::Connection; use rusqlite::Connection;
use crate::{ use crate::{
db::{Database, YomitanRow, YomitanWriter, YomitanZipImportProgress, YomitanZipImportResult}, db::{
Database, YOMITAN_DBFILE, YomitanRow, YomitanWriter, YomitanZipImportProgress,
YomitanZipImportResult,
},
error::CJDicError, error::CJDicError,
models::Entry,
}; };
pub struct AppService { pub struct AppService {
@@ -15,17 +17,11 @@ pub struct AppService {
impl AppService { impl AppService {
pub fn new<P: AsRef<Path>>(db_dir: P) -> Result<Self, CJDicError> { pub fn new<P: AsRef<Path>>(db_dir: P) -> Result<Self, CJDicError> {
let db = Database::new(db_dir)?; let db = Database::new(db_dir)?;
db.init()?;
Ok(Self { db }) Ok(Self { db })
} }
pub fn add_entry(&self, word: &str, definition: &str) -> Result<(), CJDicError> { pub fn is_yomitan_setup_yet(&self) -> bool {
self.db.insert_entry(word, definition)?; self.db.is_yomitan_dbfile_exists()
Ok(())
}
pub fn list_entries(&self) -> Result<Vec<Entry>, CJDicError> {
Ok(self.db.fetch_all_entries()?)
} }
pub fn search_yomitan( pub fn search_yomitan(
@@ -42,7 +38,7 @@ impl AppService {
} }
pub fn get_yomitan_writer(&self) -> Result<YomitanWriter, CJDicError> { pub fn get_yomitan_writer(&self) -> Result<YomitanWriter, CJDicError> {
let conn = Connection::open(self.db.dir.join("yomitan.db"))?; let conn = Connection::open(self.db.dir.join(YOMITAN_DBFILE))?;
let mut writer = YomitanWriter::new(conn)?; let mut writer = YomitanWriter::new(conn)?;
writer.create_schema()?; writer.create_schema()?;
Ok(writer) Ok(writer)
+4 -1
View File
@@ -1,12 +1,15 @@
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { Dialog, Portal } from "@chakra-ui/react"; import { Dialog, Portal } from "@chakra-ui/react";
import { invoke } from "@tauri-apps/api/core";
function LoadingDialog() { function LoadingDialog() {
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
useEffect(() => { useEffect(() => {
setIsLoading(true); invoke<boolean>("is_yomitan_setup_yet").then((is_setup) =>
setIsLoading(!is_setup),
);
}, []); }, []);
return ( return (
+8 -2
View File
@@ -29,19 +29,25 @@ function SearchPage() {
trySearch(); trySearch();
}, [q]); }, [q]);
async function trySearch() { function trySearch() {
if (!q.trim()) { if (!q.trim()) {
setEntries([]); setEntries([]);
return; return;
} }
let willRunSearch = runSearch;
if (searchTimeout) { if (searchTimeout) {
clearTimeout(searchTimeout); clearTimeout(searchTimeout);
} else {
// If new, just run immediately. No need for throttling.
runSearch();
willRunSearch = async () => {};
} }
setSearchTimeout( setSearchTimeout(
setTimeout(() => { setTimeout(() => {
runSearch(); willRunSearch();
}, 250), }, 250),
); );
} }
+3 -10
View File
@@ -1,16 +1,9 @@
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/ // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
use cjdic2_core::{AppService, Entry, db::YomitanRow}; use cjdic2_core::{AppService, YomitanRow};
#[tauri::command] #[tauri::command]
pub fn add_entry(name: &str, state: tauri::State<AppService>) -> Result<(), String> { pub fn is_yomitan_setup_yet(state: tauri::State<AppService>) -> bool {
state state.is_yomitan_setup_yet()
.add_entry(name, "definition")
.map_err(|e| e.to_string())
}
#[tauri::command]
pub fn list_entries(state: tauri::State<AppService>) -> Result<Vec<Entry>, String> {
state.list_entries().map_err(|e| e.to_string())
} }
#[tauri::command] #[tauri::command]
+4 -4
View File
@@ -1,4 +1,4 @@
use std::{fs::create_dir_all, path::Path}; use std::fs::create_dir_all;
use crate::command::*; use crate::command::*;
use cjdic2_core::*; use cjdic2_core::*;
@@ -15,15 +15,15 @@ pub fn run() {
create_dir_all(&app_dir)?; create_dir_all(&app_dir)?;
// db_path is app_dir; // db_path is app_dir;
let db_dir = Path::new(r"D:\Projects\cjdic2\tmp\save-db"); let db_dir = app_dir.as_path();
// let db_dir = Path::new(r"D:\Projects\cjdic2\tmp\save-db");
let service = AppService::new(&db_dir)?; let service = AppService::new(&db_dir)?;
app.manage(service); app.manage(service);
Ok(()) Ok(())
}) })
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
add_entry, is_yomitan_setup_yet,
list_entries,
search_yomitan search_yomitan
]) ])
.build(tauri::generate_context!()) .build(tauri::generate_context!())