예제 #1
0
 void ExpireCheck::ExpireCheckCallback(const DBID& db, const Slice& key, void* data)
 {
     ExpireCheck* e = (ExpireCheck*) data;
     ArgumentArray args;
     args.push_back("del");
     args.push_back(std::string(key.data(), key.size()));
     RedisCommandFrame cmd(args);
     e->m_server->GetMaster().FeedSlaves(NULL, db, cmd);
 }
예제 #2
0
파일: master.cpp 프로젝트: kouhate/ardb
				int OnRawKeyValue(const Slice& key, const Slice& value)
				{
					ArgumentArray args;
					args.push_back("__SET__");
					args.push_back(std::string(key.data(), key.size()));
					args.push_back(std::string(value.data(), value.size()));
					RedisCommandFrame cmd(args);
					conn.conn->Write(cmd);
					count++;
					if (count % 10000 == 0)
					{
						conn.conn->GetService().Continue();
					}
					return 0;
				}
예제 #3
0
 inline void FillNextArgument(Buffer& buf, size_t len)
 {
     const char* str = buf.GetRawReadBuffer();
     buf.AdvanceReadIndex(len);
     if (m_cmd_seted)
     {
         m_args.push_back(std::string(str, len));
     }
     else
     {
         m_cmd.append(str, len);
         m_cmd_seted = true;
     }
 }
예제 #4
0
 RedisCommandFrame(const char* fmt, ...) :
         type(REDIS_CMD_INVALID), m_is_inline(false), m_cmd_seted(false), m_raw_data_size(0)
 {
     va_list ap;
     va_start(ap, fmt);
     char buf[1024];
     vsnprintf(buf, sizeof(buf) - 1, fmt, ap);
     va_end(ap);
     char * pch;
     pch = strtok(buf, " ");
     while (pch != NULL)
     {
         m_args.push_back(std::string(pch));
         pch = strtok(NULL, " ");
     }
     m_cmd = m_args.front();
     m_args.pop_front();
 }
예제 #5
0
Command::ArgumentArray Command::getEffectiveArguments() const {
	uint effectiveArgumentsStart;
	switch (_subTypeDesc->controlFlowType) {
		case kFlowEnd:
			effectiveArgumentsStart = 0;
			break;
		case kFlowNormal:
			effectiveArgumentsStart = 1;
			break;
		case kFlowBranch:
			effectiveArgumentsStart = 2;
			break;
		default:
			error("Unhandled control flow type '%d'", _subTypeDesc->controlFlowType);
	}

	ArgumentArray effectiveArguments;
	for (uint i = effectiveArgumentsStart; i < _arguments.size(); i++) {
		effectiveArguments.push_back(_arguments[i]);
	}

	return  effectiveArguments;
}
예제 #6
0
    int LUAInterpreter::CallArdb(lua_State *lua, bool raise_error)
    {
        int j, argc = lua_gettop(lua);
        ArgumentArray cmdargs;

        /* Require at least one argument */
        if (argc == 0)
        {
            luaPushError(lua, "Please specify at least one argument for redis.call()");
            return 1;
        }

        /* Build the arguments vector */
        for (j = 0; j < argc; j++)
        {
            if (!lua_isstring(lua, j + 1))
                break;
            std::string arg;
            arg.append(lua_tostring(lua, j + 1), lua_strlen(lua, j + 1));
            cmdargs.push_back(arg);
        }

        /* Check if one of the arguments passed by the Lua script
         * is not a string or an integer (lua_isstring() return true for
         * integers as well). */
        if (j != argc)
        {
            luaPushError(lua, "Lua redis() command arguments must be strings or integers");
            return 1;
        }

        /* Setup our fake client for command execution */

        RedisCommandFrame cmd(cmdargs);
        Ardb::RedisCommandHandlerSetting* setting = g_db->FindRedisCommandHandlerSetting(cmd);
        /* Command lookup */
        if (NULL == setting)
        {
            luaPushError(lua, "Unknown Redis command called from Lua script");
            return -1;
        }

        /* There are commands that are not allowed inside scripts. */
        if (!setting->IsAllowedInScript())
        {
            luaPushError(lua, "This Redis command is not allowed from scripts");
            return -1;
        }
        LuaExecContext* ctx = g_lua_exec_ctx.GetValue();

        /* Write commands are forbidden against read-only slaves, or if a
         * command marked as non-deterministic was already called in the context
         * of this script. */
        if (setting->IsWriteCommand())
        {
            if (!g_db->GetConf().master_host.empty() && g_db->GetConf().slave_readonly && !g_db->IsLoadingData() && !(ctx->caller->flags.slave))
            {
                luaPushError(lua, "-READONLY You can't write against a read only slave.");
                return -1;
            }
        }

        Context& lua_ctx = ctx->exec;
        RedisReply& reply = lua_ctx.GetReply();
        reply.Clear();
        lua_ctx.ClearFlags();
        lua_ctx.flags.lua = 1;
        g_db->DoCall(lua_ctx, *setting, cmd);
        if (raise_error && reply.type != REDIS_REPLY_ERROR)
        {
            raise_error = 0;
        }
        redisProtocolToLuaType(lua, reply);

        if (raise_error)
        {
            /* If we are here we should have an error in the stack, in the
             * form of a table with an "err" field. Extract the string to
             * return the plain error. */
            lua_pushstring(lua, "err");
            lua_gettable(lua, -2);
            return lua_error(lua);
        }
        return 1;
    }