From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org Cc: "v.shpilevoy@tarantool.org" <v.shpilevoy@tarantool.org> Subject: [tarantool-patches] Re: [PATCH v2 1/1] schema:frommap() to create table or tuple Date: Mon, 2 Apr 2018 13:26:46 +0300 [thread overview] Message-ID: <7a5c0afb-c030-fcd2-7d86-5c92cd7fa850@tarantool.org> (raw) In-Reply-To: <E68C0BD2-2BE8-4549-B784-0BE23AAFC51C@tarantool.org> Comments accounted. On 29.03.2018 13:14, v.shpilevoy@tarantool.org wrote: > See below 10 comments. > >> diff --git a/src/box/lua/space.cc >> <http://space.cc> b/src/box/lua/space.cc <http://space.cc> >> index 29a9aca..a8cfb14 100644 >> --- a/src/box/lua/space.cc <http://space.cc> >> +++ b/src/box/lua/space.cc <http://space.cc> >> @@ -32,6 +32,7 @@ >> #include "box/lua/tuple.h" >> #include "lua/utils.h" >> #include "lua/trigger.h" >> +#include "box/schema.h" >> >> extern "C" { >> #include <lua.h> >> @@ -174,6 +175,16 @@ lbox_fillspace(struct lua_State *L, struct space >> *space, int i) >> lua_pushstring(L, space->def->engine_name); >> lua_settable(L, i); >> >> +/* space.schema_version */ >> +lua_pushstring(L, "schema_version"); >> +luaL_pushuint64(L, box_schema_version()); >> +lua_settable(L, i); > > 1. Lets name it '_schema_version' - it is internal field. > >> + >> +/* space._space */ >> +lua_pushstring(L, "_space"); >> +lua_pushlightuserdata(L, space); >> +lua_settable(L, i); > > 2. Please, find a better name for the pointer. For example, 'ptr' - then it > will be accessed as space.ptr, that looks slightly better than space._space. > >> +static int >> +lbox_space_ptr_cached(struct lua_State *L) >> +{ > diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 740b885..c2645f7 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -1420,7 +1420,7 @@ function box.schema.space.bless(space) builtin.space_run_triggers(s, yesno) end space_mt.frommap = box.internal.space.frommap - space_mt._ptr = box.internal.space._ptr + space_mt._cptr = box.internal.space._cptr space_mt.__index = space_mt setmetatable(space, space_mt) diff --git a/src/box/lua/space.cc b/src/box/lua/space.cc index 42eaf79..f8583a2 100644 --- a/src/box/lua/space.cc +++ b/src/box/lua/space.cc @@ -176,12 +176,12 @@ lbox_fillspace(struct lua_State *L, struct space *space, int i) lua_settable(L, i); /* space.schema_version */ - lua_pushstring(L, "schema_version"); + lua_pushstring(L, "_schema_version"); luaL_pushuint64(L, box_schema_version()); lua_settable(L, i); - /* space._space */ - lua_pushstring(L, "_space"); + /* space._cptr */ + lua_pushstring(L, "_cptr"); lua_pushlightuserdata(L, space); lua_settable(L, i); > 3. Add a comment, what this function does, why, and what arguments on a > stack > it expects, what and home many values returns. > >> +// take care about stack to call this function in frommap directly >> +lua_getfield(L, 1, "schema_version"); > > 4. A comment seems to be not linked with the code below. And please, do not > use '//' comments. In our code we use '/* ... */' for comments inside a > function. Note, that comment max length is 66 symbols, including indentation > before a comment. > >> + >> +void *space = nullptr; >> +if (schema_version == global_shema_version) { >> + > > 5. Do not use nullptr. Everywhere in Tarantool code only NULL is used. > >> +bool tuple = false; > > 6. Lets return tuple by default, and name the option 'table' instead of > tuple. If a user wants a table, then he must pass the option {table = true}. > >> +if (argc == 3) { >> +if (!lua_istable(L, 3)) >> +goto error; >> +lua_getfield(L, 3, "tuple"); >> +if (!lua_isboolean(L, -1) && !lua_isnil(L, -1)) >> +goto error; >> +tuple = lua_toboolean(L, -1); >> +} >> + > > 7. Double tabs prior to 'goto error'. > >> +if (tuple_fieldno_by_name(dict, key, key_len, key_hash, &fieldno)) >> +luaL_error(L, "Unknown field '%s'", key); > > 8. According to our Lua error returning convention, you can raise an > error either > on incorrect usage (bad argument type, for example), or on OOM(Out Of > Memory) > errors. On other errors you must return two values: nil and error object or > description. In this example you must return nil and "Unknown field > '%s'" string. > >> +lua_replace(L, 1); >> +lua_settop(L, 1); >> +return lbox_tuple_new(L); @@ -397,56 +397,66 @@ static struct trigger on_alter_space_in_lua = { RLIST_LINK_INITIALIZER, box_lua_space_new_or_delete, NULL, NULL }; +/** + * Get a C pointer for space structure. + * Caches the result. Cleans the user(negative) stack itself. + * @param Lua space object at top of the Lua stack + * @return C structure pointer + */ static int lbox_space_ptr_cached(struct lua_State *L) { if (lua_gettop(L) < 1 || !lua_istable(L, 1)) - luaL_error(L, "Usage: space:_ptr_cached()"); + luaL_error(L, "Usage: space:_cptr()"); - // take care about stack to call this function in frommap directly - lua_getfield(L, 1, "schema_version"); + lua_getfield(L, 1, "_schema_version"); uint64_t schema_version = luaL_touint64(L, -1); lua_pop(L, 1); uint64_t global_shema_version = box_schema_version(); - void *space = nullptr; + void *space = NULL; if (schema_version == global_shema_version) { - lua_getfield(L, 1, "_space"); + lua_getfield(L, 1, "_cptr"); space = (void *)lua_topointer(L, -1); - lua_pop(L, 1); } else { lua_getfield(L, 1, "id"); uint32_t id = luaL_touint64(L, -1); - lua_pop(L, 1); space = space_by_id(id); + /** update the cache */ luaL_pushuint64(L, global_shema_version); - lua_setfield(L, 1, "schema_version"); - + lua_setfield(L, 1, "_schema_version"); lua_pushlightuserdata(L, space); - lua_setfield(L, 1, "_space"); + lua_setfield(L, 1, "_cptr"); } - + lua_pop(L, 1); lua_pushlightuserdata(L, space); return 1; } +/** + * Make a tuple or a table Lua object by map + * @param Lua space object + * @param Lua map table object + * @param Lua opts table object (optional) + * @return C structure pointer + */ static int lbox_space_frommap(struct lua_State *L) { - struct tuple_dictionary *dict = nullptr; - struct space *space = nullptr; + struct tuple_dictionary *dict = NULL; + struct space *space = NULL; int argc = lua_gettop(L); - bool tuple = false; + bool table = false; if (argc < 2 || argc > 3 || !lua_istable(L, 2)) goto error; if (argc == 3) { if (!lua_istable(L, 3)) - goto error; - lua_getfield(L, 3, "tuple"); + goto error; + lua_getfield(L, 3, "table"); if (!lua_isboolean(L, -1) && !lua_isnil(L, -1)) - goto error; - tuple = lua_toboolean(L, -1); + goto error; + table = lua_toboolean(L, -1); } lbox_space_ptr_cached(L); @@ -461,11 +471,14 @@ lbox_space_frommap(struct lua_State *L) size_t key_len; const char *key = lua_tolstring(L, -2, &key_len); uint32_t key_hash = lua_hashstring(L, -2); - if (tuple_fieldno_by_name(dict, key, key_len, key_hash, &fieldno)) - luaL_error(L, "Unknown field '%s'", key); + if (tuple_fieldno_by_name(dict, key, key_len, key_hash, &fieldno)) { + lua_pushnil(L); + lua_pushstring(L, "Unknown field"); + return 2; + } lua_rawseti(L, -3, fieldno+1); } - if (!tuple) + if (table) return 1; lua_replace(L, 1); @@ -557,7 +570,7 @@ box_lua_space_init(struct lua_State *L) static const struct luaL_Reg space_internal_lib[] = { {"frommap", lbox_space_frommap}, - {"_ptr", lbox_space_ptr_cached}, + {"_cptr", lbox_space_ptr_cached}, {NULL, NULL} }; luaL_register(L, "box.internal.space", space_internal_lib); > > 9. How about a comment what is happening here? > > 10. Add a test on nil and box.NULL fields. And test, that a result of > frommap() actually can be inserted or replaced into a space. > > diff --git a/test/box/space_frommap.result b/test/box/space_frommap.result index 884d78c..7a4b3db 100644 --- a/test/box/space_frommap.result +++ b/test/box/space_frommap.result @@ -29,21 +29,16 @@ subscriber = box.schema.space.create('subscriber', {format = format}) ... subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}) --- -- - 2 - - 4 - - 3 - - 1 +- [2, 4, 3, 1] ... subscriber:frommap({ddd = 1, aaa = 2, bbb = 3}) --- -- - 2 - - 3 - - null - - 1 +- [2, 3, null, 1] ... subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, eee = 4}) --- -- error: Unknown field 'eee' +- null +- Unknown field ... subscriber:frommap() --- @@ -53,23 +48,34 @@ subscriber:frommap({}) --- - [] ... -subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {tuple = true}) ---- -- [2, 4, 3, 1] -... -subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {tuple = false}) +subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {table = true}) --- - - 2 - 4 - 3 - 1 ... +subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {table = false}) +--- +- [2, 4, 3, 1] +... +subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = box.NULL}) +--- +- [2, null, 3, 1] +... subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {dummy = true}) --- -- - 2 - - 4 - - 3 - - 1 +- [2, 4, 3, 1] +... +_ = subscriber:create_index('primary', {parts={'aaa'}}) +--- +... +tuple = subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}) +--- +... +subscriber:replace(tuple) +--- +- [2, 4, 3, 1] ... subscriber:drop() --- diff --git a/test/box/space_frommap.test.lua b/test/box/space_frommap.test.lua index 4760b3a..ff7ef98 100644 --- a/test/box/space_frommap.test.lua +++ b/test/box/space_frommap.test.lua @@ -14,7 +14,11 @@ subscriber:frommap({ddd = 1, aaa = 2, bbb = 3}) subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, eee = 4}) subscriber:frommap() subscriber:frommap({}) -subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {tuple = true}) -subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {tuple = false}) +subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {table = true}) +subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {table = false}) +subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = box.NULL}) subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}, {dummy = true}) +_ = subscriber:create_index('primary', {parts={'aaa'}}) +tuple = subscriber:frommap({ddd = 1, aaa = 2, ccc = 3, bbb = 4}) +subscriber:replace(tuple) subscriber:drop()
next prev parent reply other threads:[~2018-04-02 10:26 UTC|newest] Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-03-28 17:51 [tarantool-patches] " Kirill Shcherbatov 2018-03-28 18:28 ` Kirill Shcherbatov 2018-03-29 7:36 ` [tarantool-patches] " Kirill Shcherbatov 2018-03-29 10:14 ` v.shpilevoy 2018-04-02 10:26 ` Kirill Shcherbatov [this message] 2018-04-02 11:19 ` v.shpilevoy 2018-04-02 19:42 ` Kirill Shcherbatov 2018-04-03 9:47 ` Vladislav Shpilevoy 2018-04-04 14:14 ` Kirill Shcherbatov 2018-04-04 16:35 ` [tarantool-patches] " Kirill Shcherbatov 2018-04-04 16:43 ` Vladislav Shpilevoy 2018-04-06 13:47 ` Vladimir Davydov 2018-04-06 15:44 ` [tarantool-patches] " Konstantin Osipov 2018-04-09 8:30 ` Kirill Shcherbatov 2018-04-09 10:44 ` Vladislav Shpilevoy 2018-04-09 17:23 ` Kirill Shcherbatov 2018-04-09 17:45 ` Vladislav Shpilevoy 2018-04-10 10:31 ` Vladimir Davydov
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=7a5c0afb-c030-fcd2-7d86-5c92cd7fa850@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='[tarantool-patches] Re: [PATCH v2 1/1] schema:frommap() to create table or tuple' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox