From 0722947dedc333c038331b203c96c8abe5ea5d01 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Mon, 7 Apr 2025 22:26:28 +0200 Subject: [PATCH] implement note_store_save_attachment_async (in case the attachment is new, update is still unimplemented) --- application/attachment.c | 20 +++++++++- application/attachment.h | 2 +- application/note.c | 3 +- application/store.c | 82 +++++++++++++++++++++++++++++++++++++++- application/store.h | 2 + 5 files changed, 103 insertions(+), 6 deletions(-) diff --git a/application/attachment.c b/application/attachment.c index edacc1e..36a3b1b 100644 --- a/application/attachment.c +++ b/application/attachment.c @@ -29,6 +29,7 @@ #include "attachment.h" #include "note.h" +#include "store.h" #include #include @@ -83,8 +84,23 @@ void attachment_set_data(Attachment *attachment, cxmutstr data) { attachment->bin_content = data; } -void attachment_save(UiObject *obj, Attachment *attachment) { - +/* + * saves the attachment + * + * If cleanup_content is true, attachment->bin_content is set to NULL + */ +void attachment_save(UiObject *obj, Attachment *attachment, bool cleanup_content) { + if(!attachment->saved || !attachment->content_saved) { + cxmutstr content; + if(cleanup_content) { + // bin_content can be moved to note_store_save_attachment_async + content = attachment->bin_content; + attachment->bin_content = (cxmutstr){NULL, 0}; + } else { + content = attachment->bin_content.ptr ? cx_strdup(cx_strcast(attachment->bin_content)) : (cxmutstr){NULL, 0}; + } + note_store_save_attachment_async(obj, attachment, NULL, NULL); + } } diff --git a/application/attachment.h b/application/attachment.h index 36c0905..755d944 100644 --- a/application/attachment.h +++ b/application/attachment.h @@ -48,7 +48,7 @@ void attachment_set_image(Attachment *attachment, void *img); void attachment_set_data(Attachment *attachment, cxmutstr data); -void attachment_save(UiObject *obj, Attachment *attachment); +void attachment_save(UiObject *obj, Attachment *attachment, bool cleanup_content); // TODO: move this function to a separate file cxmutstr attachment_file_load(const CxAllocator *a, const char *path); diff --git a/application/note.c b/application/note.c index 1b2f9a4..d3f97ce 100644 --- a/application/note.c +++ b/application/note.c @@ -31,6 +31,7 @@ #include "store.h" #include "editor.h" #include "notebook.h" +#include "attachment.h" #include @@ -153,7 +154,7 @@ void note_save(UiObject *obj, NotebookModel *notebook, Resource *note) { if(note->attachments) { CxIterator i = cxListIterator(note->attachments); cx_foreach(Attachment *, attachment, i) { - attachment_save(obj, attachment); + attachment_save(obj, attachment, TRUE); } } } diff --git a/application/store.c b/application/store.c index 1226f03..e26a93d 100644 --- a/application/store.c +++ b/application/store.c @@ -70,6 +70,9 @@ #define SQL_NOTE_DELETE "delete from resources where resource_id = ? ;" +#define SQL_ATTACHMENT_RESOURCE_NEW "insert into resources(parent_id, name, lastmodified, creationdate, bin_content) values ((select parent_id from resources where resource_id = ?), ?, datetime(), datetime(), ?) returning resource_id;" +#define SQL_ATTACHMENT_NEW "insert into attachments(attachment_resource_id, parent_resource_id, type) values (?, ?, ?) returning attachment_id;" + static DBUConnection *connection; static UiThreadpool *queue; @@ -586,7 +589,7 @@ static int qthr_delete_note(DeleteNoteJob *job) { return 0; } -static void uithr_save_delete_finished(UiEvent *event, DeleteNoteJob *job) { +static void uithr_delete_finished(UiEvent *event, DeleteNoteJob *job) { if(job->resultcb) { job->resultcb(event, job->error, job->userdata); } @@ -600,5 +603,80 @@ void note_store_delete_async(UiObject *obj, Resource *note, UiBool move_to_trash job->resultcb = resultcb; job->userdata = userdata; job->error = 0; - ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_delete_note, job, (ui_callback)uithr_save_delete_finished, job); + ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_delete_note, job, (ui_callback)uithr_delete_finished, job); +} + + +typedef struct SaveAttachmentJob { + int64_t resource_id; + int64_t attachment_id; + cxmutstr content; + int type; + char *name; + execresult_func resultcb; + void *userdata; + int error; +} SaveAttachmentJob; + +static int qthr_save_attachment(SaveAttachmentJob *job) { + if(job->attachment_id == 0) { + DBUQuery *q = connection->createQuery(connection, NULL); + dbuQuerySetSQL(q, SQL_ATTACHMENT_RESOURCE_NEW); + dbuQuerySetParamInt64(q, 1, job->resource_id); + dbuQuerySetParamString(q, 2, cx_str(job->name)); + dbuQuerySetParamBytes(q, 3, job->content.ptr, job->content.length); + if(dbuQueryExec(q)) { + job->error = 1; + } else { + DBUResult *result = dbuQueryGetResult(q); + int64_t resource_id; + if(dbuResultAsInt64(result, &resource_id)) { + job->error = 2; + } else { + dbuQueryFree(q); + q = connection->createQuery(connection, NULL); + dbuQuerySetSQL(q, SQL_ATTACHMENT_NEW); + dbuQuerySetParamInt64(q, 1, job->resource_id); + dbuQuerySetParamInt64(q, 1, job->resource_id); + dbuQuerySetParamInt64(q, 1, job->type); + dbuQuerySetParamBytes(q, 3, job->content.ptr, job->content.length); + if(dbuQueryExec(q)) { + job->error = 3; + } else { + DBUResult *result = dbuQueryGetResult(q); + int64_t attachment_id; + if(dbuResultAsInt64(result, &attachment_id)) { + job->error = 4; + } + } + } + } + dbuQueryFree(q); + } else { + // TODO + } + + return 0; +} + +static void uithr_save_attachment_finished(UiEvent *event, SaveAttachmentJob *job) { + if(job->resultcb) { + job->resultcb(event, job->error, job->userdata); + } + + free(job->content.ptr); + free(job->name); + free(job); +} + +void note_store_save_attachment_async(UiObject *obj, Attachment *attachment, execresult_func resultcb, void *userdata) { + SaveAttachmentJob *job = malloc(sizeof(SaveAttachmentJob)); + job->resource_id = attachment->parent_resource_id; + job->attachment_id = attachment->attachment_id; + job->type = attachment->type; + job->name = strdup(attachment->name); + job->content = attachment->bin_content.ptr ? cx_strdup(cx_strcast(attachment->bin_content)) : (cxmutstr){NULL, 0}; + job->resultcb = resultcb; + job->userdata = userdata; + ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_save_attachment, job, (ui_callback)uithr_save_attachment_finished, job); } diff --git a/application/store.h b/application/store.h index 06527fd..951e9b2 100644 --- a/application/store.h +++ b/application/store.h @@ -92,6 +92,8 @@ void note_store_save_note_async(UiObject *obj, Resource *note, execresult_func r void note_store_delete_async(UiObject *obj, Resource *note, UiBool move_to_trash, execresult_func resultcb, void *userdata); +void note_store_save_attachment_async(UiObject *obj, Attachment *attachment, execresult_func resultcb, void *userdata); + #ifdef __cplusplus } #endif -- 2.43.5