From 100d61050f5fb60f41cea6b0e6bb12fb5d751a05 Mon Sep 17 00:00:00 2001 From: LDA Date: Sat, 9 Nov 2024 16:59:49 +0100 Subject: [PATCH] [ADD/FIX] Add DbOPERATIONArgs functions, fix LMDB --- CHANGELOG.md | 2 ++ include/Cytoplasm/Db.h | 42 +++++++++++++++++++++++ src/Db/Db.c | 75 ++++++++++++++++++++++++++++++++++++++---- src/Db/Flat.c | 3 +- src/Db/LMDB.c | 4 ++- 5 files changed, 118 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a646e92..95c7149 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,8 @@ are not even initialized to a default value. - Make `HttpRouter` decode path parts before matching them on regular expressions. - Fixed a bug in `ArraySort()` that would crash programs if the passed array has no elements. +- Adds `Db[OP]Args` functions that are equivalent to their `Db[OP]` counter parts, but + uses an array of string instead of variadic arguments. ## v0.4.0 diff --git a/include/Cytoplasm/Db.h b/include/Cytoplasm/Db.h index 14a1064..c481521 100644 --- a/include/Cytoplasm/Db.h +++ b/include/Cytoplasm/Db.h @@ -119,6 +119,13 @@ extern void DbMaxCacheSet(Db *, size_t); */ extern DbRef * DbCreate(Db *, size_t,...); +/** + * Behaves like + * .Fn DbCreate , + * but with an array of strings instead of variadic arguments. + */ +extern DbRef * DbCreateArgs(Db *, Array *); + /** * Lock an existing object in the database. This function will fail * if the object does not exist. It takes a variable number of C @@ -129,6 +136,13 @@ extern DbRef * DbCreate(Db *, size_t,...); */ extern DbRef * DbLock(Db *, size_t,...); +/** + * Behaves like + * .Fn DbLock , + * but with an array of strings instead of variadic arguments. + */ +extern DbRef * DbLockArgs(Db *, Array *); + /** * Behaves like * .Fn DbLock , @@ -138,6 +152,13 @@ extern DbRef * DbLock(Db *, size_t,...); */ extern DbRef * DbLockIntent(Db *, DbHint, size_t,...); +/** + * Behaves like + * .Fn DbLockIntent , + * but with an array of strings instead of variadic arguments. + */ +extern DbRef * DbLockIntentArgs(Db *, DbHint, Array *); + /** * Immediately and permanently remove an object from the database. * This function assumes the object is not locked, otherwise undefined @@ -145,6 +166,13 @@ extern DbRef * DbLockIntent(Db *, DbHint, size_t,...); */ extern bool DbDelete(Db *, size_t,...); +/** + * Behaves like + * .Fn DbDelete , + * but with an array of strings instead of variadic arguments. + */ +extern bool DbDeleteArgs(Db *, Array *); + /** * Unlock an object and return it back to the database. This function * immediately syncs the object to the filesystem. The cache is a @@ -162,6 +190,13 @@ extern bool DbUnlock(Db *, DbRef *); */ extern bool DbExists(Db *, size_t,...); +/** + * Behaves like + * .Fn DbExists , + * but with an array of strings instead of variadic arguments. + */ +extern bool DbExistsArgs(Db *, Array *); + /** * List all of the objects at a given path. Unlike the other varargs * functions, this one does not take a path to a specific object; it @@ -174,6 +209,13 @@ extern bool DbExists(Db *, size_t,...); */ extern Array * DbList(Db *, size_t,...); +/** + * Behaves like + * .Fn DbList , + * but with an array of strings instead of variadic arguments. + */ +extern Array * DbListArgs(Db *, Array *); + /** * Free the list returned by * .Fn DbListFree . diff --git a/src/Db/Db.c b/src/Db/Db.c index 1015bbf..b275b84 100644 --- a/src/Db/Db.c +++ b/src/Db/Db.c @@ -262,6 +262,16 @@ DbClose(Db * db) Free(db); } +DbRef * +DbCreateArgs(Db * db, Array *args) +{ + if (!args || !db || !db->create) + { + return NULL; + } + + return db->create(db, args); +} DbRef * DbCreate(Db * db, size_t nArgs,...) { @@ -283,12 +293,22 @@ DbCreate(Db * db, size_t nArgs,...) return NULL; } - ret = db->create(db, args); + ret = DbCreateArgs(db, args); ArrayFree(args); return ret; } +bool +DbDeleteArgs(Db * db, Array *args) +{ + if (!args || !db || !db->delete) + { + return false; + } + + return db->delete(db, args); +} bool DbDelete(Db * db, size_t nArgs,...) { @@ -305,12 +325,22 @@ DbDelete(Db * db, size_t nArgs,...) args = ArrayFromVarArgs(nArgs, ap); va_end(ap); - ret = db->delete(db, args); + ret = DbDeleteArgs(db, args); ArrayFree(args); return ret; } +DbRef * +DbLockArgs(Db * db, Array *args) +{ + if (!args || !db || !db->lockFunc) + { + return NULL; + } + + return db->lockFunc(db, DB_HINT_WRITE, args); +} DbRef * DbLock(Db * db, size_t nArgs,...) { @@ -318,6 +348,11 @@ DbLock(Db * db, size_t nArgs,...) Array *args; DbRef *ret; + if (!db) + { + return NULL; + } + va_start(ap, nArgs); args = ArrayFromVarArgs(nArgs, ap); va_end(ap); @@ -327,13 +362,22 @@ DbLock(Db * db, size_t nArgs,...) return NULL; } - ret = db->lockFunc(db, DB_HINT_WRITE, args); + ret = DbLockArgs(db, args); ArrayFree(args); return ret; } +DbRef * +DbLockIntentArgs(Db * db, DbHint hint, Array *args) +{ + if (!db || !args || !db->lockFunc) + { + return NULL; + } + return db->lockFunc(db, hint, args); +} DbRef * DbLockIntent(Db * db, DbHint hint, size_t nArgs,...) { @@ -350,7 +394,7 @@ DbLockIntent(Db * db, DbHint hint, size_t nArgs,...) return NULL; } - ret = db->lockFunc(db, hint, args); + ret = DbLockIntentArgs(db, hint, args); ArrayFree(args); @@ -368,6 +412,16 @@ DbUnlock(Db * db, DbRef * ref) return db->unlock(db, ref); } +bool +DbExistsArgs(Db * db, Array *args) +{ + if (!args || !db || !db->exists) + { + return false; + } + + return db->exists(db, args); +} bool DbExists(Db * db, size_t nArgs,...) { @@ -388,12 +442,21 @@ DbExists(Db * db, size_t nArgs,...) return false; } - ret = db->exists(db, args); + ret = DbExistsArgs(db, args); ArrayFree(args); return ret; } +Array * +DbListArgs(Db *db, Array *args) +{ + if (!db || !args || !db->list) + { + return NULL; + } + return db->list(db, args); +} Array * DbList(Db * db, size_t nArgs,...) { @@ -410,7 +473,7 @@ DbList(Db * db, size_t nArgs,...) path = ArrayFromVarArgs(nArgs, ap); va_end(ap); - result = db->list(db, path); + result = DbListArgs(db, path); ArrayFree(path); return result; diff --git a/src/Db/Flat.c b/src/Db/Flat.c index df5685c..5945bb4 100644 --- a/src/Db/Flat.c +++ b/src/Db/Flat.c @@ -54,7 +54,8 @@ DbDirName(FlatDb * db, Array * args, size_t strip) { char *tmp; char *sanitise = StrDuplicate(ArrayGet(args, i)); - for (j = 0; j < strlen(sanitise); j++) + size_t len = strlen(sanitise); + for (j = 0; j < len; j++) { sanitise[j] = DbSanitiseChar(sanitise[j]); } diff --git a/src/Db/LMDB.c b/src/Db/LMDB.c index f1c743c..7c7eee6 100644 --- a/src/Db/LMDB.c +++ b/src/Db/LMDB.c @@ -128,7 +128,9 @@ LMDBKeyHead(MDB_val key) return NULL; } - while ((void *) (end - 1) >= key.mv_data && *(end - 1)) + /* Doing >= will lead to cases where it is sent straight to the + * start. Don't do that. */ + while ((void *) (end - 1) > key.mv_data && *(end - 1)) { end--; } -- 2.45.2