专栏首页码匠的流水账聊聊claudb的scripting command
原创

聊聊claudb的scripting command

本文主要研究一下claudb的scripting command

AbstractEvalCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/scripting/AbstractEvalCommand.java

abstract class AbstractEvalCommand implements DBCommand {
​
  @Override
  public RedisToken execute(Database db, Request request) {
    return script(request).map(script -> execute(request, script))
        .getOrElse(error("NOSCRIPT No matching script. Please use EVAL"));
  }
​
  private RedisToken execute(Request request, SafeString script) {
    int numParams = parseInt(request.getParam(1).toString());
    if (numParams + 2 > request.getLength()) {
      return error("invalid number of arguments");
    }
    List<SafeString> params = request.getParams().stream().skip(2).collect(toList());
    List<SafeString> keys = readParams(numParams, params);
    List<SafeString> argv = readArguments(numParams, params);
    return LuaInterpreter.buildFor(request).execute(script, keys, argv);
  }
​
  protected abstract Option<SafeString> script(Request request);
​
  private List<SafeString> readParams(int numParams, List<SafeString> params) {
    List<SafeString> keys = new LinkedList<>();
    for (int i = 0; i < numParams; i++) {
      keys.add(params.get(i));
    }
    return keys;
  }
​
  private List<SafeString> readArguments(int numParams, List<SafeString> params) {
    List<SafeString> argv = new LinkedList<>();
    for (int i = numParams; i < params.size(); i++) {
      argv.add(params.get(i));
    }
    return argv;
  }
}
  • AbstractEvalCommand实现了DBCommand接口,其execute方法先通过子类实现的script方法获取SafeString,然后再内部的execute方法执行脚本;execute方法先解析keys、argv,然后通过LuaInterpreter.buildFor(request).execute(script, keys, argv)执行lua脚本

EvalCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/scripting/EvalCommand.java

@Command("eval")
@ParamLength(2)
public class EvalCommand extends AbstractEvalCommand {
​
  @Override
  protected Option<SafeString> script(Request request) {
    return Option.some(request.getParam(0));
  }
}
  • EvalCommand继承了AbstractEvalCommand,其script方法取request.getParam(0)

EvalShaCommand

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/scripting/EvalShaCommand.java

@Command("evalsha")
@ParamLength(2)
public class EvalShaCommand extends AbstractEvalCommand {
​
  @Override
  protected Option<SafeString> script(Request request) {
    DBServerState server = getServerState(request.getServerContext());
    return server.getScript(request.getParam(0));
  }
}
  • EvalShaCommand继承了AbstractEvalCommand,其script方法先通过getServerState(request.getServerContext())获取server,再执行server.getScript(request.getParam(0))

ScriptCommands

claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/scripting/ScriptCommands.java

@ParamLength(1)
@Command("script")
public class ScriptCommands implements DBCommand {
​
  @Override
  public RedisToken execute(Database db, Request request) {
    return Pattern1.<Request, RedisToken>build()
        .when(isCommand("load"))
          .then(this::load)
        .when(isCommand("exists"))
          .then(this::exists)
        .when(isCommand("flush"))
          .then(this::flush)
        .otherwise()
          .then(this::unknownCommand)
        .apply(request);
  }
​
  private RedisToken unknownCommand(Request request) {
    return RedisToken.error("Unknown SCRIPT subcommand: " + request.getParam(0));
  }
​
  private RedisToken load(Request request) {
    SafeString script = request.getParam(1);
    return Try.of(() -> digest(script)).map(sha1 -> {
      DBServerState server = getServerState(request.getServerContext());
      server.saveScript(safeString(sha1), script);
      return RedisToken.string(sha1);
    }).getOrElse(RedisToken.error("ERR cannot generate sha1 sum for script: " + script));
  }
​
  private RedisToken exists(Request request) {
    DBServerState server = getServerState(request.getServerContext());
    return integer(server.getScript(request.getParam(1)).isPresent());
  }
​
  private RedisToken flush(Request request) {
    getServerState(request.getServerContext()).cleanScripts();
    return RedisToken.responseOk();
  }
​
  private String digest(SafeString script) throws NoSuchAlgorithmException {
    MessageDigest digest = MessageDigest.getInstance("SHA-1");
    return new SafeString(digest.digest(script.getBytes())).toHexString();
  }
​
  private Matcher1<Request> isCommand(String command) {
    return request -> request.getParam(0).toString().toLowerCase().equals(command);
  }
}
  • ScriptCommands实现了DBCommand接口,其execute方法支持load、exists、flush命令;其中load方法通过server.saveScript(safeString(sha1), script)来保存script;其exists方法通过server.getScript(request.getParam(1)).isPresent()来判断script是否存在;其flush方法执行getServerState(request.getServerContext()).cleanScripts()

小结

claudb scripting相关的command有EvalCommand、EvalShaCommand、ScriptCommands

doc

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 聊聊claudb的scripting command

    claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/scripting/Abstract...

    codecraft
  • 聊聊claudb的pubsub command

    claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/pubsub/PublishComm...

    codecraft
  • 聊聊claudb的pubsub command

    claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/pubsub/PublishComm...

    codecraft
  • 聊聊claudb的scripting command

    claudb-1.7.1/src/main/java/com/github/tonivade/claudb/command/scripting/Abstract...

    codecraft
  • Spring Cloud Zuul中DispatcherServlet和ZuulServlet

    Zuul是通过Servlet机制实现的。一般情况下,ZuulServet被嵌入到Spring Dispatch机制中,由DispatcherServlet分派处...

    java达人
  • MOOON-server新消息处理接口

        MOOON-server提供了一个通用的TCP框架,并对包的解析抽象出了IPacketHandler接口,这个接口提供了无限制的宽容度,支持任何协议,但...

    一见
  • Laravel的生命周期

    当我们在命令行终端键入php这个命令的时候,使用的就是CLI模式;当使用nginx或者其他服务器作为宿主来处理一个请求的时候,会调用php来运行,此时使用的就是...

    用户2475223
  • python爬虫---从零开始(二)Urllib库

      在这里我们看到,当我们输入urllib.request.urlopen('http://baidu.com')时,我们会得到一大长串的文本,也就是我们将要从...

    小菜的不能再菜
  • 【Python爬虫】Urllib的使用(2)

    这是第二篇介绍爬虫基础知识的文章,之前的文章【Python爬虫】初识爬虫(1)主要是让大家了解爬虫和爬虫需要的基础知识,今天主要给大家介绍Urllib的使用。

    PM小王
  • 单细胞RNA数据标准化与聚类分析

    单细胞转录组测序产生的数据是成百上千个基因在上万个细胞中的表达情况,属于高维数据,我们需要对数据进行严格的质控与过滤,将合格的数据降维到低维子空间,使数据可视化...

    生信交流平台

扫码关注云+社区

领取腾讯云代金券