281 lines
7.1 KiB
Rust
281 lines
7.1 KiB
Rust
use super::*;
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub enum FileOwnerKind {
|
|
Pad,
|
|
Note,
|
|
}
|
|
|
|
#[derive(Debug, Clone, Copy)]
|
|
pub struct FileOwner {
|
|
pub kind: FileOwnerKind,
|
|
pub id: i64,
|
|
}
|
|
|
|
pub async fn find_file_owner(
|
|
pool: &Database,
|
|
token: &str,
|
|
) -> Result<Option<FileOwner>, sqlx::Error> {
|
|
if let Some(id) = sqlx::query_scalar::<_, i64>(queries::get(pool.kind(), queries::Q026))
|
|
.bind(token)
|
|
.fetch_optional(pool.pool())
|
|
.await?
|
|
{
|
|
return Ok(Some(FileOwner {
|
|
kind: FileOwnerKind::Pad,
|
|
id,
|
|
}));
|
|
}
|
|
if let Some(id) = sqlx::query_scalar::<_, i64>(queries::get(pool.kind(), queries::Q027))
|
|
.bind(token)
|
|
.fetch_optional(pool.pool())
|
|
.await?
|
|
{
|
|
return Ok(Some(FileOwner {
|
|
kind: FileOwnerKind::Note,
|
|
id,
|
|
}));
|
|
}
|
|
Ok(None)
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize)]
|
|
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: queries::Query,
|
|
owner_id: i64,
|
|
) -> Result<Vec<NoteFile>, sqlx::Error> {
|
|
if pool.kind() == DatabaseKind::Sqlite {
|
|
return Ok(
|
|
sqlx::query_as::<_, SqliteNoteFile>(queries::get(pool.kind(), 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::get(pool.kind(), 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(())
|
|
}
|
|
|
|
pub async fn find_pad_file(
|
|
pool: &Database,
|
|
pad_id: i64,
|
|
file_id: i64,
|
|
) -> Result<Option<NoteFile>, sqlx::Error> {
|
|
if pool.kind() == DatabaseKind::Sqlite {
|
|
return Ok(
|
|
sqlx::query_as::<_, SqliteNoteFile>(queries::get(pool.kind(), queries::Q046))
|
|
.bind(file_id)
|
|
.bind(pad_id)
|
|
.fetch_optional(pool.pool())
|
|
.await?
|
|
.map(NoteFile::from),
|
|
);
|
|
}
|
|
sqlx::query_as::<_, NoteFile>(queries::get(pool.kind(), queries::Q046))
|
|
.bind(file_id)
|
|
.bind(pad_id)
|
|
.fetch_optional(pool.pool())
|
|
.await
|
|
}
|
|
|
|
pub async fn delete_pad_file(
|
|
pool: &Database,
|
|
pad_id: i64,
|
|
file_id: i64,
|
|
) -> Result<(), sqlx::Error> {
|
|
sqlx::query(queries::get(pool.kind(), queries::Q047))
|
|
.bind(file_id)
|
|
.bind(pad_id)
|
|
.execute(pool.pool())
|
|
.await?;
|
|
Ok(())
|
|
}
|
|
|
|
|
|
impl<'r> sqlx::FromRow<'r, AnyRow> for NoteFile {
|
|
fn from_row(row: &'r AnyRow) -> Result<Self, sqlx::Error> {
|
|
let attached: i64 = row.try_get("is_attached")?;
|
|
Ok(Self {
|
|
id: row.try_get("id")?,
|
|
filename: crate::row_decode::text(row, "filename")?,
|
|
url: crate::row_decode::text(row, "url")?,
|
|
mime_type: crate::row_decode::text(row, "mime_type")?,
|
|
size_bytes: row.try_get("size_bytes")?,
|
|
created_at: crate::row_decode::text(row, "created_at")?,
|
|
is_attached: attached != 0,
|
|
detached_at: crate::row_decode::optional_text(row, "detached_at")?,
|
|
})
|
|
}
|
|
}
|