diff --git a/src/database.js.c b/src/database.js.c index c20cf80c..b309d05f 100644 --- a/src/database.js.c +++ b/src/database.js.c @@ -23,6 +23,7 @@ static void _database_finalizer(JSRuntime *runtime, JSValue value); static JSValue _database_get(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _database_set(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); +static JSValue _database_exchange(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _database_remove(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _database_get_all(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); static JSValue _database_get_like(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv); @@ -72,6 +73,7 @@ static JSValue _database_create(JSContext* context, JSValueConst this_val, int a JS_SetPropertyStr(context, object, "get", JS_NewCFunction(context, _database_get, "get", 1)); JS_SetPropertyStr(context, object, "set", JS_NewCFunction(context, _database_set, "set", 2)); + JS_SetPropertyStr(context, object, "exchange", JS_NewCFunction(context, _database_exchange, "exchange", 2)); JS_SetPropertyStr(context, object, "remove", JS_NewCFunction(context, _database_remove, "remove", 1)); JS_SetPropertyStr(context, object, "getAll", JS_NewCFunction(context, _database_get_all, "getAll", 0)); JS_SetPropertyStr(context, object, "getLike", JS_NewCFunction(context, _database_get_like, "getLike", 1)); @@ -140,6 +142,36 @@ JSValue _database_set(JSContext* context, JSValueConst this_val, int argc, JSVal return JS_UNDEFINED; } +static JSValue _database_exchange(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) +{ + JSValue exchanged = JS_UNDEFINED; + database_t* database = JS_GetOpaque(this_val, _database_class_id); + if (database) + { + sqlite3_stmt* statement; + if (sqlite3_prepare(database->db, "UPDATE properties SET value = $1 WHERE id = $2 AND key = $3 AND value = $4", -1, &statement, NULL) == SQLITE_OK) + { + size_t key_length; + size_t expected_length; + size_t set_length; + const char* key = JS_ToCStringLen(context, &key_length, argv[0]); + const char* expected = JS_ToCStringLen(context, &expected_length, argv[1]); + const char* set = JS_ToCStringLen(context, &set_length, argv[2]); + if (sqlite3_bind_text(statement, 1, set, set_length, NULL) == SQLITE_OK && + sqlite3_bind_text(statement, 2, database->id, -1, NULL) == SQLITE_OK && + sqlite3_bind_text(statement, 3, key, key_length, NULL) == SQLITE_OK && + sqlite3_bind_text(statement, 4, expected, expected_length, NULL) == SQLITE_OK && + sqlite3_step(statement) == SQLITE_DONE) + { + exchanged = sqlite3_changes(database->db) != 0 ? JS_TRUE : JS_FALSE; + } + JS_FreeCString(context, key); + sqlite3_finalize(statement); + } + } + return exchanged; +} + JSValue _database_remove(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { database_t* database = JS_GetOpaque(this_val, _database_class_id);