use crate::c_ptr;
use crate::error::{Error, TarantoolError};
use crate::ffi::lua;
use crate::ffi::tarantool::luaT_call;
use crate::index::{Index, IndexOptions};
use tlua::AsLua as _;
use tlua::{
LuaError::{self, ExecutionError},
LuaFunction, LuaTable,
};
pub fn create_index(space_id: u32, index_name: &str, opts: &IndexOptions) -> Result<Index, Error> {
let lua = crate::lua_state();
let b: LuaTable<_> = lua
.get("box")
.ok_or_else(|| ExecutionError("box == nil".into()))?;
let b_schema: LuaTable<_> = b
.get("schema")
.ok_or_else(|| ExecutionError("box.schema == nil".into()))?;
let b_s_index: LuaTable<_> = b_schema
.get("index")
.ok_or_else(|| ExecutionError("box.schema.index == nil".into()))?;
let index_create: LuaFunction<_> = b_s_index
.get("create")
.ok_or_else(|| ExecutionError("box.schema.index.create == nil".into()))?;
let new_index: LuaTable<_> = index_create
.call_with_args((space_id, index_name, opts))
.map_err(LuaError::from)?;
let index_id: u32 = new_index.get("id").ok_or_else(|| {
ExecutionError(format!("box.space[{space_id}].index['{index_name}'] == nil").into())
})?;
Ok(Index::new(space_id, index_id))
}
pub fn drop_index(space_id: u32, index_id: u32) -> Result<(), Error> {
unsafe {
let lua = crate::lua_state();
let drop_state = lua.as_lua();
lua::lua_getglobal(drop_state, c_ptr!("box"));
lua::lua_getfield(drop_state, -1, c_ptr!("space"));
lua::lua_getfield(drop_state, -1, c_ptr!("_space"));
lua::lua_getfield(drop_state, -1, c_ptr!("get"));
lua::lua_pushvalue(drop_state, -2);
lua::lua_pushinteger(drop_state, space_id as isize);
if luaT_call(drop_state, 2, 1) == 1 {
return Err(TarantoolError::last().into());
}
lua::lua_getfield(drop_state, -1, c_ptr!("name"));
let space_name = lua::lua_tostring(drop_state, -1);
lua::lua_remove(drop_state, -1);
lua::lua_getglobal(drop_state, c_ptr!("box"));
lua::lua_getfield(drop_state, -1, c_ptr!("space"));
lua::lua_getfield(drop_state, -1, c_ptr!("_index"));
lua::lua_getfield(drop_state, -1, c_ptr!("get"));
lua::lua_pushvalue(drop_state, -2);
lua::lua_newtable(drop_state);
lua::lua_pushinteger(drop_state, 1);
lua::lua_pushinteger(drop_state, space_id as isize);
lua::lua_settable(drop_state, -3);
lua::lua_pushinteger(drop_state, 2);
lua::lua_pushinteger(drop_state, index_id as isize);
lua::lua_settable(drop_state, -3);
if luaT_call(drop_state, 2, 1) == 1 {
return Err(TarantoolError::last().into());
}
lua::lua_getfield(drop_state, -1, c_ptr!("name"));
let index_name = lua::lua_tostring(drop_state, -1);
lua::lua_remove(drop_state, -1);
lua::lua_getglobal(drop_state, c_ptr!("box"));
lua::lua_getfield(drop_state, -1, c_ptr!("space"));
lua::lua_getfield(drop_state, -1, space_name);
lua::lua_getfield(drop_state, -1, c_ptr!("index"));
lua::lua_getfield(drop_state, -1, index_name);
lua::lua_getfield(drop_state, -1, c_ptr!("drop"));
lua::lua_pushvalue(drop_state, -2);
if luaT_call(drop_state, 1, 1) == 1 {
return Err(TarantoolError::last().into());
}
}
Ok(())
}