aggregate data
This commit is contained in:
+28
-8
@@ -135,6 +135,10 @@ pub struct NoteListItem {
|
||||
url: String,
|
||||
protected: bool,
|
||||
created_by: Option<String>,
|
||||
participant_count: i64,
|
||||
file_count: i64,
|
||||
file_size_bytes: i64,
|
||||
revision_count: i64,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
@@ -224,17 +228,29 @@ pub async fn open_workspace(
|
||||
bearer_token(&headers),
|
||||
)
|
||||
.await?;
|
||||
let stats = db::list_note_stats(&state.db, workspace.id)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|stats| (stats.note_id, stats))
|
||||
.collect::<std::collections::HashMap<_, _>>();
|
||||
let notes = db::list_notes(&state.db, workspace.id)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|note| NoteListItem {
|
||||
url: format!("/w/{}/n/{}", workspace.slug, note.slug),
|
||||
slug: note.slug,
|
||||
title: note.title,
|
||||
created_at: db::normalize_timestamp(¬e.created_at),
|
||||
updated_at: db::normalize_timestamp(¬e.updated_at),
|
||||
protected: note.protected,
|
||||
created_by: note.created_by,
|
||||
.map(|note| {
|
||||
let stats = stats.get(¬e.id);
|
||||
NoteListItem {
|
||||
url: format!("/w/{}/n/{}", workspace.slug, note.slug),
|
||||
slug: note.slug,
|
||||
title: note.title,
|
||||
created_at: db::normalize_timestamp(¬e.created_at),
|
||||
updated_at: db::normalize_timestamp(¬e.updated_at),
|
||||
protected: note.protected,
|
||||
created_by: note.created_by,
|
||||
participant_count: stats.map_or(0, |value| value.participant_count),
|
||||
file_count: stats.map_or(0, |value| value.file_count),
|
||||
file_size_bytes: stats.map_or(0, |value| value.file_size_bytes),
|
||||
revision_count: stats.map_or(0, |value| value.revision_count),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
|
||||
@@ -307,6 +323,10 @@ pub async fn create_note(
|
||||
updated_at: db::normalize_timestamp(¬e.updated_at),
|
||||
protected: note.protected,
|
||||
created_by: note.created_by,
|
||||
participant_count: 0,
|
||||
file_count: 0,
|
||||
file_size_bytes: 0,
|
||||
revision_count: 0,
|
||||
}),
|
||||
))
|
||||
}
|
||||
|
||||
@@ -99,6 +99,15 @@ pub struct Revision {
|
||||
pub owner_map: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct NoteStats {
|
||||
pub note_id: i64,
|
||||
pub participant_count: i64,
|
||||
pub file_count: i64,
|
||||
pub file_size_bytes: i64,
|
||||
pub revision_count: i64,
|
||||
}
|
||||
|
||||
pub async fn find_workspace(pool: &Database, slug: &str) -> Result<Option<Workspace>, sqlx::Error> {
|
||||
sqlx::query_as::<_, Workspace>(queries::get(pool.kind(), queries::Q001))
|
||||
.bind(slug)
|
||||
@@ -164,6 +173,45 @@ pub async fn list_notes(pool: &Database, workspace_id: i64) -> Result<Vec<Note>,
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_note_stats(
|
||||
pool: &Database,
|
||||
workspace_id: i64,
|
||||
) -> Result<Vec<NoteStats>, sqlx::Error> {
|
||||
let placeholder = match pool.kind() {
|
||||
DatabaseKind::Postgres => "$1",
|
||||
DatabaseKind::Sqlite | DatabaseKind::MySql => "?",
|
||||
};
|
||||
let query = format!(
|
||||
"SELECT n.id AS note_id, \
|
||||
((SELECT COUNT(DISTINCT r.author) FROM note_revisions r \
|
||||
WHERE r.note_id = n.id AND r.author IS NOT NULL AND TRIM(r.author) <> '') + \
|
||||
CASE WHEN n.created_by IS NOT NULL AND TRIM(n.created_by) <> '' AND NOT EXISTS (\
|
||||
SELECT 1 FROM note_revisions r WHERE r.note_id = n.id AND r.author = n.created_by\
|
||||
) THEN 1 ELSE 0 END) AS participant_count, \
|
||||
(SELECT COUNT(*) FROM note_files f WHERE f.note_id = n.id) AS file_count, \
|
||||
(SELECT COALESCE(SUM(f.size_bytes), 0) FROM note_files f WHERE f.note_id = n.id) AS file_size_bytes, \
|
||||
(SELECT COUNT(*) FROM note_revisions r WHERE r.note_id = n.id) AS revision_count \
|
||||
FROM notes n WHERE n.workspace_id = {placeholder}"
|
||||
);
|
||||
|
||||
let rows = sqlx::query(&query)
|
||||
.bind(workspace_id)
|
||||
.fetch_all(pool.pool())
|
||||
.await?;
|
||||
|
||||
rows.into_iter()
|
||||
.map(|row| {
|
||||
Ok(NoteStats {
|
||||
note_id: row.try_get("note_id")?,
|
||||
participant_count: row.try_get("participant_count")?,
|
||||
file_count: row.try_get("file_count")?,
|
||||
file_size_bytes: row.try_get("file_size_bytes")?,
|
||||
revision_count: row.try_get("revision_count")?,
|
||||
})
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub async fn find_note(
|
||||
pool: &Database,
|
||||
workspace_id: i64,
|
||||
|
||||
Reference in New Issue
Block a user