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 2/2] schema: expose space_mt and index_mt on `box.schema` table Date: Sun, 1 Apr 2018 14:02:46 +0300 [thread overview] Message-ID: <95fd6df65760120d64d3dc7cd4f2c2c322ff76ff.1522580337.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1522580337.git.v.shpilevoy@tarantool.org> In-Reply-To: <cover.1522580337.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. Closes #3204 --- src/box/lua/schema.lua | 21 ++++++++--- test/box-tap/schema_mt.test.lua | 79 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 5 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 8b6f69ad8..6e325a5c5 100644 --- a/src/box/lua/schema.lua +++ b/src/box/lua/schema.lua @@ -1075,6 +1075,7 @@ end internal.check_iterator_type = check_iterator_type -- export for net.box local index_mt = {} +box.schema.index_mt = index_mt -- __len and __index index_mt.len = function(index) check_index_arg(index, 'len') @@ -1289,6 +1290,7 @@ index_mt.alter = function(index, options) end local space_mt = {} +box.schema.space_mt = space_mt space_mt.len = function(space) check_space_arg(space, 'len') local pk = space.index[0] @@ -1409,18 +1411,27 @@ end space_mt.__index = space_mt function box.schema.space.bless(space) - local index_mt = table.deepcopy(index_mt) - local space_mt = table.deepcopy(space_mt) + -- At first, reference all global index functions. At second, + -- choose an implementation for read operations. They are not + -- in a global index_mt, because they are engine specific. + -- All common index_mt functions must be referenced here to + -- be able to get them using getmetatable(index_object) - if + -- they are only in index_mt, then getmetatable() returns only + -- read ops. + local local_index_mt = table.deepcopy(index_mt) + local_index_mt.__index = function(index, key) + return local_index_mt[key] or index_mt[key] + end -- true if reading operations may yield local read_yields = space.engine == 'vinyl' local read_ops = {'select', 'get', 'min', 'max', 'count', 'random', 'pairs'} for _, op in ipairs(read_ops) do if read_yields then -- use Lua/C implmenetation - index_mt[op] = index_mt[op .. "_luac"] + local_index_mt[op] = index_mt[op .. "_luac"] else -- use FFI implementation - index_mt[op] = index_mt[op .. "_ffi"] + local_index_mt[op] = index_mt[op .. "_ffi"] end end index_mt.__pairs = index_mt.pairs -- Lua 5.2 compatibility @@ -1430,7 +1441,7 @@ function box.schema.space.bless(space) if type(space.index) == 'table' and space.enabled then for j, index in pairs(space.index) do if type(j) == 'number' then - setmetatable(index, index_mt) + setmetatable(index, local_index_mt) end end end diff --git a/test/box-tap/schema_mt.test.lua b/test/box-tap/schema_mt.test.lua new file mode 100755 index 000000000..096c4ad60 --- /dev/null +++ b/test/box-tap/schema_mt.test.lua @@ -0,0 +1,79 @@ +#!/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(7) + +box.cfg{ + log="tarantool.log", +} + +local sp1 = box.schema.space.create('test') +local sp2 = box.schema.space.create('test2') + +test:is( + getmetatable(sp1), + getmetatable(sp2), + 'all spaces use the same metatable' +) + +local idx1 = sp1:create_index('primary') +local idx2 = sp2:create_index('primary') + +test:isnt( + getmetatable(idx1), + getmetatable(idx2), + 'all indexes have their own metatable' +) + +test:is( + idx1.get, + idx2.get, + 'memtx indexes share read methods' +) + +local sp3 = box.schema.space.create('test3', {engine='vinyl'}) +local sp4 = box.schema.space.create('test4', {engine='vinyl'}) + +local idx3 = sp3:create_index('primary') +local idx4 = sp4:create_index('primary') + +test:is( + idx3.get, + idx4.get, + 'vinyl indexes share read methods' +) + +test:isnt( + idx1.get, + idx3.get, + 'memtx and vinyl indexes have separate read methods' +) + +function box.schema.space_mt.foo() end + +test:is( + sp1.foo, + box.schema.space_mt.foo, + 'box.schema.space_mt is mutable' +) + +function box.schema.index_mt.foo() end + +test:is( + idx1.foo, + box.schema.index_mt.foo, + 'box.schema.index_mt is mutable' +) + +test:check() + +sp1:drop() +sp2:drop() +sp3:drop() +sp4:drop() +os.exit(0) -- 2.14.3 (Apple Git-98)
next prev parent reply other threads:[~2018-04-01 11:02 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 ` Vladislav Shpilevoy [this message] 2018-04-02 11:28 ` [PATCH 2/2] schema: expose space_mt and index_mt on `box.schema` table 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 ` [PATCH v2 3/3] schema: expose space_mt and index_mt on box.schema table Vladislav Shpilevoy 2018-05-05 12:47 ` [tarantool-patches] " 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=95fd6df65760120d64d3dc7cd4f2c2c322ff76ff.1522580337.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=vdavydov.dev@gmail.com \ --subject='Re: [PATCH 2/2] 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