big dev changes

This commit is contained in:
Mateusz Gruszczyński
2026-07-21 10:11:57 +02:00
parent 4bb92a343b
commit 0b4b1753a0
23 changed files with 690 additions and 51 deletions
+186 -12
View File
@@ -44,6 +44,39 @@ pub struct Note {
pub created_at: String,
pub updated_at: String,
pub owner_map: String,
pub protected: bool,
pub created_by: Option<String>,
}
#[derive(Debug, Clone, FromRow)]
struct SqliteNote {
id: i64,
workspace_id: i64,
slug: String,
title: String,
content: String,
created_at: String,
updated_at: String,
owner_map: String,
protected: i64,
created_by: Option<String>,
}
impl From<SqliteNote> for Note {
fn from(value: SqliteNote) -> Self {
Self {
id: value.id,
workspace_id: value.workspace_id,
slug: value.slug,
title: value.title,
content: value.content,
created_at: value.created_at,
updated_at: value.updated_at,
owner_map: value.owner_map,
protected: value.protected != 0,
created_by: value.created_by,
}
}
}
#[derive(Debug, Serialize, FromRow)]
@@ -98,10 +131,19 @@ pub fn verify_workspace_password(workspace: &Workspace, password: Option<&str>)
}
pub async fn list_notes(pool: &Database, workspace_id: i64) -> Result<Vec<Note>, sqlx::Error> {
if pool.kind() == DatabaseKind::Sqlite {
return Ok(sqlx::query_as::<_, SqliteNote>(queries::Q003)
.bind(workspace_id)
.fetch_all(pool.pool())
.await?
.into_iter()
.map(Note::from)
.collect());
}
sqlx::query_as::<_, Note>(queries::get(pool.kind(), queries::Q003))
.bind(workspace_id)
.fetch_all(pool.pool())
.await
.bind(workspace_id)
.fetch_all(pool.pool())
.await
}
pub async fn find_note(
@@ -109,11 +151,19 @@ pub async fn find_note(
workspace_id: i64,
slug: &str,
) -> Result<Option<Note>, sqlx::Error> {
if pool.kind() == DatabaseKind::Sqlite {
return Ok(sqlx::query_as::<_, SqliteNote>(queries::Q004)
.bind(workspace_id)
.bind(slug)
.fetch_optional(pool.pool())
.await?
.map(Note::from));
}
sqlx::query_as::<_, Note>(queries::get(pool.kind(), queries::Q004))
.bind(workspace_id)
.bind(slug)
.fetch_optional(pool.pool())
.await
.bind(workspace_id)
.bind(slug)
.fetch_optional(pool.pool())
.await
}
pub async fn create_note(
@@ -121,19 +171,21 @@ pub async fn create_note(
workspace_id: i64,
slug: &str,
title: &str,
protected: bool,
created_by: Option<&str>,
) -> Result<Note, sqlx::Error> {
sqlx::query(queries::get(pool.kind(), queries::Q005))
.bind(workspace_id)
.bind(slug)
.bind(title)
.bind(protected)
.bind(created_by)
.execute(pool.pool())
.await?;
sqlx::query_as::<_, Note>(queries::get(pool.kind(), queries::Q004))
.bind(workspace_id)
.bind(slug)
.fetch_one(pool.pool())
.await
find_note(pool, workspace_id, slug)
.await?
.ok_or(sqlx::Error::RowNotFound)
}
pub async fn save_revision(
@@ -453,3 +505,125 @@ pub async fn find_file_owner(pool: &Database, token: &str) -> Result<Option<File
}
Ok(None)
}
#[derive(Debug, Clone, Serialize, FromRow)]
pub struct NoteFile {
pub id: i64,
pub filename: String,
pub url: String,
pub mime_type: String,
pub size_bytes: i64,
pub created_at: String,
pub is_attached: bool,
pub detached_at: Option<String>,
}
#[derive(Debug, Clone, FromRow)]
struct SqliteNoteFile {
id: i64,
filename: String,
url: String,
mime_type: String,
size_bytes: i64,
created_at: String,
is_attached: i64,
detached_at: Option<String>,
}
impl From<SqliteNoteFile> for NoteFile {
fn from(value: SqliteNoteFile) -> Self {
Self {
id: value.id,
filename: value.filename,
url: value.url,
mime_type: value.mime_type,
size_bytes: value.size_bytes,
created_at: value.created_at,
is_attached: value.is_attached != 0,
detached_at: value.detached_at,
}
}
}
pub async fn delete_note(pool: &Database, note_id: i64) -> Result<(), sqlx::Error> {
sqlx::query(queries::get(pool.kind(), queries::Q031)).bind(note_id).execute(pool.pool()).await?;
Ok(())
}
pub async fn register_note_file(pool: &Database, note_id: i64, filename: &str, url: &str, mime_type: &str, size_bytes: i64) -> Result<(), sqlx::Error> {
sqlx::query(queries::get(pool.kind(), queries::Q032))
.bind(note_id).bind(filename).bind(url).bind(mime_type).bind(size_bytes)
.execute(pool.pool()).await?;
Ok(())
}
pub async fn list_note_files(pool: &Database, note_id: i64) -> Result<Vec<NoteFile>, sqlx::Error> {
list_files(pool, queries::Q033, note_id).await
}
async fn list_files(pool: &Database, query: &'static str, owner_id: i64) -> Result<Vec<NoteFile>, sqlx::Error> {
if pool.kind() == DatabaseKind::Sqlite {
return Ok(sqlx::query_as::<_, SqliteNoteFile>(query)
.bind(owner_id)
.fetch_all(pool.pool())
.await?
.into_iter()
.map(NoteFile::from)
.collect());
}
sqlx::query_as::<_, NoteFile>(queries::get(pool.kind(), query))
.bind(owner_id)
.fetch_all(pool.pool())
.await
}
pub async fn set_note_file_attached(pool: &Database, file_id: i64, attached: bool) -> Result<(), sqlx::Error> {
let detached_at: Option<String> = if attached { None } else { Some(chrono::Utc::now().to_rfc3339()) };
sqlx::query(queries::get(pool.kind(), queries::Q034)).bind(attached).bind(detached_at).bind(file_id).execute(pool.pool()).await?;
Ok(())
}
pub async fn register_pad_file(pool: &Database, pad_id: i64, filename: &str, url: &str, mime_type: &str, size_bytes: i64) -> Result<(), sqlx::Error> {
sqlx::query(queries::get(pool.kind(), queries::Q035))
.bind(pad_id).bind(filename).bind(url).bind(mime_type).bind(size_bytes)
.execute(pool.pool()).await?;
Ok(())
}
pub async fn list_pad_files(pool: &Database, pad_id: i64) -> Result<Vec<NoteFile>, sqlx::Error> {
list_files(pool, queries::Q036, pad_id).await
}
pub async fn set_pad_file_attached(pool: &Database, file_id: i64, attached: bool) -> Result<(), sqlx::Error> {
let detached_at: Option<String> = if attached { None } else { Some(chrono::Utc::now().to_rfc3339()) };
sqlx::query(queries::get(pool.kind(), queries::Q037)).bind(attached).bind(detached_at).bind(file_id).execute(pool.pool()).await?;
Ok(())
}
pub async fn find_note_file(pool: &Database, note_id: i64, file_id: i64) -> Result<Option<NoteFile>, sqlx::Error> {
if pool.kind() == DatabaseKind::Sqlite {
return Ok(sqlx::query_as::<_, SqliteNoteFile>(queries::Q038)
.bind(file_id)
.bind(note_id)
.fetch_optional(pool.pool())
.await?
.map(NoteFile::from));
}
sqlx::query_as::<_, NoteFile>(queries::get(pool.kind(), queries::Q038))
.bind(file_id)
.bind(note_id)
.fetch_optional(pool.pool())
.await
}
pub async fn delete_note_file(pool: &Database, note_id: i64, file_id: i64) -> Result<(), sqlx::Error> {
sqlx::query(queries::get(pool.kind(), queries::Q039))
.bind(file_id)
.bind(note_id)
.execute(pool.pool())
.await?;
Ok(())
}