This commit is contained in:
1 parent
e646598078
commit
ead5d96b78
13 files changed
+1829
-1
No files matched your search
@@ -12,6 +12,34 @@ use chrono::{DateTime, TimeZone, Utc};
|
||||
use serde::de::DeserializeOwned;
|
||||
use sqlx::{Executor, Sqlite, SqlitePool, Transaction};
|
||||
use uuid::Uuid;
|
||||
#[derive(Clone, Debug, sqlx::FromRow)]
|
||||
pub(crate) struct InstanceScreenshotSource {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub path: String,
|
||||
}
|
||||
|
||||
pub(crate) async fn get_instance_screenshot_source(
|
||||
instance_id: &str,
|
||||
pool: &SqlitePool,
|
||||
) -> crate::Result<Option<InstanceScreenshotSource>> {
|
||||
Ok(sqlx::query_as::<_, InstanceScreenshotSource>(
|
||||
"SELECT id, name, path FROM instances WHERE id = ?",
|
||||
)
|
||||
.bind(instance_id)
|
||||
.fetch_optional(pool)
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub(crate) async fn list_screenshot_sources(
|
||||
pool: &SqlitePool,
|
||||
) -> crate::Result<Vec<InstanceScreenshotSource>> {
|
||||
Ok(sqlx::query_as::<_, InstanceScreenshotSource>(
|
||||
"SELECT id, name, path FROM instances ORDER BY name, id",
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?)
|
||||
}
|
||||
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
pub(crate) struct InstanceRow {
|
||||
|
||||
@@ -2,3 +2,4 @@ pub(crate) mod config_sync_rows;
|
||||
pub(crate) mod content_rows;
|
||||
pub(crate) mod instance_rows;
|
||||
pub(crate) mod loader_component_rows;
|
||||
pub(crate) mod screenshot_rows;
|
||||
@@ -0,0 +1,236 @@
|
||||
use sqlx::{Sqlite, SqlitePool, Transaction};
|
||||
|
||||
#[derive(Clone, Debug, sqlx::FromRow)]
|
||||
pub(crate) struct ScreenshotRow {
|
||||
pub id: String,
|
||||
pub instance_id: String,
|
||||
pub file_name: String,
|
||||
pub content_hash: String,
|
||||
pub file_size: i64,
|
||||
pub modified_at: i64,
|
||||
pub created_at: i64,
|
||||
pub group_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, sqlx::FromRow)]
|
||||
pub(crate) struct ScreenshotGroupRow {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
pub(crate) async fn list_screenshots(
|
||||
instance_id: &str,
|
||||
pool: &SqlitePool,
|
||||
) -> crate::Result<Vec<ScreenshotRow>> {
|
||||
Ok(sqlx::query_as!(
|
||||
ScreenshotRow,
|
||||
r#"
|
||||
SELECT
|
||||
screenshots.id,
|
||||
screenshots.instance_id,
|
||||
screenshots.file_name,
|
||||
screenshots.content_hash,
|
||||
screenshots.file_size,
|
||||
screenshots.modified_at,
|
||||
screenshots.created_at,
|
||||
memberships.group_id AS "group_id?"
|
||||
FROM screenshots
|
||||
LEFT JOIN screenshot_group_memberships memberships
|
||||
ON memberships.screenshot_id = screenshots.id
|
||||
WHERE screenshots.instance_id = ?
|
||||
ORDER BY screenshots.file_name, screenshots.id
|
||||
"#,
|
||||
instance_id,
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub(crate) async fn get_screenshot_by_key(
|
||||
instance_id: &str,
|
||||
file_name: &str,
|
||||
pool: &SqlitePool,
|
||||
) -> crate::Result<Option<ScreenshotRow>> {
|
||||
Ok(sqlx::query_as!(
|
||||
ScreenshotRow,
|
||||
r#"
|
||||
SELECT
|
||||
screenshots.id,
|
||||
screenshots.instance_id,
|
||||
screenshots.file_name,
|
||||
screenshots.content_hash,
|
||||
screenshots.file_size,
|
||||
screenshots.modified_at,
|
||||
screenshots.created_at,
|
||||
memberships.group_id AS "group_id?"
|
||||
FROM screenshots
|
||||
LEFT JOIN screenshot_group_memberships memberships
|
||||
ON memberships.screenshot_id = screenshots.id
|
||||
WHERE screenshots.instance_id = ? AND screenshots.file_name = ?
|
||||
"#,
|
||||
instance_id,
|
||||
file_name,
|
||||
)
|
||||
.fetch_optional(pool)
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub(crate) async fn copy_group_membership(
|
||||
source_id: &str,
|
||||
edited_id: &str,
|
||||
tx: &mut Transaction<'_, Sqlite>,
|
||||
) -> crate::Result<()> {
|
||||
sqlx::query!(
|
||||
r#"
|
||||
INSERT INTO screenshot_group_memberships (screenshot_id, group_id)
|
||||
SELECT ?, group_id
|
||||
FROM screenshot_group_memberships
|
||||
WHERE screenshot_id = ?
|
||||
ON CONFLICT (screenshot_id) DO UPDATE SET group_id = excluded.group_id
|
||||
"#,
|
||||
edited_id,
|
||||
source_id,
|
||||
)
|
||||
.execute(&mut **tx)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn insert_screenshot(
|
||||
row: &ScreenshotRow,
|
||||
tx: &mut Transaction<'_, Sqlite>,
|
||||
) -> crate::Result<()> {
|
||||
sqlx::query!(
|
||||
"
|
||||
INSERT INTO screenshots (
|
||||
id,
|
||||
instance_id,
|
||||
file_name,
|
||||
content_hash,
|
||||
file_size,
|
||||
modified_at,
|
||||
created_at
|
||||
)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
",
|
||||
row.id,
|
||||
row.instance_id,
|
||||
row.file_name,
|
||||
row.content_hash,
|
||||
row.file_size,
|
||||
row.modified_at,
|
||||
row.created_at,
|
||||
)
|
||||
.execute(&mut **tx)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn update_screenshot(
|
||||
row: &ScreenshotRow,
|
||||
tx: &mut Transaction<'_, Sqlite>,
|
||||
) -> crate::Result<()> {
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE screenshots
|
||||
SET
|
||||
instance_id = ?,
|
||||
file_name = ?,
|
||||
content_hash = ?,
|
||||
file_size = ?,
|
||||
modified_at = ?,
|
||||
created_at = ?
|
||||
WHERE id = ?
|
||||
",
|
||||
row.instance_id,
|
||||
row.file_name,
|
||||
row.content_hash,
|
||||
row.file_size,
|
||||
row.modified_at,
|
||||
row.created_at,
|
||||
row.id,
|
||||
)
|
||||
.execute(&mut **tx)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn delete_screenshot(
|
||||
id: &str,
|
||||
tx: &mut Transaction<'_, Sqlite>,
|
||||
) -> crate::Result<()> {
|
||||
sqlx::query!("DELETE FROM screenshots WHERE id = ?", id)
|
||||
.execute(&mut **tx)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn move_screenshot(
|
||||
source_instance_id: &str,
|
||||
source_file_name: &str,
|
||||
target_instance_id: &str,
|
||||
target_file_name: &str,
|
||||
pool: &SqlitePool,
|
||||
) -> crate::Result<()> {
|
||||
let mut tx = pool.begin().await?;
|
||||
sqlx::query!(
|
||||
"DELETE FROM screenshots WHERE instance_id = ? AND file_name = ?",
|
||||
target_instance_id,
|
||||
target_file_name,
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
|
||||
sqlx::query!(
|
||||
"
|
||||
UPDATE screenshots
|
||||
SET instance_id = ?, file_name = ?
|
||||
WHERE instance_id = ? AND file_name = ?
|
||||
",
|
||||
target_instance_id,
|
||||
target_file_name,
|
||||
source_instance_id,
|
||||
source_file_name,
|
||||
)
|
||||
.execute(&mut *tx)
|
||||
.await?;
|
||||
|
||||
tx.commit().await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn delete_screenshot_by_key(
|
||||
instance_id: &str,
|
||||
file_name: &str,
|
||||
pool: &SqlitePool,
|
||||
) -> crate::Result<()> {
|
||||
sqlx::query!(
|
||||
"DELETE FROM screenshots WHERE instance_id = ? AND file_name = ?",
|
||||
instance_id,
|
||||
file_name,
|
||||
)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) async fn list_groups(
|
||||
pool: &SqlitePool,
|
||||
) -> crate::Result<Vec<ScreenshotGroupRow>> {
|
||||
Ok(sqlx::query_as!(
|
||||
ScreenshotGroupRow,
|
||||
"
|
||||
SELECT id, name
|
||||
FROM screenshot_groups
|
||||
ORDER BY display_order, name, id
|
||||
",
|
||||
)
|
||||
.fetch_all(pool)
|
||||
.await?)
|
||||
}
|
||||
@@ -120,6 +120,7 @@ pub struct State {
|
||||
pub(crate) install_job_cancellations: DashMap<Uuid, CancellationToken>,
|
||||
pub(crate) install_job_operation_locks:
|
||||
DashMap<Uuid, Arc<AsyncMutex<InstallJobOperationState>>>,
|
||||
pub(crate) screenshot_locks: DashMap<String, Arc<AsyncMutex<()>>>,
|
||||
|
||||
/// Process manager
|
||||
pub process_manager: ProcessManager,
|
||||
@@ -904,6 +905,7 @@ impl State {
|
||||
install_db_semaphore: Semaphore::new(1),
|
||||
install_job_cancellations: DashMap::new(),
|
||||
install_job_operation_locks: DashMap::new(),
|
||||
screenshot_locks: DashMap::new(),
|
||||
process_manager,
|
||||
friends_socket,
|
||||
restart_after_pending_update: AtomicBool::new(false),
|
||||
@@ -931,6 +933,18 @@ impl State {
|
||||
) -> InstanceLockGuard {
|
||||
self.instance_locks.lock_exclusive(instance_id).await
|
||||
}
|
||||
|
||||
pub(crate) async fn lock_instance_screenshots(
|
||||
&self,
|
||||
instance_id: &str,
|
||||
) -> tokio::sync::OwnedMutexGuard<()> {
|
||||
self.screenshot_locks
|
||||
.entry(instance_id.to_string())
|
||||
.or_insert_with(|| Arc::new(AsyncMutex::new(())))
|
||||
.clone()
|
||||
.lock_owned()
|
||||
.await
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@@ -971,6 +985,7 @@ pub(crate) async fn test_state(
|
||||
install_db_semaphore: Semaphore::new(1),
|
||||
install_job_cancellations: DashMap::new(),
|
||||
install_job_operation_locks: DashMap::new(),
|
||||
screenshot_locks: DashMap::new(),
|
||||
process_manager: ProcessManager::new(),
|
||||
friends_socket: FriendsSocket::new(),
|
||||
restart_after_pending_update: AtomicBool::new(false),
|
||||
|
||||
Reference in new issue
Block a user