From 9b0666eef9109c4f37e7b45853c9b21ed0b4d448 Mon Sep 17 00:00:00 2001 From: Olaf Wintermann Date: Fri, 16 Jan 2026 11:34:36 +0100 Subject: [PATCH] add note_store_save_notebook_async --- application/nbconfig.c | 6 +-- application/store.c | 66 +++++++++++++++++++++++++++---- application/store.h | 6 ++- application/tests/test-store.c | 71 +++++++++++++++++++++++++++++++--- application/tests/test-store.h | 5 ++- application/tests/testmain.c | 3 +- 6 files changed, 137 insertions(+), 20 deletions(-) diff --git a/application/nbconfig.c b/application/nbconfig.c index b903448..7c604a3 100644 --- a/application/nbconfig.c +++ b/application/nbconfig.c @@ -146,7 +146,7 @@ static void nbconfig_group_save(NotebookConfigDialog *nbconfig) { if(res->resource_id == 0) { note_store_new_notebook_async(application_global_obj(), res, group_created, res); } else { - note_store_save_resource_async(application_global_obj(), res, group_saved, res); + note_store_update_resource_async(application_global_obj(), res, group_saved, res); note_store_groups_updated(); } } @@ -272,7 +272,7 @@ static void nbconfig_grouplist_name_changed(UiEvent *event, void *userdata) { static void notebook_created(UiEvent *event, int64_t newid, int error, void *userdata) { NoteStore *store = note_store_get(); Resource *res = userdata; - Resource *parent = note_store_get_notebook_by_id(res->parent_id); + Resource *parent = note_store_get_notebook_by_id(store, res->parent_id); if(parent) { if(!parent->children) { parent->children = cxArrayListCreate(store->mp->allocator, CX_STORE_POINTERS, 8); @@ -308,7 +308,7 @@ static void nbconfig_notebook_save(NotebookConfigDialog *nbconfig) { if(res->resource_id == 0) { note_store_new_notebook_async(application_global_obj(), res, notebook_created, res); } else { - note_store_save_resource_async(application_global_obj(), res, notebook_saved, res); + note_store_update_resource_async(application_global_obj(), res, notebook_saved, res); note_store_groups_updated(); } } diff --git a/application/store.c b/application/store.c index 27c0b84..4c47bf8 100644 --- a/application/store.c +++ b/application/store.c @@ -494,11 +494,15 @@ NoteStore* note_store_get() { return current_store; } -Resource* note_store_get_notebook_by_id(int64_t resource_id) { - if(!current_store || !current_store->root) { +Resource* note_store_get_notebook_by_id(NoteStore *store, int64_t resource_id) { + if(!store || !store->root) { return NULL; } + if(store->root->resource_id == resource_id) { + return store->root; + } + CxIterator i = cxListIterator(current_store->root->children); cx_foreach(Resource *, res, i) { if(res->resource_id == resource_id) { @@ -1025,10 +1029,10 @@ typedef struct ExecJob { int error; } ExecJob; -static int qthr_save_resource(ExecJob *job) { +static int qthr_update_resource(ExecJob *job) { Resource *res = job->resource; DBUQuery *q = dbuQueryCreate(connection, NULL, SQL_RESOURCE_SAVE); - + if(res->nodename) { dbuQuerySetParamString(q, 1, cx_str(res->nodename)); } else { @@ -1063,20 +1067,68 @@ static int qthr_save_resource(ExecJob *job) { return 0; } -static void uithr_save_resource_finished(UiEvent *event, ExecJob *job) { +static void uithr_update_resource_finished(UiEvent *event, ExecJob *job) { if(job->resultcb) { job->resultcb(event, job->error, job->userdata); } free(job); } -void note_store_save_resource_async(UiObject *obj, Resource *res, execresult_func resultcb, void *userdata) { +void note_store_update_resource_async(UiObject *obj, Resource *res, execresult_func resultcb, void *userdata) { ExecJob *job = malloc(sizeof(ExecJob)); job->resource = res; job->resultcb = resultcb; job->userdata = userdata; job->error = 0; - ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_save_resource, job, (ui_callback)uithr_save_resource_finished, job); + //qthr_update_resource(job); + //uithr_update_resource_finished(NULL, job); + ui_threadpool_job(queue, obj, (ui_threadfunc)qthr_update_resource, job, (ui_callback)uithr_update_resource_finished, job); +} + +typedef struct SaveResourceJob { + NoteStore *store; + Resource *res; + execresult_func resultcb; + void *userdata; +} SaveResourceJob; + +static void uithr_save_resource_finished(UiEvent *event, int error, void *userdata) { + SaveResourceJob *job = userdata; + if(!error) { + note_store_groups_updated(); + } + if(job->resultcb) { + job->resultcb(event, error, job->userdata); + } +} + +static void uithr_save_new_resource_finished(UiEvent *event, int64_t newid, int error, void *userdata) { + SaveResourceJob *job = userdata; + if(!error) { + NoteStore *store = job->store; + job->res->resource_id = newid; + Resource *parent = note_store_get_notebook_by_id(store, job->res->parent_id); + if(parent) { + if(!parent->children) { + parent->children = cxArrayListCreate(store->mp->allocator, CX_STORE_POINTERS, 8); + } + cxListAdd(parent->children, job->res); + } + } + uithr_save_resource_finished(event, error, userdata); +} + +void note_store_save_notebook_async(UiObject *obj, Resource *res, execresult_func resultcb, void *userdata) { + SaveResourceJob *job = malloc(sizeof(SaveResourceJob)); + job->store = note_store_get(); + job->res = res; + job->resultcb = resultcb; + job->userdata = userdata; + if(res->resource_id == 0) { + note_store_new_notebook_async(obj, res, uithr_save_new_resource_finished, job); + } else { + note_store_update_resource_async(obj, res, uithr_save_resource_finished, job); + } } static void uithr_execjob_finished(UiEvent *event, ExecJob *job) { diff --git a/application/store.h b/application/store.h index ab6446f..f1b3939 100644 --- a/application/store.h +++ b/application/store.h @@ -117,7 +117,7 @@ int note_store_reload(); NoteStore* note_store_get(); -Resource* note_store_get_notebook_by_id(int64_t resource_id); +Resource* note_store_get_notebook_by_id(NoteStore *store, int64_t resource_id); CxList* note_store_get_notes(const CxAllocator *a, int64_t parent_collection_id); void note_store_get_notes_async(UiObject *obj, int64_t parent_resource_id, listresult_func resultcb, void *userdata); @@ -138,7 +138,9 @@ void note_store_new_notebook_async(UiObject *obj, Resource *notebook, createresu void note_store_new_resource_async(UiObject *obj, Resource *res, createresult_func resultcb, void *userdata); -void note_store_save_resource_async(UiObject *obj, Resource *res, execresult_func resultcb, void *userdata); +void note_store_update_resource_async(UiObject *obj, Resource *res, execresult_func resultcb, void *userdata); + +void note_store_save_notebook_async(UiObject *obj, Resource *res, execresult_func resultcb, void *userdata); void note_store_delete_empty_collection_async( UiObject *obj, diff --git a/application/tests/test-store.c b/application/tests/test-store.c index f2e4fae..c8fc54d 100644 --- a/application/tests/test-store.c +++ b/application/tests/test-store.c @@ -223,12 +223,12 @@ CX_TEST(test_note_store_new_notebook_async) { } } -static void test_save_resource_result(UiEvent *event, int error, void *userdata) { +static void test_update_resource_result(UiEvent *event, int error, void *userdata) { int *ptr = userdata; *ptr = error; } -CX_TEST(test_note_store_save_resource_async) { +CX_TEST(test_note_store_update_resource_async) { CX_TEST_DO { UiObject *obj = ui_dummy_object(); @@ -246,11 +246,11 @@ CX_TEST(test_note_store_save_resource_async) { } CX_TEST_ASSERT(res); - cxFree(store->mp->allocator, res->nodename); + //cxFree(store->mp->allocator, res->nodename); res->nodename = cx_strdup_a(store->mp->allocator, "test_save_resource_result").ptr; int result = -1; - note_store_save_resource_async(obj, res, test_save_resource_result, &result); + note_store_update_resource_async(obj, res, test_update_resource_result, &result); ui_exec_buffered_mainthread_calls_wait(3); CX_TEST_ASSERT(!note_store_reload()); @@ -271,6 +271,67 @@ CX_TEST(test_note_store_save_resource_async) { } } +static void test_save_notebook_result(UiEvent *event, int error, void *userdata) { + int *ptr = userdata; + *ptr = error; +} + +CX_TEST(test_note_store_save_notebook_async) { + CX_TEST_DO { + UiObject *obj = ui_dummy_object(); + + NoteStore *store = note_store_get(); + CX_TEST_ASSERT(store); + size_t numchildren = cxListSize(store->root->children); + + // Test 1: create a new resource + Resource *res0 = cxZalloc(store->mp->allocator, sizeof(Resource)); + res0->parent_id = store->root->resource_id; + res0->nodename = cx_strdup_a(store->mp->allocator, "test_save_notebook_res0").ptr; + + int error = -1; + note_store_save_notebook_async(obj, res0, test_save_notebook_result, &error); + ui_exec_buffered_mainthread_calls_wait(3); + + CX_TEST_ASSERT(error == 0); + CX_TEST_ASSERT(cxListSize(store->root->children) == numchildren + 1); + + int64_t resource_id = res0->resource_id; + + CX_TEST_ASSERT(!note_store_reload()); + store = note_store_get(); + CX_TEST_ASSERT(store && store->root && store->root->children); + CX_TEST_ASSERT(cxListSize(store->root->children) == numchildren + 1); + + res0 = note_store_get_notebook_by_id(store, resource_id); + CX_TEST_ASSERT(res0); + CX_TEST_ASSERT(res0->resource_id == resource_id); + CX_TEST_ASSERT(!cx_strcmp(res0->nodename, "test_save_notebook_res0")); + + // Test 2: update resource + numchildren = cxListSize(store->root->children); + res0->nodename = "test_save_notebook_update0"; //cx_strdup_a(store->mp->allocator, "test_save_notebook_update0").ptr; + + ui_exec_buffered_mainthread_calls(); + error = -1; + note_store_save_notebook_async(obj, res0, test_save_notebook_result, &error); + ui_exec_buffered_mainthread_calls_wait(3); + + CX_TEST_ASSERT(error == 0); + CX_TEST_ASSERT(cxListSize(store->root->children) == numchildren); + CX_TEST_ASSERT(!note_store_reload()); + store = note_store_get(); + CX_TEST_ASSERT(store && store->root && store->root->children); + CX_TEST_ASSERT(cxListSize(store->root->children) == numchildren); + + res0 = note_store_get_notebook_by_id(store, resource_id); + CX_TEST_ASSERT(res0); + CX_TEST_ASSERT(!cx_strcmp(res0->nodename, "test_save_notebook_update0")); + + ui_close(obj); + } +} + CX_TEST(test_note_store_get_notebook_by_id) { // it is important that this test is run after some other tests // created some resources @@ -282,7 +343,7 @@ CX_TEST(test_note_store_get_notebook_by_id) { CxIterator i = cxListIterator(store->root->children); cx_foreach(Resource *, res, i) { - Resource *xres = note_store_get_notebook_by_id(res->resource_id); + Resource *xres = note_store_get_notebook_by_id(store, res->resource_id); CX_TEST_ASSERT(res == xres); } } diff --git a/application/tests/test-store.h b/application/tests/test-store.h index 0e12cdd..eefcb13 100644 --- a/application/tests/test-store.h +++ b/application/tests/test-store.h @@ -39,11 +39,12 @@ CX_TEST(test_init_note_store); CX_TEST(test_note_store_create_default); CX_TEST(test_user_settings_is_valid); -CX_TEST(test_note_store_get_notebook_by_id); CX_TEST(test_note_store_reload); CX_TEST(test_note_store_new_resource_async); CX_TEST(test_note_store_new_notebook_async); -CX_TEST(test_note_store_save_resource_async); +CX_TEST(test_note_store_update_resource_async); +CX_TEST(test_note_store_save_notebook_async); +CX_TEST(test_note_store_get_notebook_by_id); #ifdef __cplusplus diff --git a/application/tests/testmain.c b/application/tests/testmain.c index de17487..a0cbc06 100644 --- a/application/tests/testmain.c +++ b/application/tests/testmain.c @@ -59,7 +59,8 @@ int main(int argc, char **argv) { cx_test_register(suite, test_note_store_reload); cx_test_register(suite, test_note_store_new_resource_async); cx_test_register(suite, test_note_store_new_notebook_async); - cx_test_register(suite, test_note_store_save_resource_async); + cx_test_register(suite, test_note_store_update_resource_async); + cx_test_register(suite, test_note_store_save_notebook_async); cx_test_register(suite, test_note_store_get_notebook_by_id); cx_test_register(suite, test_parse_markdown_para); -- 2.47.3