Add new data model
This commit is contained in:
parent
945984adfa
commit
ce5f3bbd7d
1 changed files with 316 additions and 70 deletions
140
sync-server/src/app_state/database/queries.rs
Normal file
140
sync-server/src/app_state/database/queries.rs
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
use super::{Database, Transaction, models::*};
|
||||
use anyhow::{Result, ensure};
|
||||
|
||||
impl Database {
|
||||
pub async fn get_request_event(
|
||||
tx: &mut Transaction<'_>,
|
||||
request_id: uuid::Uuid,
|
||||
) -> Result<Option<(Vec<u8>, String)>> {
|
||||
Ok(sqlx::query_as(
|
||||
"SELECT request_fingerprint, event_json FROM events WHERE request_id = ?",
|
||||
)
|
||||
.bind(request_id.to_string())
|
||||
.fetch_optional(&mut **tx)
|
||||
.await?)
|
||||
}
|
||||
|
||||
pub async fn get_latest_document_version(
|
||||
&self,
|
||||
vault: &VaultId,
|
||||
id: &DocumentId,
|
||||
transaction: Option<&mut Transaction<'_>>,
|
||||
) -> Result<Option<StoredDocumentVersion>> {
|
||||
let query = sqlx::query_as::<_, StoredDocumentVersion>(
|
||||
"SELECT * FROM documents WHERE document_id = ? ORDER BY vault_update_id DESC LIMIT 1",
|
||||
)
|
||||
.bind(id.hyphenated());
|
||||
|
||||
Ok(if let Some(tx) = transaction {
|
||||
query.fetch_optional(&mut **tx).await?
|
||||
} else {
|
||||
query
|
||||
.fetch_optional(&self.get_connection_pool(vault).await?)
|
||||
.await?
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn get_document_version(
|
||||
&self,
|
||||
vault: &VaultId,
|
||||
version: VaultUpdateId,
|
||||
transaction: Option<&mut Transaction<'_>>,
|
||||
) -> Result<Option<StoredDocumentVersion>> {
|
||||
let query = sqlx::query_as::<_, StoredDocumentVersion>(
|
||||
"SELECT * FROM documents WHERE vault_update_id = ?",
|
||||
)
|
||||
.bind(version);
|
||||
|
||||
Ok(if let Some(tx) = transaction {
|
||||
query.fetch_optional(&mut **tx).await?
|
||||
} else {
|
||||
query
|
||||
.fetch_optional(&self.get_connection_pool(vault).await?)
|
||||
.await?
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn current_file_manifest(tx: &mut Transaction<'_>) -> Result<FileManifest> {
|
||||
let Some(file_manifest_id) = sqlx::query_scalar::<_, VaultUpdateId>(
|
||||
"SELECT file_manifest_id FROM file_manifests ORDER BY file_manifest_id DESC LIMIT 1",
|
||||
)
|
||||
.fetch_optional(&mut **tx)
|
||||
.await?
|
||||
else {
|
||||
return Ok(FileManifest::default());
|
||||
};
|
||||
|
||||
let entries = sqlx::query_as::<_, (uuid::fmt::Hyphenated, String)>(
|
||||
"SELECT document_id, path FROM file_manifest_entries WHERE file_manifest_id = ?",
|
||||
)
|
||||
.bind(file_manifest_id)
|
||||
.fetch_all(&mut **tx)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|(document_id, path)| (document_id.into_uuid(), path))
|
||||
.collect();
|
||||
|
||||
Ok(FileManifest {
|
||||
file_manifest_id,
|
||||
entries,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn latest_event_id(tx: &mut Transaction<'_>) -> Result<VaultUpdateId> {
|
||||
Ok(
|
||||
sqlx::query_scalar("SELECT COALESCE(MAX(event_id), 0) FROM events")
|
||||
.fetch_one(&mut **tx)
|
||||
.await?,
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn vault_snapshot(&self, vault: &VaultId) -> Result<VaultSnapshot> {
|
||||
let mut tx = self.create_readonly_transaction(vault).await?;
|
||||
let head_event_id = Self::latest_event_id(&mut tx).await?;
|
||||
let file_manifest = Self::current_file_manifest(&mut tx).await?;
|
||||
|
||||
let versions = sqlx::query_as::<_, StoredDocumentVersion>(
|
||||
"SELECT d.* FROM latest_document_versions d
|
||||
JOIN file_manifest_entries m ON m.document_id = d.document_id
|
||||
WHERE m.file_manifest_id = ? ORDER BY d.vault_update_id",
|
||||
)
|
||||
.bind(file_manifest.file_manifest_id)
|
||||
.fetch_all(&mut *tx)
|
||||
.await?;
|
||||
|
||||
let documents = versions.into_iter().map(Into::into).collect();
|
||||
|
||||
Ok(VaultSnapshot {
|
||||
head_event_id,
|
||||
file_manifest,
|
||||
documents,
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn events_after(&self, vault: &VaultId, after: VaultUpdateId) -> Result<EventBatch> {
|
||||
let mut tx = self.create_readonly_transaction(vault).await?;
|
||||
let head_event_id = Self::latest_event_id(&mut tx).await?;
|
||||
|
||||
ensure!(
|
||||
(0..=head_event_id).contains(&after),
|
||||
"Event cursor is outside this vault's history"
|
||||
);
|
||||
|
||||
let rows: Vec<String> = sqlx::query_scalar(
|
||||
"SELECT event_json FROM events WHERE event_id > ? ORDER BY event_id",
|
||||
)
|
||||
.bind(after)
|
||||
.fetch_all(&mut *tx)
|
||||
.await?;
|
||||
|
||||
let events = rows
|
||||
.iter()
|
||||
.map(|json| serde_json::from_str(json))
|
||||
.collect::<Result<_, _>>()?;
|
||||
|
||||
Ok(EventBatch {
|
||||
head_event_id,
|
||||
events,
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue