Status Parse()

in src/commands/cmd_cluster.cc [148:241]


  Status Parse(const std::vector<std::string> &args) override {
    subcommand_ = util::ToLower(args[1]);

    if (args.size() == 2 && (subcommand_ == "version" || subcommand_ == "myid")) return Status::OK();

    if (subcommand_ == "setnodeid" && args_.size() == 3 && args_[2].size() == kClusterNodeIdLen) return Status::OK();

    if (subcommand_ == "migrate") {
      if (args.size() < 4 || args.size() > 6) return {Status::RedisParseErr, errWrongNumOfArguments};

      Status s = CommandTable::ParseSlotRanges(args_[2], slot_ranges_);
      if (!s.IsOK()) {
        return s;
      }

      dst_node_id_ = args[3];

      if (args.size() >= 5) {
        auto sync_flag = util::ToLower(args[4]);
        if (sync_flag == "async") {
          sync_migrate_ = false;

          if (args.size() == 6) {
            return {Status::RedisParseErr, "Async migration does not support timeout"};
          }
        } else if (sync_flag == "sync") {
          sync_migrate_ = true;

          if (args.size() == 6) {
            auto parse_result = ParseInt<int>(args[5], 10);
            if (!parse_result) {
              return {Status::RedisParseErr, "timeout is not an integer or out of range"};
            }
            if (*parse_result < 0) {
              return {Status::RedisParseErr, errTimeoutIsNegative};
            }
            sync_migrate_timeout_ = *parse_result;
          }
        } else {
          return {Status::RedisParseErr, "Invalid sync flag"};
        }
      }
      return Status::OK();
    }

    if (subcommand_ == "setnodes" && args_.size() >= 4) {
      nodes_str_ = args_[2];

      auto parse_result = ParseInt<int64_t>(args[3], 10);
      if (!parse_result) {
        return {Status::RedisParseErr, "Invalid version"};
      }

      set_version_ = *parse_result;

      if (args_.size() == 4) return Status::OK();

      if (args_.size() == 5 && util::EqualICase(args_[4], "force")) {
        force_ = true;
        return Status::OK();
      }

      return {Status::RedisParseErr, "Invalid setnodes options"};
    }

    // CLUSTERX SETSLOT $SLOT_ID NODE $NODE_ID $VERSION
    if (subcommand_ == "setslot" && args_.size() == 6) {
      Status s = CommandTable::ParseSlotRanges(args_[2], slot_ranges_);
      if (!s.IsOK()) {
        return s;
      }

      if (!util::EqualICase(args_[3], "node")) {
        return {Status::RedisParseErr, "Invalid setslot options"};
      }

      if (args_[4].size() != kClusterNodeIdLen) {
        return {Status::RedisParseErr, "Invalid node id"};
      }

      auto parse_version = ParseInt<int64_t>(args[5], 10);
      if (!parse_version) {
        return {Status::RedisParseErr, errValueNotInteger};
      }

      if (*parse_version < 0) return {Status::RedisParseErr, "Invalid version"};

      set_version_ = *parse_version;

      return Status::OK();
    }

    return {Status::RedisParseErr, "CLUSTERX command, CLUSTERX VERSION|MYID|SETNODEID|SETNODES|SETSLOT|MIGRATE"};
  }