sql >> Base de Datos >  >> NoSQL >> Redis

¿Conjunto de Redis condicional / solo actualización con la versión más reciente?

Puede escribir un script lua que verifique el valor actual de la clave y lo cambie si el valor difiere del nuevo. He agregado un ejemplo en c de invocar el script lua a través del programa c y hacer el trabajo requerido.

  //g++ -g -o condition condition.cpp  -I/usr/local/include/hiredis -L/usr/local/lib  -levent -lhiredis
/*----------------------
  EVAL
  ------------------------*/

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <hiredis/hiredis.h>

using namespace std;

struct timeval _timeout ;
redisContext *_redisContext;
const long long SEC_TO_USEC = 1000000 ;

void connect(const std::string &ip,
    int port,
    int timeoutInUsec )
{
  _timeout.tv_sec = timeoutInUsec / SEC_TO_USEC ;
  _timeout.tv_usec = timeoutInUsec % SEC_TO_USEC ;

  _redisContext = redisConnectWithTimeout(ip.c_str(), port, _timeout);
  if (_redisContext->err)
  {
    std::cout << "Cannot connect to redis server. "
      << " Error : " << _redisContext->errstr
      << std::endl ;
    exit(1);
  }
}

//lua scrip for conditional set
string scriptMultipleCommands =
"local res = redis.call(\"GET\", KEYS[1])              "
"if res == ARGV[1] then                                "
" return nil                                           "
"else                                                  "
"redis.call(\"SET\", KEYS[1],  ARGV[1])                "
"end                                                   "
"local data = redis.call(\"GET\",KEYS[1])              "
"return data                                           ";

void luaCommand(char** argv)
{
  string command;
  command.append( scriptMultipleCommands );
  redisReply *reply =
    ( redisReply * ) redisCommand( _redisContext,
        "EVAL %s %d %s %s ",command.c_str(),1,argv[1],argv[2]);

  cout<<"Redis reply type "<<reply->type<<endl;

  if (reply->type == REDIS_REPLY_ARRAY)
  {
    cout<<"Redis reply size "<<reply->elements<<endl;
    for (int j = 0; j < reply->elements; j++)
    {
      if((j+1) < reply->elements)
      {
        cout<<(reply->element[j]->str)<<","<<(reply->element[j+1]->str)<<endl;
        ++j;
      }
    }
  }
  else if (reply->type == REDIS_REPLY_INTEGER) {
    cout<<"Key value "<<reply->integer<<endl;
  }
  else
    cout<<endl<<"EVAL: "<< reply->str<<endl;

  freeReplyObject(reply);
}

int main(int argc,char** argv)
{
  connect("10.0.0.30",6379,1500000);
  luaCommand(argv);

  return 0;
}