From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtpng2.m.smailru.net (smtpng2.m.smailru.net [94.100.179.3]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dev.tarantool.org (Postfix) with ESMTPS id 61EE546970E for ; Tue, 28 Jan 2020 15:50:46 +0300 (MSK) From: Chris Sosnin Date: Tue, 28 Jan 2020 15:50:43 +0300 Message-Id: <2da617affc8e5f94e6b4b9b4d6126d5fcd0c6c1b.1580215539.git.k.sosnin@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Subject: [Tarantool-patches] [PATCH v4 3/3] box: provide a user friendly frontend for accessing session settings List-Id: Tarantool development patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: v.shpilevoy@tarantool.org, tarantool-patches@dev.tarantool.org - space_object:update() is hard to use for configuring session settings, so we provide box.session.setting table, which can be used in a much more native way. - Prior to this patch sql settings were not accessible before box.cfg() call, even though these flags can be set right after session creation. Part of #4711 --- src/box/lua/session.c | 106 ++++++++++++++++++ src/box/sql.c | 5 - ...1-access-settings-from-any-frontend.result | 57 ++++++++++ ...access-settings-from-any-frontend.test.lua | 17 +++ 4 files changed, 180 insertions(+), 5 deletions(-) diff --git a/src/box/lua/session.c b/src/box/lua/session.c index c6a600f6f..3ba1253c7 100644 --- a/src/box/lua/session.c +++ b/src/box/lua/session.c @@ -42,6 +42,9 @@ #include "box/user.h" #include "box/schema.h" #include "box/port.h" +#include "box/session_settings.h" + +extern void sql_session_settings_init(); static const char *sessionlib_name = "box.session"; @@ -411,6 +414,108 @@ lbox_session_on_access_denied(struct lua_State *L) lbox_push_on_access_denied_event, NULL); } +static int +session_setting_serialize(lua_State *L) +{ + lua_getfield(L, -1, "_id"); + int sid = lua_tointeger(L, -1); + const char *mp_pair, *mp_pair_end; + session_settings[sid].get(sid, &mp_pair, &mp_pair_end); + uint32_t len; + mp_decode_array(&mp_pair); /* [setting_name : value] */ + mp_decode_str(&mp_pair, &len); + uint32_t field_type = session_settings[sid].metadata.field_type; + if (field_type == FIELD_TYPE_BOOLEAN) { + bool value = mp_decode_bool(&mp_pair); + lua_pushboolean(L, value); + } else { + const char *str = mp_decode_str(&mp_pair, &len); + lua_pushlstring(L, str, len); + } + return 1; +} + +static int +session_setting_set(lua_State *L) +{ + if (lua_gettop(L) != 2) + goto error; + int arg_type = lua_type(L, -1); + lua_getfield(L, -2, "_id"); + int sid = lua_tointeger(L, -1); + struct session_setting *setting = &session_settings[sid]; + lua_pop(L, 1); + switch (arg_type) { + case LUA_TBOOLEAN: { + bool value = lua_toboolean(L, -1); + size_t size = mp_sizeof_bool(value); + char *mp_value = (char *)region_alloc(&fiber()->gc, + size); + mp_encode_bool(mp_value, value); + if (setting->set(sid, mp_value) != 0) + luaT_error(L); + lua_pushstring(L, setting->name); + lua_pushboolean(L, value); + break; + } + case LUA_TSTRING: { + const char *str = lua_tostring(L, -1); + size_t len = strlen(str); + uint32_t size = mp_sizeof_str(len); + char *mp_value = (char *)region_alloc(&fiber()->gc, + size); + mp_encode_str(mp_value, str, len); + if (setting->set(sid, mp_value) != 0) + luaT_error(L); + lua_pushstring(L, setting->name); + lua_pushstring(L, str); + break; + } + default: + goto error; + } + return 2; +error: + luaL_error(L, "box.session.settings.set(): bad arguments"); + return -1; +} + +static void +session_setting_create(struct lua_State *L, int id) +{ + lua_newtable(L); + lua_pushstring(L, "_id"); + lua_pushinteger(L, id); + lua_settable(L, -3); + lua_newtable(L); /* setting metatable */ + lua_pushstring(L, "__serialize"); + lua_pushcfunction(L, session_setting_serialize); + lua_settable(L, -3); + lua_setmetatable(L, -2); + lua_pushcfunction(L, session_setting_set); + lua_setfield(L, -2, "set"); +} + +void +session_settings_init(struct lua_State *L) +{ + /* Init settings that are avaliable right after session creation. */ + sql_session_settings_init(); + static const struct luaL_Reg settingslib[] = { + {NULL, NULL} + }; + luaL_register_module(L, "box.session.settings", settingslib); + int id = sql_session_setting_BEGIN; + for (; id <= sql_session_setting_END; ++id) { + /* Store settings as name : id */ + struct session_setting *setting = &session_settings[id]; + lua_pushstring(L, setting->name); + session_setting_create(L, id); + lua_settable(L, -3); + } + lua_pop(L, 1); +} + void session_storage_cleanup(int sid) { @@ -448,6 +553,7 @@ exit: void box_lua_session_init(struct lua_State *L) { + session_settings_init(L); static const struct luaL_Reg session_internal_lib[] = { {"create", lbox_session_create}, {"run_on_connect", lbox_session_run_on_connect}, diff --git a/src/box/sql.c b/src/box/sql.c index 1256df856..ba98ce5df 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -64,14 +64,9 @@ static const uint32_t default_sql_flags = SQL_EnableTrigger | SQL_AutoIndex | SQL_RecTriggers; -extern void -sql_session_settings_init(); - void sql_init() { - sql_session_settings_init(); - default_flags |= default_sql_flags; current_session()->sql_flags |= default_sql_flags; diff --git a/test/box/gh-4511-access-settings-from-any-frontend.result b/test/box/gh-4511-access-settings-from-any-frontend.result index f072bafae..1c3ca7661 100644 --- a/test/box/gh-4511-access-settings-from-any-frontend.result +++ b/test/box/gh-4511-access-settings-from-any-frontend.result @@ -298,3 +298,60 @@ s:update('sql_defer_foreign_keys', {{'=', 'value', '1'}}) | --- | - error: Session setting sql_defer_foreign_keys expected a value of type boolean | ... + +-- gh-4711: Provide a user-friendly frontend for accessing session settings. +settings = box.session.settings + | --- + | ... +assert(settings ~= nil) + | --- + | - true + | ... + +s:update('sql_default_engine', {{'=', 2, 'vinyl'}}) + | --- + | - ['sql_default_engine', 'vinyl'] + | ... +settings.sql_default_engine + | --- + | - vinyl + | ... +settings.sql_default_engine:set('memtx') + | --- + | - sql_default_engine + | - memtx + | ... +assert(s:get('sql_default_engine').value == 'memtx') + | --- + | - true + | ... +settings.sql_defer_foreign_keys:set(true) + | --- + | - sql_defer_foreign_keys + | - true + | ... +assert(s:get('sql_defer_foreign_keys').value == true) + | --- + | - true + | ... +s:update('sql_defer_foreign_keys', {{'=', 2, false}}) + | --- + | - ['sql_defer_foreign_keys', false] + | ... +settings.sql_defer_foreign_keys + | --- + | - false + | ... + +settings.sql_default_engine:set(true) + | --- + | - error: Session setting sql_default_engine expected a value of type string + | ... +settings.sql_defer_foreign_keys:set(false, 1, 2, 3) + | --- + | - error: 'box.session.settings.set(): bad arguments' + | ... +settings.sql_parser_debug:set('string') + | --- + | - error: Session setting sql_parser_debug expected a value of type boolean + | ... diff --git a/test/box/gh-4511-access-settings-from-any-frontend.test.lua b/test/box/gh-4511-access-settings-from-any-frontend.test.lua index 40a58ad04..53f03450d 100644 --- a/test/box/gh-4511-access-settings-from-any-frontend.test.lua +++ b/test/box/gh-4511-access-settings-from-any-frontend.test.lua @@ -118,3 +118,20 @@ s:update('sql_defer_foreign_keys', {{'=', 'some text', true}}) s:update('sql_defer_foreign_keys', {{'=', 'value', 1}}) s:update('sql_defer_foreign_keys', {{'=', 'value', {1}}}) s:update('sql_defer_foreign_keys', {{'=', 'value', '1'}}) + +-- gh-4711: Provide a user-friendly frontend for accessing session settings. +settings = box.session.settings +assert(settings ~= nil) + +s:update('sql_default_engine', {{'=', 2, 'vinyl'}}) +settings.sql_default_engine +settings.sql_default_engine:set('memtx') +assert(s:get('sql_default_engine').value == 'memtx') +settings.sql_defer_foreign_keys:set(true) +assert(s:get('sql_defer_foreign_keys').value == true) +s:update('sql_defer_foreign_keys', {{'=', 2, false}}) +settings.sql_defer_foreign_keys + +settings.sql_default_engine:set(true) +settings.sql_defer_foreign_keys:set(false, 1, 2, 3) +settings.sql_parser_debug:set('string') -- 2.21.1 (Apple Git-122.3)