Wed, 11 Dec 2024 21:53:31 +0100
add object cache
| dbutils/object.c | file | annotate | diff | comparison | revisions | |
| dbutils/object.h | file | annotate | diff | comparison | revisions |
--- a/dbutils/object.c Wed Dec 11 20:57:19 2024 +0100 +++ b/dbutils/object.c Wed Dec 11 21:53:31 2024 +0100 @@ -33,6 +33,7 @@ #include <cx/array_list.h> #include <cx/linked_list.h> #include <cx/hash_map.h> +#include <cx/printf.h> #include "object.h" @@ -110,7 +111,7 @@ .create = list_result_create, .add = list_result_add }; - if(dbuObjectBuilderGet(builder, &result)) { + if(dbuObjectExec(builder, &result)) { cxListDestroy(result_list); return NULL; } @@ -136,10 +137,10 @@ cxListDestroy(result_list); return NULL; } - if(dbuObjectBuilderGet(builder, &result)) { + if(dbuObjectExec(builder, &result)) { cxListDestroy(result_list); return NULL; - } + } return result_list; } @@ -155,13 +156,50 @@ /* ------------------------- Object Builder -----------------------------*/ -int dbuObjectBuilderGet(DBUObjectBuilder *builder, DBUObjectBuilderResult *objresult) { - DBUClass *cls = builder->resultType; // TODO: rename var +static int result_add_noop(DBUObjectBuilderResult *result, void *obj) { + return 0; +} + +int dbuObjectExec(DBUObjectBuilder *builder, DBUObjectBuilderResult *objresult) { + if(cxListSize(builder->additionalQueries) > 0) { + builder->cache = cxHashMapCreateSimple(sizeof(DBUBuilderObjCache)); + if(!builder->cache) { + return 1; + } + } + + int ret = dbuObjectExecuteQuery(builder, builder->mainQuery, builder->resultType, objresult); + if(!ret) { + CxIterator i = cxListIterator(builder->additionalQueries); + cx_foreach(DBUBuilderQuery *, a, i) { + DBUObjectBuilderResult result = { + .userdata1 = NULL, + .userdata2 = NULL, + .int1 = CX_STORE_POINTERS, + .create = list_result_create, + .add = result_add_noop + }; + + ret = dbuObjectExecuteQuery(builder, a->query, a->type, &result); + if(ret) { + break; + } + } + } + + if(builder->cache) { + cxMapDestroy(builder->cache); + } + builder->cache = NULL; + return ret; +} + +int dbuObjectExecuteQuery(DBUObjectBuilder *builder, DBUQuery *query, DBUClass *type, DBUObjectBuilderResult *objresult) { + DBUClass *cls = type; // TODO: execute additional queries // execute sql - DBUQuery *query = builder->mainQuery; if(query->exec(query)) { query->free(query); return 1; @@ -276,6 +314,24 @@ } else { cxstring text = result->getText(result, i); field.field->initValue(field.field, a, current_obj, text.ptr, text.length); + + // if obj caching is enabled and the current field contains + // the primary key, add this object to the cache + if(builder->cache && field.field == current_cls->primary_key) { + cxmutstr cache_key = cx_asprintf("%.*s::%.*s", + (int)current_cls->name.length, current_cls->name.ptr, + (int)text.length, text.ptr); + if(!cache_key.ptr) { + err = 1; + break; + } + int r = cxMapPut(builder->cache, cache_key, current_obj); + free(cache_key.ptr); + if(r) { + err = 1; + break; + } + } } } }
--- a/dbutils/object.h Wed Dec 11 20:57:19 2024 +0100 +++ b/dbutils/object.h Wed Dec 11 21:53:31 2024 +0100 @@ -60,6 +60,11 @@ void (*free)(DBUObjectBuilderResult *result); }; +typedef struct DBUBuilderObjCache { + DBUClass *class; + void *obj; +} DBUBuilderObjCache; + struct DBUObjectBuilder { const CxAllocator *allocator; @@ -88,8 +93,8 @@ /* * value: DBUBuilderQuery * - * Additional queries are executed before the main query and the result - * objects are cached and later added as children to the main result. + * Additional queries are executed after the main query and the result + * objects are added to the previous queried objects */ CxList *additionalQueries; @@ -97,9 +102,20 @@ * result builder */ DBUObjectBuilderResult *result; + + /* + * object cache + * + * key: <tablename> + <primary key> + * value: DBUBuilderObjCache + * + */ + CxMap *cache; }; -int dbuObjectBuilderGet(DBUObjectBuilder *builder, DBUObjectBuilderResult *objresult); +int dbuObjectExec(DBUObjectBuilder *builder, DBUObjectBuilderResult *objresult); + +int dbuObjectExecuteQuery(DBUObjectBuilder *builder, DBUQuery *query, DBUClass *type, DBUObjectBuilderResult *objresult); #ifdef __cplusplus }