36
36
import io .lettuce .core .protocol .Command ;
37
37
import io .lettuce .core .protocol .CommandArgs ;
38
38
import io .lettuce .core .protocol .CommandType ;
39
+ import io .lettuce .core .protocol .ProtocolKeyword ;
39
40
import io .lettuce .core .pubsub .StatefulRedisPubSubConnection ;
40
41
import io .lettuce .core .sentinel .api .StatefulRedisSentinelConnection ;
41
42
42
43
import java .lang .reflect .Constructor ;
44
+ import java .nio .charset .StandardCharsets ;
43
45
import java .util .ArrayList ;
44
46
import java .util .Collections ;
45
47
import java .util .HashMap ;
@@ -389,7 +391,7 @@ public Object execute(String command, @Nullable CommandOutput commandOutputTypeH
389
391
Assert .hasText (command , "a valid command needs to be specified" );
390
392
391
393
String name = command .trim ().toUpperCase ();
392
- CommandType commandType = CommandType . valueOf (name );
394
+ ProtocolKeyword commandType = getCommandType (name );
393
395
394
396
validateCommandIfRunningInTransactionMode (commandType , args );
395
397
@@ -1109,14 +1111,14 @@ io.lettuce.core.ScanCursor getScanCursor(long cursorId) {
1109
1111
return io .lettuce .core .ScanCursor .of (Long .toString (cursorId ));
1110
1112
}
1111
1113
1112
- private void validateCommandIfRunningInTransactionMode (CommandType cmd , byte []... args ) {
1114
+ private void validateCommandIfRunningInTransactionMode (ProtocolKeyword cmd , byte []... args ) {
1113
1115
1114
1116
if (this .isQueueing ()) {
1115
1117
validateCommand (cmd , args );
1116
1118
}
1117
1119
}
1118
1120
1119
- private void validateCommand (CommandType cmd , @ Nullable byte []... args ) {
1121
+ private void validateCommand (ProtocolKeyword cmd , @ Nullable byte []... args ) {
1120
1122
1121
1123
RedisCommand redisCommand = RedisCommand .failsafeCommandLookup (cmd .name ());
1122
1124
if (!RedisCommand .UNKNOWN .equals (redisCommand ) && redisCommand .requiresArguments ()) {
@@ -1128,6 +1130,15 @@ private void validateCommand(CommandType cmd, @Nullable byte[]... args) {
1128
1130
}
1129
1131
}
1130
1132
1133
+ private static ProtocolKeyword getCommandType (String name ) {
1134
+
1135
+ try {
1136
+ return CommandType .valueOf (name );
1137
+ } catch (IllegalArgumentException e ) {
1138
+ return new CustomCommandType (name );
1139
+ }
1140
+ }
1141
+
1131
1142
/**
1132
1143
* {@link TypeHints} provide {@link CommandOutput} information for a given {@link CommandType}.
1133
1144
*
@@ -1136,7 +1147,7 @@ private void validateCommand(CommandType cmd, @Nullable byte[]... args) {
1136
1147
static class TypeHints {
1137
1148
1138
1149
@ SuppressWarnings ("rawtypes" ) //
1139
- private static final Map <CommandType , Class <? extends CommandOutput >> COMMAND_OUTPUT_TYPE_MAPPING = new HashMap <>();
1150
+ private static final Map <ProtocolKeyword , Class <? extends CommandOutput >> COMMAND_OUTPUT_TYPE_MAPPING = new HashMap <>();
1140
1151
1141
1152
@ SuppressWarnings ("rawtypes" ) //
1142
1153
private static final Map <Class <?>, Constructor <CommandOutput >> CONSTRUCTORS = new ConcurrentHashMap <>();
@@ -1298,7 +1309,7 @@ static class TypeHints {
1298
1309
* @return {@link ByteArrayOutput} as default when no matching {@link CommandOutput} available.
1299
1310
*/
1300
1311
@ SuppressWarnings ("rawtypes" )
1301
- public CommandOutput getTypeHint (CommandType type ) {
1312
+ public CommandOutput getTypeHint (ProtocolKeyword type ) {
1302
1313
return getTypeHint (type , new ByteArrayOutput <>(CODEC ));
1303
1314
}
1304
1315
@@ -1309,7 +1320,7 @@ public CommandOutput getTypeHint(CommandType type) {
1309
1320
* @return
1310
1321
*/
1311
1322
@ SuppressWarnings ("rawtypes" )
1312
- public CommandOutput getTypeHint (CommandType type , CommandOutput defaultType ) {
1323
+ public CommandOutput getTypeHint (ProtocolKeyword type , CommandOutput defaultType ) {
1313
1324
1314
1325
if (type == null || !COMMAND_OUTPUT_TYPE_MAPPING .containsKey (type )) {
1315
1326
return defaultType ;
@@ -1552,4 +1563,49 @@ public void onClose(StatefulConnection<?, ?> connection) {
1552
1563
connection .setAutoFlushCommands (true );
1553
1564
}
1554
1565
}
1566
+
1567
+ /**
1568
+ * @since 2.3.8
1569
+ */
1570
+ static class CustomCommandType implements ProtocolKeyword {
1571
+
1572
+ private final String name ;
1573
+
1574
+ CustomCommandType (String name ) {
1575
+ this .name = name ;
1576
+ }
1577
+
1578
+ @ Override
1579
+ public byte [] getBytes () {
1580
+ return name .getBytes (StandardCharsets .US_ASCII );
1581
+ }
1582
+
1583
+ @ Override
1584
+ public String name () {
1585
+ return name ;
1586
+ }
1587
+
1588
+ @ Override
1589
+ public boolean equals (Object o ) {
1590
+
1591
+ if (this == o ) {
1592
+ return true ;
1593
+ }
1594
+ if (!(o instanceof CustomCommandType )) {
1595
+ return false ;
1596
+ }
1597
+ CustomCommandType that = (CustomCommandType ) o ;
1598
+ return ObjectUtils .nullSafeEquals (name , that .name );
1599
+ }
1600
+
1601
+ @ Override
1602
+ public int hashCode () {
1603
+ return ObjectUtils .nullSafeHashCode (name );
1604
+ }
1605
+
1606
+ @ Override
1607
+ public String toString () {
1608
+ return name ;
1609
+ }
1610
+ }
1555
1611
}
0 commit comments