Skip to content

Commit

Permalink
Merge pull request #41 from zzgab/feature_36_scan
Browse files Browse the repository at this point in the history
issue #36 : basic support for SCAN
  • Loading branch information
volker48 authored Dec 20, 2017
2 parents 43cb309 + f497e80 commit a81a5f3
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 4 deletions.
44 changes: 40 additions & 4 deletions src/main/java/com/fiftyonred/mock_jedis/MockJedis.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.ArrayList;
import java.util.Collection;

import redis.clients.jedis.*;
import redis.clients.util.Pool;
import redis.clients.util.Slowlog;

import static redis.clients.jedis.Protocol.Keyword.MATCH;

public class MockJedis extends Jedis {

public static final String NOT_IMPLEMENTED = "Not implemented";
Expand Down Expand Up @@ -1320,14 +1324,46 @@ public ScanResult<Tuple> zscan(String key, int cursor, ScanParams params) {

@Override
public ScanResult<String> scan(String cursor) {
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
return scan(cursor, (new ScanParams()).match("*"));
}

/**
* In this simple proposal, we're not testing complex iterations
* of scan cursor. SCAN is simply a wrapper for KEYS, and the result
* is given in one single response, no matter the COUNT argument.
*/
@Override
public ScanResult<String> scan(String cursor, ScanParams params) {
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
}

// We need to extract the MATCH argument from the scan params
Collection<byte[]> rawParams = params.getParams();

// Raw collection is a list of byte[], made of: key1, value1, key2, value2, etc.
boolean isKey = true;
String match = null;
boolean foundMatchKey = false;

// So, we run over the list, where any even index is a key, and the following data is its value.
for (byte[] raw : rawParams) {
if (isKey) {
String key = new String(raw);
if (key.equals(new String(MATCH.raw))) {
// What really interests us is the MATCH key.
foundMatchKey = true;
}
}
// As soon as we've found the MATCH key, we can stop searching.
else if (foundMatchKey) {
match = new String(raw);
break;
}
isKey = !isKey;
}

// Our simple implementation of SCAN is really a plain wrapper for KEYS,
// relying on the current mock implementation of the pattern search.
return new ScanResult<String>("0", new ArrayList<String>(keys(match)));
}

@Override
public ScanResult<Map.Entry<String, String>> hscan(String key, String cursor) {
throw new UnsupportedOperationException(NOT_IMPLEMENTED);
Expand Down
23 changes: 23 additions & 0 deletions src/test/java/com/fiftyonred/mock_jedis/MockJedisTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import redis.clients.jedis.Jedis;
import redis.clients.jedis.SortingParams;
import redis.clients.jedis.exceptions.JedisDataException;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

import java.util.*;

Expand Down Expand Up @@ -216,4 +218,25 @@ public void testMultipleDB() {
j.select(5);
assertEquals(1L, j.dbSize().longValue());
}

/**
* In this simple proposal, we're not testing complex iterations
* of scan cursor. SCAN is simply a wrapper for KEYS, and the result
* is given in one single response, no matter the COUNT argument.
*/
@Test
public void testScan() {
j.set("key1", "val1");
j.set("key2", "val2");
j.set("kk", "val3");

ScanParams scanParams = new ScanParams();
scanParams.count(100).match("key*");
ScanResult<String> scanResult;
scanResult = j.scan("0", scanParams);


assertEquals(2L, scanResult.getResult().size());
assertEquals("0", scanResult.getStringCursor());
}
}

0 comments on commit a81a5f3

Please sign in to comment.