sequence

This article focuses on Claudb’s String Command

GetCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/GetCommand. Java

@ReadOnly @Command("get") @ParamLength(1) @ParamType(DataType.STRING) public class GetCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { return convert(db.get(safeKey(request.getParam(0)))); }}Copy the code
  • Db.get (safeKey(request.getParam(0)))

MultiGetCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/MultiGetCommand. Java

@ReadOnly @Command("mget") @ParamLength(1) public class MultiGetCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { ImmutableArray<DatabaseValue> result = request.getParams() .map(DatabaseKey::safeKey) .filter(key -> db.isType(key, DataType.STRING)) .map(db::get); return convert(result); }}Copy the code
  • MultiGetCommand implements the DBCommand interface. Its execute method iterates through Request.getParams () to retrieve datatype.string and then executes db::get one by one

SetCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/SetCommand. Java

@Command("set") @ParamLength(2) public class SetCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { return com.github.tonivade.purefun.type.Try.of(() -> parse(request)) .map(params -> onSuccess(db, request, params)) .recover(this::onFailure) .get(); } private RedisToken onSuccess(Database db, Request request, Parameters parameters) { DatabaseKey key = safeKey(request.getParam(0)); DatabaseValue value = parseValue(request, parameters); return value.equals(saveValue(db, parameters, key, value)) ? responseOk() : nullString(); } private DatabaseValue parseValue(Request request, Parameters parameters) { DatabaseValue value = string(request.getParam(1)); if (parameters.ttl ! = null) { value = value.expiredAt(Instant.now().plus(parameters.ttl)); } return value; } private RedisToken onFailure(Throwable e) { return Pattern1.<Throwable, RedisToken>build() .when(instanceOf(SyntaxException.class)) .returns(error("syntax error")) .when(instanceOf(NumberFormatException.class)) .returns(error("value is not an integer or out of range")) .otherwise() .returns(error("error: " + e.getMessage())) .apply(e); } private DatabaseValue saveValue(Database db, Parameters params, DatabaseKey key, DatabaseValue value) { DatabaseValue savedValue = null; if (params.ifExists) { savedValue = putValueIfExists(db, key, value); } else if (params.ifNotExists) { savedValue = putValueIfNotExists(db, key, value); } else { savedValue = putValue(db, key, value); } return savedValue; } private DatabaseValue putValue(Database db, DatabaseKey key, DatabaseValue value) { db.put(key, value); return value; } private DatabaseValue putValueIfExists(Database db, DatabaseKey key, DatabaseValue value) { DatabaseValue oldValue = db.get(key); if (oldValue ! = null) { return putValue(db, key, value); } return oldValue; } private DatabaseValue putValueIfNotExists(Database db, DatabaseKey key, DatabaseValue value) { return db.merge(key, value, (oldValue, newValue) -> oldValue); } private Parameters parse(Request request) { Parameters parameters = new Parameters(); if (request.getLength() > 2) { for (int i = 2; i < request.getLength(); i++) { SafeString option = request.getParam(i); if (match("EX", option)) { if (parameters.ttl ! = null) { throw new SyntaxException(); } parameters.ttl = parseTtl(request, ++i) .map(Duration::ofSeconds) .getOrElseThrow(SyntaxException::new); } else if (match("PX", option)) { if (parameters.ttl ! = null) { throw new SyntaxException(); } parameters.ttl = parseTtl(request, ++i) .map(Duration::ofMillis) .getOrElseThrow(SyntaxException::new); } else if (match("NX", option)) { if (parameters.ifExists) { throw new SyntaxException(); } parameters.ifNotExists = true; } else if (match("XX", option)) { if (parameters.ifNotExists) { throw new SyntaxException(); } parameters.ifExists = true; } else { throw new SyntaxException(); } } } return parameters; } private boolean match(String string, SafeString option) { return string.equalsIgnoreCase(option.toString()); } private Option<Integer> parseTtl(Request request, int i) { Option<SafeString> ttlOption = request.getOptionalParam(i);  return ttlOption.map(SafeString::toString).map(Integer::parseInt); } private static class Parameters { private boolean ifExists; private boolean ifNotExists; private TemporalAmount ttl; } private static class SyntaxException extends RuntimeException { private static final long serialVersionUID = 6960370945568192189L; }}Copy the code
  • SetCommand implements DBCommand interface. Its execute method is first parsed into parameters through the parse method, which supports EX, PX, NX and XX parameters. SyntaxException is thrown if the syntax error occurs. OnFailure then handles the different exceptions; The onSuccess method constructs DatabaseValue through parseValue(request, parameters) and then executes the saveValue method, which executes putValueIfExists for ifExists, Execute putValueIfNotExists for ifNotExists and putValue for others

MultiSetCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/MultiSetCommand. Java

@Command("mset")
@ParamLength(2)
public class MultiSetCommand implements DBCommand {

  @Override
  public RedisToken execute(Database db, Request request) {
    SafeString key = null;
    for (SafeString value : request.getParams()) {
      if (key != null) {
        db.put(safeKey(key), string(value));
        key = null;
      } else {
        key = value;
      }
    }
    return status("OK");
  }
}
Copy the code
  • MultiSetCommand implements the DBCommand interface. Its execute method traverses Request.getParams (), executing db.put(safeKey(key), string(value)) one by one.

GetSetCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/GetSetCommand. Java

@Command("getset") @ParamLength(2) @ParamType(DataType.STRING) public class GetSetCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { return convert(db.put(safeKey(request.getParam(0)), string(request.getParam(1)))); }}Copy the code
  • Db. put(safeKey(Request.getParam (0)), string(Request.getParam (1))), Return RedisToken at the same time

IncrementCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/IncrementCommand. Java

@Command("incr") @ParamLength(1) @ParamType(DataType.STRING) public class IncrementCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { try { DatabaseValue value = db.merge(safeKey(request.getParam(0)), string("1"), (oldValue, newValue) -> { int current = Integer.parseInt(oldValue.getString().toString()); return string(String.valueOf(current + 1)); }); return integer(Integer.parseInt(value.getString().toString())); } catch (NumberFormatException e) { return error("ERR value is not an integer or out of range"); }}}Copy the code
  • IncrementCommand implements DBCommand interface, execute method db.merge, oldValue gets current, String. ValueOf (current + 1)

IncrementByCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/IncrementByCommand. Java

@Command("incrby") @ParamLength(2) @ParamType(DataType.STRING) public class IncrementByCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { try { DatabaseValue value = db.merge(safeKey(request.getParam(0)), string(request.getParam(1)), (oldValue, newValue) -> { int increment = Integer.parseInt(newValue.getString().toString()); int current = Integer.parseInt(oldValue.getString().toString()); return string(String.valueOf(current + increment)); }); return integer(Integer.parseInt(value.getString().toString())); } catch (NumberFormatException e) { return error("ERR value is not an integer or out of range"); }}}Copy the code
  • Db. merge IncrementByCommand IncrementByCommand IncrementByCommand IncrementByCommand IncrementByCommand IncrementByCommand ValueOf (current + increment)

DecrementCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/DecrementCommand. Java

@Command("decr") @ParamLength(1) @ParamType(DataType.STRING) public class DecrementCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { try { DatabaseValue value = db.merge(safeKey(request.getParam(0)), string("-1"), (oldValue, newValue) -> { int current = Integer.parseInt(oldValue.getString().toString()); return string(String.valueOf(current - 1)); }); return integer(Integer.parseInt(value.getString().toString())); } catch (NumberFormatException e) { return error("ERR value is not an integer or out of range"); }}}Copy the code
  • DecrementCommand implements the DBCommand interface with its execute method, db.merge, which fetches current through oldValue and then string.valueof (current-1)

DecrementByCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/DecrementByCommand. Java

@Command("decrby") @ParamLength(2) @ParamType(DataType.STRING) public class DecrementByCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { try { DatabaseValue value = db.merge(safeKey(request.getParam(0)), string("-" + request.getParam(1)), (oldValue, newValue) -> { int decrement = Integer.parseInt(newValue.getString().toString()); int current = Integer.parseInt(oldValue.getString().toString()); return string(String.valueOf(current + decrement)); }); return integer(Integer.parseInt(value.getString().toString())); } catch (NumberFormatException e) { return error("ERR value is not an integer or out of range"); }}}Copy the code
  • DecrementByCommand implements the DBCommand interface, and its execute method does db.merge, which obtains Decrement via newValue and current through oldValue, Return to String.valueof (current + Decrement). Note that request.getParam(1) has been changed to a negative value

StringLengthCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/StringLengthCommand. Java

@ReadOnly @Command("strlen") @ParamLength(1) @ParamType(DataType.STRING) public class StringLengthCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { DatabaseValue value = db.getOrDefault(safeKey(request.getParam(0)), DatabaseValue.EMPTY_STRING); SafeString string = value.getString(); return integer(string.length()); }}Copy the code
  • StringLengthCommand implements the DBCommand interface. Its execute method fetches DatabaseValue from db.getorDefault before fetching String.length ().

SetExpiredCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/SetExpiredCommand. Java

@Command("setex") @ParamLength(3) public class SetExpiredCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { try { db.put(safeKey(request.getParam(0)), string(request.getParam(2)) .expiredAt(parseTtl(request.getParam(1)))); return responseOk(); } catch (NumberFormatException e) { return error("ERR value is not an integer or out of range"); } } private int parseTtl(SafeString safeString) { return Integer.parseInt(safeString.toString()); }}Copy the code
  • SetExpiredCommand implements DBCommand, which executes db.put, expiredAt(parseTtl(request.getParam(1))) on value.

BitCountCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/bitset/BitCountCommand. Java

@Command("bitcount") @ParamLength(1) @ParamType(DataType.STRING) public class BitCountCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { DatabaseValue value = db.getOrDefault(safeKey(request.getParam(0)), bitset()); BitSet bitSet = BitSet.valueOf(value.getString().getBuffer()); return integer(bitSet.cardinality()); }}Copy the code
  • BitCountCommand implements the DBCommand interface. Its execute method first fetches the DatabaseValue from db.getorDefault. Then bitset.valueof (value.getString().getBuffer())) is converted to BitSet and returns bitset.cardinality ().

SetBitCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/bitset/SetBitCommand. Java

@Command("setbit") @ParamLength(3) @ParamType(DataType.STRING) public class SetBitCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { try { int offset = Integer.parseInt(request.getParam(1).toString()); int bit = Integer.parseInt(request.getParam(2).toString()); Queue<Boolean> queue = new LinkedList<>(); db.merge(safeKey(request.getParam(0)), bitset(), (oldValue, newValue) -> { BitSet bitSet = BitSet.valueOf(oldValue.getString().getBuffer()); queue.add(bitSet.get(offset)); bitSet.set(offset, bit ! = 0); return oldValue; }); return integer(queue.poll()); } catch (NumberFormatException e) { return error("bit or offset is not an integer"); }}}Copy the code
  • SetBitCommand implements DBCommand. Execute db.merge oldValue into bitSet, and then execute bitset. set(offset, bit! = 0)

GetBitCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/bitset/GetBitCommand. Java

@Command("getbit") @ParamLength(2) @ParamType(DataType.STRING) public class GetBitCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { try { int offset = Integer.parseInt(request.getParam(1).toString()); DatabaseValue value = db.getOrDefault(safeKey(request.getParam(0)), bitset()); BitSet bitSet = BitSet.valueOf(value.getString().getBuffer()); return integer(bitSet.get(offset)); } catch (NumberFormatException e) { return error("bit offset is not an integer"); }}}Copy the code
  • GetBitCommand implements the DBCommand interface. Its execute method retrieves DatabaseValue from db.getorDefault, converts it to bitSet, and returns bitset.get (offset).

SetIfNotExistsCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/SetIfNotExistsCommand. Java

@Command("setnx") @ParamLength(2) public class SetIfNotExistsCommand implements DBCommand { @Override public RedisToken execute(Database db, Request request) { DatabaseKey key = safeKey(request.getParam(0)); DatabaseValue value = string(request.getParam(1)); return integer(putValueIfNotExists(db, key, value).equals(value)); } private DatabaseValue putValueIfNotExists(Database db, DatabaseKey key, DatabaseValue value) { return db.merge(key, value, (oldValue, newValue) -> oldValue); }}Copy the code
  • SetIfNotExistsCommand implements the DBCommand interface, whose execute method executes putValueIfNotExists and whose remappingFunction returns oldValue

MultiSetIfNotExistsCommand

Claudb 1.7.1 / SRC/main/Java/com/lot/tonivade/claudb/command/string/MultiSetIfNotExistsCommand. Java

@Command("msetnx")
@ParamLength(2)
public class MultiSetIfNotExistsCommand implements DBCommand {
  @Override
  public RedisToken execute(Database db, Request request) {
    Set<Tuple2<SafeString, SafeString>> pairs = toPairs(request);
    if (noneExists(db, pairs)) {
      pairs.forEach(entry -> db.put(safeKey(entry.get1()), string(entry.get2())));
      return integer(1);
    }
    return integer(0);
  }

  private boolean noneExists(Database db, Set<Tuple2<SafeString, SafeString>> pairs) {
    return pairs.stream()
        .map(Tuple2::get1)
        .map(DatabaseKey::safeKey)
        .noneMatch(db::containsKey);
  }

  private Set<Tuple2<SafeString, SafeString>> toPairs(Request request) {
    Set<Tuple2<SafeString, SafeString>> pairs = new HashSet<>();
    SafeString key = null;
    for (SafeString value : request.getParams()) {
      if (key != null) {
        pairs.add(entry(key, value));
        key = null;
      } else {
        key = value;
      }
    }
    return pairs;
  }
}
Copy the code
  • MultiSetIfNotExistsCommand DBCommand command interface is achieved, Its execute method executes db.put(safeKey(entry.get1()), string(entry.get2())) through pairs if noneExists(db, pairs) is true

summary

claudb String commands include GetCommand, MultiGetCommand, SetCommand, MultiSetCommand, GetSetCommand, IncrementCommand, IncrementByCommand DecrementCommand, DecrementByCommand, StringLengthCommand, SetExpiredCommand, BitCountCommand, GetBitCommand, SetIfNotExistsC Ommand, MultiSetIfNotExistsCommand

doc

  • command/string