Update database

This commit is contained in:
2022-10-23 13:49:11 +00:00
committed by GitHub
parent 9d1bb86d97
commit 918ce0ecb4
7 changed files with 169 additions and 7 deletions

View File

@@ -52,7 +52,7 @@ cmake = { version = "0.1", optional = true }
[features]
all = ["db", "db_sqlite", "exif", "ugoira", "server"]
avdict = ["bindgen", "cmake", "flagset"]
db = ["anyhow", "async-trait", "bytes"]
db = ["anyhow", "async-trait", "bytes", "flagset"]
db_all = ["db", "db_sqlite"]
db_sqlite = ["rusqlite"]
exif = ["bindgen", "c_fixed_string", "cmake", "link-cplusplus", "utf16string"]

View File

@@ -3,5 +3,4 @@
| id | File id | integer |
| path | The path of the file | string |
| last_modified | The last time the file was modified(HTTP Header) | timestamp |
| etag | The etag(HTTP Header) of the file | string |
| url | The source url | string |

View File

@@ -6,3 +6,5 @@
| uid | User id of the author | integer |
| description | Description of artwork | string |
| count | Number of pages | integer |
| is_nsfw | Whether the artwork is NSFW | boolean |
| lock | Specify which part should not be updated. | integer |

View File

@@ -1,4 +1,5 @@
pub mod config;
pub mod pixiv_artworks;
#[cfg(feature = "db_sqlite")]
pub mod sqlite;
#[cfg(feature = "server")]
@@ -11,6 +12,7 @@ pub use config::check_db_config;
pub use config::PixivDownloaderDbConfig;
#[cfg(feature = "db_sqlite")]
pub use config::PixivDownloaderSqliteConfig;
pub use pixiv_artworks::{PixivArtwork, PixivArtworkLock};
#[cfg(feature = "db_sqlite")]
pub use sqlite::{PixivDownloaderSqlite, SqliteError};
#[cfg(feature = "server")]

30
src/db/pixiv_artworks.rs Normal file
View File

@@ -0,0 +1,30 @@
use flagset::FlagSet;
flagset::flags! {
/// Speicfy which part should not be updated.
pub enum PixivArtworkLock: u8 {
Title = 1,
Author = 2,
Description = 4,
IsNsfw = 8,
}
}
pub struct PixivArtwork {
/// The artwork ID
pub id: u64,
/// The artwork title
pub title: String,
/// The artwork author
pub author: String,
/// The author's UID
pub uid: u64,
/// The artwork description
pub description: String,
/// The artwork's page count
pub count: u64,
/// Whether the artwork is NSFW
pub is_nsfw: bool,
/// Specify which part should not be updated.
pub lock: FlagSet<PixivArtworkLock>,
}

View File

@@ -1,11 +1,12 @@
#[cfg(feature = "server")]
use super::super::{PixivArtwork, PixivArtworkLock, Token, User};
use super::super::{
PixivDownloaderDb, PixivDownloaderDbConfig, PixivDownloaderDbError, PixivDownloaderSqliteConfig,
};
#[cfg(feature = "server")]
use super::super::{Token, User};
use super::SqliteError;
use bytes::BytesMut;
use chrono::{DateTime, Utc};
use flagset::FlagSet;
use futures_util::lock::Mutex;
use rusqlite::{Connection, OpenFlags, OptionalExtension, Transaction};
use std::collections::HashMap;
@@ -24,7 +25,6 @@ const FILES_TABLE: &'static str = "CREATE TABLE files (
id INTEGER PRIMARY KEY AUTOINCREMENT,
path TEXT,
last_modified DATETIME,
etag TEXT,
url TEXT
);";
const PIXIV_ARTWORK_TAGS_TABLE: &'static str = "CREATE TABLE pixiv_artwork_tags (
@@ -37,7 +37,9 @@ title TEXT,
author TEXT,
uid INT,
description TEXT,
count INT
count INT,
is_nsfw BOOLEAN,
lock INT
);";
const PIXIV_FILES_TABLE: &'static str = "CREATE TABLE pixiv_files (
id INT,
@@ -75,13 +77,40 @@ v3 INT,
v4 INT,
PRIMARY KEY (id)
);";
const VERSION: [u8; 4] = [1, 0, 0, 4];
const VERSION: [u8; 4] = [1, 0, 0, 5];
pub struct PixivDownloaderSqlite {
db: Mutex<Connection>,
}
impl PixivDownloaderSqlite {
fn _add_pixiv_artwork(
ts: &Transaction,
id: u64,
title: &str,
author: &str,
uid: u64,
description: &str,
count: u64,
is_nsfw: bool,
lock: &FlagSet<PixivArtworkLock>,
) -> Result<(), SqliteError> {
ts.execute(
"INSERT INTO pixiv_artworks (id, title, author, uid, description, count, is_nsfw, lock) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
(
id,
title,
author,
uid,
description,
count,
is_nsfw,
lock.bits(),
),
)?;
Ok(())
}
#[cfg(feature = "server")]
async fn _add_root_user(
&self,
@@ -172,6 +201,12 @@ impl PixivDownloaderSqlite {
tx.execute(TOKEN_TABLE, [])?;
tx.execute(USERS_TABLE, [])?;
}
if db_version < [1, 0, 0, 5] {
tx.execute("DROP TABLE files;", [])?;
tx.execute(FILES_TABLE, [])?;
tx.execute("ALTER TABLE pixiv_artworks ADD is_nsfw BOOLEAN;", [])?;
tx.execute("ALTER TABLE pixiv_artworks ADD lock INT;", [])?;
}
self._write_version(&tx)?;
tx.commit()?;
}
@@ -258,6 +293,35 @@ impl PixivDownloaderSqlite {
Ok(tables)
}
async fn get_pixiv_artwork(&self, id: u64) -> Result<Option<PixivArtwork>, SqliteError> {
let con = self.db.lock().await;
Ok(con
.query_row("SELECT * FROM pixiv_artworks WHERE id = ?;", [id], |row| {
let lock: u8 = row.get(7)?;
Ok(PixivArtwork {
id: row.get(0)?,
title: row.get(1)?,
author: row.get(2)?,
uid: row.get(3)?,
description: row.get(4)?,
count: row.get(5)?,
is_nsfw: row.get(6)?,
lock: match FlagSet::<PixivArtworkLock>::new(lock) {
Ok(f) => f,
Err(_) => {
return Err(rusqlite::Error::FromSqlConversionFailure(
7,
rusqlite::types::Type::Integer,
"Failed to parse lock bit.".into(),
)
.into())
}
},
})
})
.optional()?)
}
#[cfg(feature = "server")]
async fn get_token(&self, id: u64) -> Result<Option<Token>, SqliteError> {
let con = self.db.lock().await;
@@ -555,6 +619,36 @@ impl PixivDownloaderDb for PixivDownloaderSqlite {
}
}
async fn add_pixiv_artwork(
&self,
id: u64,
title: &str,
author: &str,
uid: u64,
description: &str,
count: u64,
is_nsfw: bool,
lock: &FlagSet<PixivArtworkLock>,
) -> Result<PixivArtwork, PixivDownloaderDbError> {
{
let mut con = self.db.lock().await;
let mut ts = con.transaction()?;
Self::_add_pixiv_artwork(
&mut ts,
id,
title,
author,
uid,
description,
count,
is_nsfw,
lock,
)?;
ts.commit()?;
}
Ok(self.get_pixiv_artwork(id).await?.expect("User not found:"))
}
#[cfg(feature = "server")]
async fn add_root_user(
&self,
@@ -644,6 +738,13 @@ impl PixivDownloaderDb for PixivDownloaderSqlite {
Ok(())
}
async fn get_pixiv_artwork(
&self,
id: u64,
) -> Result<Option<PixivArtwork>, PixivDownloaderDbError> {
Ok(self.get_pixiv_artwork(id).await?)
}
#[cfg(feature = "server")]
async fn get_token(&self, id: u64) -> Result<Option<Token>, PixivDownloaderDbError> {
Ok(self.get_token(id).await?)

View File

@@ -1,8 +1,10 @@
use super::PixivDownloaderDbConfig;
use super::PixivDownloaderDbError;
use super::{PixivArtwork, PixivArtworkLock};
#[cfg(feature = "server")]
use super::{Token, User};
use chrono::{DateTime, Utc};
use flagset::FlagSet;
#[async_trait]
pub trait PixivDownloaderDb {
@@ -13,6 +15,26 @@ pub trait PixivDownloaderDb {
) -> Result<Self, PixivDownloaderDbError>
where
Self: Sized + Send + Sync;
/// Add/Update an artwork to the database
/// * `id` - The artwork ID
/// * `title` - The artwork title
/// * `author` - The artwork author
/// * `uid` - The author's ID
/// * `description` - The artwork description
/// * `count` - The artwork's page count
/// * `is_nsfw` - Whether the artwork is NSFW
/// * `lock` - Specify which part should not be updated.
async fn add_pixiv_artwork(
&self,
id: u64,
title: &str,
author: &str,
uid: u64,
description: &str,
count: u64,
is_nsfw: bool,
lock: &FlagSet<PixivArtworkLock>,
) -> Result<PixivArtwork, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Add root user to database.
/// * `name` - User name
@@ -73,6 +95,12 @@ pub trait PixivDownloaderDb {
id: u64,
expired_at: &DateTime<Utc>,
) -> Result<(), PixivDownloaderDbError>;
/// Get an artwork from database
/// * `id` - The artwork ID
async fn get_pixiv_artwork(
&self,
id: u64,
) -> Result<Option<PixivArtwork>, PixivDownloaderDbError>;
#[cfg(feature = "server")]
/// Get token by ID
/// * `id` - The token ID