[PATCH v2 2/2] schema: expose space_mt and index_mt on `box.schema` table
Vladislav Shpilevoy
v.shpilevoy at tarantool.org
Thu Mar 29 17:31:45 MSK 2018
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 | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index ff89c8e58..2f85bc541 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -1387,27 +1387,40 @@ function index_mt:alter(options)
end
function box.schema.space.bless(space)
- local space_mt = table.deepcopy(space_mt)
- local index_mt = table.deepcopy(index_mt)
+ local local_index_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.
+ for k, v in pairs(index_mt) do
+ local_index_mt[k] = v
+ end
+ local_index_mt.__index = function(index, key)
+ return local_index_mt[key] or index_mt[key]
+ end
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] = local_index_mt[op .. "_luac"]
else
-- use FFI implementation
- index_mt[op] = index_mt[op .. "_ffi"]
+ local_index_mt[op] = local_index_mt[op .. "_ffi"]
end
end
- index_mt.__pairs = index_mt.pairs -- Lua 5.2 compatibility
- index_mt.__ipairs = index_mt.pairs -- Lua 5.2 compatibility
+ -- Lua 5.2 compatibility
+ local_index_mt.__pairs = local_index_mt.pairs
+ local_index_mt.__ipairs = local_index_mt.pairs
setmetatable(space, space_mt)
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
--
2.14.3 (Apple Git-98)
More information about the Tarantool-patches
mailing list