| 586 | } |
| 587 | |
| 588 | Status FunctionDelete(engine::Context &ctx, redis::Connection *conn, const std::string &name) { |
| 589 | auto lua = conn->Owner()->Lua(); |
| 590 | |
| 591 | // load the library into this lua state |
| 592 | if (!FunctionIsLibExist(conn, &ctx, name, true)) { |
| 593 | return {Status::NotOK, "the library does not exist in lua environment"}; |
| 594 | } |
| 595 | |
| 596 | lua_getglobal(lua, REDIS_FUNCTION_LIBRARIES); |
| 597 | if (lua_isnil(lua, -1)) { |
| 598 | lua_pop(lua, 1); |
| 599 | return {Status::NotOK, "the library does not exist in lua environment"}; |
| 600 | } |
| 601 | |
| 602 | lua_getfield(lua, -1, name.c_str()); |
| 603 | if (lua_isnil(lua, -1)) { |
| 604 | lua_pop(lua, 2); |
| 605 | return {Status::NotOK, "the library does not exist in lua environment"}; |
| 606 | } |
| 607 | |
| 608 | auto storage = conn->GetServer()->storage; |
| 609 | auto cf = storage->GetCFHandle(ColumnFamilyID::Propagate); |
| 610 | |
| 611 | for (size_t i = 1; i <= lua_objlen(lua, -1); ++i) { |
| 612 | lua_rawgeti(lua, -1, static_cast<int>(i)); |
| 613 | std::string func = lua_tostring(lua, -1); |
| 614 | auto _ = storage->Delete(ctx, rocksdb::WriteOptions(), cf, engine::kLuaFuncLibPrefix + func); |
| 615 | lua_pop(lua, 1); |
| 616 | } |
| 617 | |
| 618 | lua_pop(lua, 2); |
| 619 | |
| 620 | auto s = storage->Delete(ctx, rocksdb::WriteOptions(), cf, engine::kLuaLibCodePrefix + name); |
| 621 | if (!s.ok()) return {Status::NotOK, s.ToString()}; |
| 622 | |
| 623 | // reset all lua context from all workers |
| 624 | // to ensure the library is removed from all lua states |
| 625 | // TODO: optimize it to only delete this library |
| 626 | // instead of resetting all libraries |
| 627 | conn->GetServer()->ScriptReset(); |
| 628 | |
| 629 | return Status::OK(); |
| 630 | } |
| 631 | |
| 632 | Status FunctionFlush(redis::Connection *conn, engine::Context *ctx) { |
| 633 | auto storage = conn->GetServer()->storage; |
no test coverage detected