From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@freelists.org Cc: vdavydov.dev@gmail.com, Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Subject: [PATCH v2 3/3] schema: expose space_mt and index_mt on box.schema table Date: Tue, 3 Apr 2018 19:50:47 +0300 [thread overview] Message-ID: <8053011f0e2036fdb811dd7ad6097ccc150b76d0.1522774214.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1522774214.git.v.shpilevoy@tarantool.org> In-Reply-To: <cover.1522774214.git.v.shpilevoy@tarantool.org> This commit allows userland to extend the space and index metatables with their own functions or even metamethods. Reducing barriers for this kind of experimentation is vital for user contribution toward the improvement of Tarantool's API. There are 4 metatables available for extending: box.schema.space_mt - metatable of all spaces; box.schema.index_mt - base metatable of all indexes - replicated into the vinyl and memtx. See below how. box.schema.vinyl_index_mt - metatable of all vinyl indexes; box.schema.memtx_index_mt - metatable of all memtx indexes. Closes #3204 --- src/box/lua/schema.lua | 17 +++++---- test/box-tap/schema_mt.test.lua | 80 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+), 9 deletions(-) create mode 100755 test/box-tap/schema_mt.test.lua diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua index 4b5eeeda9..5d5b0dc49 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -1074,10 +1074,6 @@ end internal.check_iterator_type = check_iterator_type -- export for net.box -local function forbid_new_index(t, k, v) - return error('Attempt to modify a read-only table') -end - local base_index_mt = {} base_index_mt.__index = base_index_mt -- @@ -1098,6 +1094,7 @@ setmetatable(base_index_mt, { rawset(t, k, v) end }) + -- __len and __index base_index_mt.len = function(index) check_index_arg(index, 'len') @@ -1118,7 +1115,6 @@ base_index_mt.bsize = function(index) end -- Lua 5.2 compatibility base_index_mt.__len = base_index_mt.len -base_index_mt.__newindex = forbid_new_index -- min and max base_index_mt.min_ffi = function(index, key) check_index_arg(index, 'min') @@ -1345,7 +1341,6 @@ space_mt.bsize = function(space) end return builtin.space_bsize(s) end -space_mt.__newindex = forbid_new_index space_mt.get = function(space, key) check_space_arg(space, 'get') @@ -1440,13 +1435,17 @@ space_mt.run_triggers = function(space, yesno) end space_mt.__index = space_mt +box.schema.index_mt = base_index_mt +box.schema.memtx_index_mt = memtx_index_mt +box.schema.vinyl_index_mt = vinyl_index_mt +box.schema.space_mt = space_mt + function box.schema.space.bless(space) - local space_mt = table.deepcopy(space_mt) local index_mt if space.engine == 'vinyl' then - index_mt = table.deepcopy(vinyl_index_mt) + index_mt = vinyl_index_mt else - index_mt = table.deepcopy(memtx_index_mt) + index_mt = memtx_index_mt end setmetatable(space, space_mt) diff --git a/test/box-tap/schema_mt.test.lua b/test/box-tap/schema_mt.test.lua new file mode 100755 index 000000000..b785b8e21 --- /dev/null +++ b/test/box-tap/schema_mt.test.lua @@ -0,0 +1,80 @@ +#!/usr/bin/env tarantool +-- +-- pr-3204: expose space_mt, index_mt into box.schema. +-- + +local tap = require('tap') +local test = tap.test('schema_mt') + +test:plan(18) + +box.cfg{ + log="tarantool.log", +} + +-- +-- Check that space metatable is shared between all spaces, +-- regardless of engine. +-- +local sp1 = box.schema.create_space('test1', {engine = 'memtx'}) +local sp2 = box.schema.create_space('test2', {engine = 'vinyl'}) +test:is(getmetatable(sp1), getmetatable(sp2), 'spaces share metatables') + +function box.schema.space_mt.myfunc(space, args) + return args +end +test:is(sp1:myfunc(123), 123, 'space_mt can be extended') +test:is(sp1.myfunc, sp2.myfunc, 'space_mt can be extended') + +-- +-- Check that index metatable is shared in a scope of an engine. +-- +local sp1_pk = sp1:create_index('pk') +local sp1_sk = sp1:create_index('sk') +local sp2_pk = sp2:create_index('pk') +local sp2_sk = sp2:create_index('sk') +test:is(getmetatable(sp1_pk), getmetatable(sp1_sk), 'memtx indexes share metatables') +test:is(getmetatable(sp2_pk), getmetatable(sp2_sk), 'vinyl indexes share metatables') +test:isnt(getmetatable(sp1_pk), getmetatable(sp2_pk), 'engines do not share metatables') + +-- +-- Check that there are two ways to extend index metatable: +-- extend base index metatable, or extend engine specific. +-- +function box.schema.index_mt.common_func(index, args) + return args +end +function box.schema.vinyl_index_mt.vinyl_func(index, args) + return args +end +function box.schema.memtx_index_mt.memtx_func(index, args) + return args +end +test:is(box.schema.index_mt.common_func, box.schema.vinyl_index_mt.common_func, + 'base index_mt is replicated into vinyl index_mt') +test:is(box.schema.index_mt.common_func, box.schema.memtx_index_mt.common_func, + 'base index_mt is replicated into memtx index_mt') +test:is(box.schema.index_mt.vinyl_func, nil, 'vinyl index_mt is not replicated') +test:is(box.schema.index_mt.memtx_func, nil, 'memtx index_mt is not replicated') + +test:is(sp1_pk.common_func, box.schema.index_mt.common_func, + 'new common methods are visible in memtx index') +test:is(sp2_pk.common_func, box.schema.index_mt.common_func, + 'new common methods are visible in vinyl index') + +test:is(sp1_pk.memtx_func, box.schema.memtx_index_mt.memtx_func, + 'new memtx methods are visible in memtx index') +test:is(sp2_pk.vinyl_func, box.schema.vinyl_index_mt.vinyl_func, + 'new vinyl methods are visible in vinyl index') + +test:is(sp1_pk:memtx_func(100), 100, 'memtx local methods work') +test:is(sp1_sk:common_func(200), 200, 'memtx common methods work') +test:is(sp2_pk:vinyl_func(300), 300, 'vinyl local methods work') +test:is(sp2_sk:common_func(400), 400, 'vinyl common methods work') + +sp1:drop() +sp2:drop() + +test:check() + +os.exit(0) -- 2.14.3 (Apple Git-98)
next prev parent reply other threads:[~2018-04-03 16:50 UTC|newest] Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-03-23 13:07 [PATCH 0/2] schema: expose space_mt and index_mt on table Vladislav Shpilevoy 2018-03-23 13:07 ` [PATCH 1/2] schema: expose space_mt and index_mt on `box.schema` table Vladislav Shpilevoy 2018-03-23 13:07 ` [PATCH 2/2] schema: review fixes for box.schema.space/index metatables Vladislav Shpilevoy 2018-03-29 10:54 ` [PATCH 0/2] schema: expose space_mt and index_mt on table Vladimir Davydov 2018-03-29 14:31 ` [PATCH v2 0/2] schema: expose space_mt and index_mt on box.schema table Vladislav Shpilevoy 2018-03-29 14:31 ` [PATCH v2 1/2] schema: move space_mt and index_mt definition out of space bless Vladislav Shpilevoy 2018-04-01 9:33 ` Vladimir Davydov 2018-04-01 11:02 ` [PATCH 0/2] schema: expose space_mt and index_mt on box.schema table Vladislav Shpilevoy 2018-04-01 11:02 ` [PATCH 1/2] schema: move space_mt and index_mt definition out of space bless Vladislav Shpilevoy 2018-04-01 11:02 ` [PATCH 2/2] schema: expose space_mt and index_mt on `box.schema` table Vladislav Shpilevoy 2018-04-02 11:28 ` Vladimir Davydov 2018-04-03 16:50 ` [PATCH v2 0/3] schema: expose space_mt and index_mt on box.schema table Vladislav Shpilevoy 2018-04-03 16:50 ` [PATCH v2 1/3] schema: move space_mt and index_mt definition out of space bless Vladislav Shpilevoy 2018-04-03 16:50 ` [PATCH v2 2/3] schema: inherit vinyl/memtx_index_mt from base index mt Vladislav Shpilevoy 2018-04-03 16:50 ` Vladislav Shpilevoy [this message] 2018-05-05 12:47 ` [tarantool-patches] Re: [PATCH v2 3/3] schema: expose space_mt and index_mt on box.schema table Vladislav Shpilevoy 2018-05-08 16:48 ` Konstantin Osipov 2018-05-08 17:33 ` Vladislav Shpilevoy 2018-03-29 14:31 ` [PATCH v2 2/2] schema: expose space_mt and index_mt on `box.schema` table Vladislav Shpilevoy 2018-04-01 9:37 ` [PATCH v2 0/2] schema: expose space_mt and index_mt on box.schema table 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=8053011f0e2036fdb811dd7ad6097ccc150b76d0.1522774214.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=vdavydov.dev@gmail.com \ --subject='Re: [PATCH v2 3/3] schema: expose space_mt and index_mt on box.schema table' \ /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