diff --git a/Cargo.lock b/Cargo.lock index 86e7b92..20e07aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1334,6 +1334,7 @@ dependencies = [ "async-trait", "atty", "bindgen", + "bytes", "c_fixed_string", "cfg-if 1.0.0", "chrono", diff --git a/Cargo.toml b/Cargo.toml index 406af0d..5e80f51 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,6 +8,7 @@ edition = "2018" [dependencies] async-trait = { version = "0.1", optional = true } atty = "0.2" +bytes = { version = "1.2", optional = true } c_fixed_string = { version = "0.2", optional = true } cfg-if = "1" chrono = "0.4" @@ -46,7 +47,7 @@ cmake = { version = "0.1", optional = true } [features] all = ["db", "db_sqlite", "exif", "ugoira", "server"] avdict = ["bindgen", "cmake", "flagset"] -db = [] +db = ["bytes"] db_all = ["db", "db_sqlite"] db_sqlite = ["rusqlite"] exif = ["bindgen", "c_fixed_string", "cmake", "link-cplusplus", "utf16string"] diff --git a/src/db/mod.rs b/src/db/mod.rs index 13f9ea5..c0edbaa 100644 --- a/src/db/mod.rs +++ b/src/db/mod.rs @@ -2,6 +2,7 @@ pub mod config; #[cfg(feature = "db_sqlite")] pub mod sqlite; pub mod traits; +pub mod user; pub use config::check_db_config; pub use config::PixivDownloaderDbConfig; @@ -10,6 +11,7 @@ pub use config::PixivDownloaderSqliteConfig; #[cfg(feature = "db_sqlite")] pub use sqlite::{PixivDownloaderSqlite, SqliteError}; pub use traits::PixivDownloaderDb; +pub use user::User; pub type PixivDownloaderDbError = Box; use crate::{get_helper, gettext}; diff --git a/src/db/sqlite/db.rs b/src/db/sqlite/db.rs index 3de3702..3fbcc0d 100644 --- a/src/db/sqlite/db.rs +++ b/src/db/sqlite/db.rs @@ -1,9 +1,11 @@ use super::super::{ - PixivDownloaderDb, PixivDownloaderDbConfig, PixivDownloaderDbError, PixivDownloaderSqliteConfig, + PixivDownloaderDb, PixivDownloaderDbConfig, PixivDownloaderDbError, + PixivDownloaderSqliteConfig, User, }; use super::SqliteError; +use bytes::BytesMut; use futures_util::lock::Mutex; -use rusqlite::{Connection, OpenFlags, Transaction}; +use rusqlite::{Connection, OpenFlags, OptionalExtension, Transaction}; use std::collections::HashMap; const AUTHORS_TABLE: &'static str = "CREATE TABLE authors ( @@ -169,6 +171,23 @@ impl PixivDownloaderSqlite { Ok(tables) } + async fn _get_user(&self, id: u64) -> Result, SqliteError> { + let con = self.db.lock().await; + Ok(con + .query_row("SELECT * FROM users WHERE id = ?;", [id], |row| { + let password: Vec = row.get(3)?; + let password: &[u8] = &password; + Ok(User { + id: row.get(0)?, + name: row.get(1)?, + username: row.get(2)?, + password: BytesMut::from(password), + is_admin: row.get(4)?, + }) + }) + .optional()?) + } + async fn _read_version(&self) -> Result, SqliteError> { let con = self.db.lock().await; let mut stmt = con.prepare("SELECT v1, v2, v3, v4 FROM version WHERE id='main';")?; @@ -220,6 +239,10 @@ impl PixivDownloaderDb for PixivDownloaderSqlite { } } + async fn get_user(&self, id: u64) -> Result, PixivDownloaderDbError> { + Ok(self._get_user(id).await?) + } + async fn init(&self) -> Result<(), PixivDownloaderDbError> { if !self._check_database().await? { self._create_table().await?; diff --git a/src/db/traits.rs b/src/db/traits.rs index 07e8a07..379f4fd 100644 --- a/src/db/traits.rs +++ b/src/db/traits.rs @@ -1,14 +1,19 @@ use super::PixivDownloaderDbConfig; use super::PixivDownloaderDbError; +use super::User; #[async_trait] pub trait PixivDownloaderDb { /// Create a new instance of database + /// * `cfg` - The database configuration fn new + ?Sized>( cfg: &R, ) -> Result where Self: Sized + Send + Sync; + /// Get a user by ID + /// * `id`: The user's ID + async fn get_user(&self, id: u64) -> Result, PixivDownloaderDbError>; /// Initialize the database (create tables, migrate data, etc.) async fn init(&self) -> Result<(), PixivDownloaderDbError>; } diff --git a/src/db/user.rs b/src/db/user.rs new file mode 100644 index 0000000..fe99be9 --- /dev/null +++ b/src/db/user.rs @@ -0,0 +1,15 @@ +use bytes::BytesMut; + +/// A user in the database +pub struct User { + /// The user ID + pub id: u64, + /// The user's name + pub name: String, + /// Unique user name + pub username: String, + /// hashed password + pub password: BytesMut, + /// Whether the user is an admin + pub is_admin: bool, +}