diff --git a/core/core.js b/core/core.js index 4c0d3bd7..90829d47 100644 --- a/core/core.js +++ b/core/core.js @@ -232,6 +232,14 @@ async function getProcessBlob(blobId, key, options) { }, 'getUser': getUser.bind(null, process, process), 'user': getUser(process, process), + 'apps': function() { + var apps = process.credentials && + process.credentials.session && + process.credentials.session.name ? + new Database(process.credentials.session.name).getLike('path:%') : + {}; + return Object.fromEntries(Object.keys(apps).map(key => [key.substring(5), apps[key]])); + }, } }; if (options.api) { diff --git a/src/database.c b/src/database.c index 4a703ede..3247aded 100644 --- a/src/database.c +++ b/src/database.c @@ -24,6 +24,7 @@ static JSValue _database_get(JSContext* context, JSValueConst this_val, int argc static JSValue _database_set(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); void tf_database_init(JSContext* context, sqlite3* sqlite) { JS_NewClassID(&_database_class_id); @@ -65,6 +66,7 @@ static JSValue _database_create(JSContext* context, JSValueConst this_val, int a JS_SetPropertyStr(context, object, "set", JS_NewCFunction(context, _database_set, "set", 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)); return object; } @@ -152,3 +154,28 @@ JSValue _database_get_all(JSContext* context, JSValueConst this_val, int argc, J } return array; } + +JSValue _database_get_like(JSContext* context, JSValueConst this_val, int argc, JSValueConst* argv) { + JSValue result = JS_UNDEFINED; + database_t* database = JS_GetOpaque(this_val, _database_class_id); + if (database) { + sqlite3_stmt* statement; + if (sqlite3_prepare(database->db, "SELECT key, value FROM properties WHERE id = ? AND KEY LIKE ?", -1, &statement, NULL) == SQLITE_OK) { + const char* pattern = JS_ToCString(context, argv[0]); + if (sqlite3_bind_text(statement, 1, database->id, -1, NULL) == SQLITE_OK && + sqlite3_bind_text(statement, 2, pattern, -1, NULL) == SQLITE_OK) { + result = JS_NewObject(context); + while (sqlite3_step(statement) == SQLITE_ROW) { + JS_SetPropertyStr( + context, + result, + (const char*)sqlite3_column_text(statement, 0), + JS_NewStringLen(context, (const char*)sqlite3_column_text(statement, 1), sqlite3_column_bytes(statement, 1))); + } + } + JS_FreeCString(context, pattern); + sqlite3_finalize(statement); + } + } + return result; +}