Skip to content

DATAREDIS-293 - JedisConnection, allow bulk addition with same score. #63

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jredisVersion=06052013
jedisVersion=2.4.1
springVersion=3.2.8.RELEASE
log4jVersion=1.2.17
version=1.3.0.BUILD-SNAPSHOT
version=1.3.0.DATAREDIS-293-SNAPSHOT
srpVersion=0.7
jacksonVersion=1.8.8
fasterXmlJacksonVersion=2.2.0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* Copyright 2011-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,8 +19,12 @@
* A {@link Comparable} software version
*
* @author Jennifer Hickey
* @author Christoph Strobl
*/
public class Version implements Comparable<Version> {

public static final Version UNKNOWN = new Version(0, 0, 0);

Integer major;
Integer minor;
Integer patch;
Expand Down Expand Up @@ -48,4 +52,51 @@ public int compareTo(Version o) {
public String toString() {
return "" + major + "." + minor + "." + patch;
}

@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((major == null) ? 0 : major.hashCode());
result = prime * result + ((minor == null) ? 0 : minor.hashCode());
result = prime * result + ((patch == null) ? 0 : patch.hashCode());
return result;
}

@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (!(obj instanceof Version)) {
return false;
}
Version other = (Version) obj;
if (major == null) {
if (other.major != null) {
return false;
}
} else if (!major.equals(other.major)) {
return false;
}
if (minor == null) {
if (other.minor != null) {
return false;
}
} else if (!minor.equals(other.minor)) {
return false;
}
if (patch == null) {
if (other.patch != null) {
return false;
}
} else if (!patch.equals(other.patch)) {
return false;
}
return true;
}

}
53 changes: 53 additions & 0 deletions src/main/java/org/springframework/data/redis/VersionParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.redis;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
* Central class for reading version string (eg. {@literal 1.3.1}) into {@link Version}.
*
* @author Christoph Strobl
* @since 1.3
*/
public class VersionParser {

private static final Pattern VERSION_MATCHER = Pattern.compile("([0-9]+)\\.([0-9]+)(\\.([0-9]+))?(.*)");

/**
* Parse version string {@literal eg. 1.1.1} to {@link Version}.
*
* @param version
* @return
*/
public static Version parseVersion(String version) {
if (version == null) {
return Version.UNKNOWN;
}

Matcher matcher = VERSION_MATCHER.matcher(version);
if (matcher.matches()) {
String major = matcher.group(1);
String minor = matcher.group(2);
String patch = matcher.group(4);
return new Version(Integer.parseInt(major), minor != null ? Integer.parseInt(minor) : 0,
patch != null ? Integer.parseInt(patch) : 0);
}
return Version.UNKNOWN;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -2923,7 +2923,7 @@ private Map<byte[], Double> zAddArgs(Set<Tuple> tuples) {

Map<byte[], Double> args = new HashMap<byte[], Double>();
for (Tuple tuple : tuples) {
if (args.containsValue(tuple.getScore())) {
if (args.containsValue(tuple.getScore()) && !JedisVersionUtil.atLeastJedis24()) {
throw new UnsupportedOperationException(
"Bulk add of multiple elements with the same score is not supported. Add the elements individually.");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.redis.connection.jedis;

import java.io.IOException;
import java.util.Properties;

import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.data.redis.Version;
import org.springframework.data.redis.VersionParser;
import org.springframework.util.StringUtils;

import redis.clients.jedis.Jedis;

/**
* @author Christoph Strobl
* @since 1.3
*/
public class JedisVersionUtil {

private static Version jedisVersion = parseVersion(resolveJedisVersion());

/**
* @return current {@link redis.clients.jedis.Jedis} version.
*/
public static Version jedisVersion() {
return jedisVersion;
}

/**
* Parse version string {@literal eg. 1.1.1} to {@link Version}.
*
* @param version
* @return
*/
static Version parseVersion(String version) {
return VersionParser.parseVersion(version);
}

/**
* @return true if used jedis version is at minimum {@literal 2.4}.
*/
public static boolean atLeastJedis24() {
return atLeast("2.4");
}

private static String resolveJedisVersion() {

String version = Jedis.class.getPackage().getImplementationVersion();

if (!StringUtils.hasText(version)) {
try {
Properties props = PropertiesLoaderUtils.loadAllProperties("META-INF/maven/redis.clients/jedis/pom.properties");
if (props.containsKey("version")) {
version = props.getProperty("version");
}
} catch (IOException e) {
// ignore this one
}
}
return version;
}

/**
* Compares given version string against current jedis version.
*
* @param version
* @return true in case given version is greater than equal to current one.
*/
public static boolean atLeast(String version) {
return jedisVersion.compareTo(parseVersion(version)) >= 0;
}

/**
* Compares given version string against current jedis version.
*
* @param version
* @return true in case given version is less than equal to current one.
*/
public static boolean atMost(String version) {
return jedisVersion.compareTo(parseVersion(version)) <= 0;
}

}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2011-2013 the original author or authors.
* Copyright 2011-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -15,20 +15,16 @@
*/
package org.springframework.data.redis;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.data.redis.connection.RedisConnection;

/**
* Utilities for examining the Redis version
*
* @author Jennifer Hickey
* @author Christoph Strobl
*/
public abstract class RedisVersionUtils {

private static final Pattern VERSION_MATCHER = Pattern.compile("([0-9]+)\\.([0-9]+)(\\.([0-9]+))?");

public static Version getRedisVersion(RedisConnection connection) {
return parseVersion((String) connection.info().get("redis_version"));
}
Expand All @@ -42,14 +38,11 @@ public static boolean atMost(String version, RedisConnection connection) {
}

public static Version parseVersion(String version) {
Matcher matcher = VERSION_MATCHER.matcher(version);
if (matcher.matches()) {
String major = matcher.group(1);
String minor = matcher.group(2);
String patch = matcher.group(4);
return new Version(Integer.parseInt(major), minor != null ? Integer.parseInt(minor) : 0,
patch != null ? Integer.parseInt(patch) : 0);

Version resolvedVersion = VersionParser.parseVersion(version);
if (Version.UNKNOWN.equals(resolvedVersion)) {
throw new IllegalArgumentException("Specified version cannot be parsed");
}
throw new IllegalArgumentException("Specified version cannot be parsed");
return resolvedVersion;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Copyright 2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.redis;

import static org.hamcrest.core.IsEqual.*;
import static org.junit.Assert.*;

import org.junit.Test;

/**
* @author Christoph Strobl
*/
public class VersionParserUnitTests {

@Test
public void shouldParseNullToUnknown() {
assertThat(VersionParser.parseVersion(null), equalTo(Version.UNKNOWN));
}

@Test
public void shouldParseEmptyVersionStringToUnknown() {
assertThat(VersionParser.parseVersion(""), equalTo(Version.UNKNOWN));
}

@Test
public void shouldParseInvalidVersionStringToUnknown() {
assertThat(VersionParser.parseVersion("ThisIsNoValidVersion"), equalTo(Version.UNKNOWN));
}

@Test
public void shouldParseMajorMinorWithoutPatchCorrectly() {
assertThat(VersionParser.parseVersion("1.2"), equalTo(new Version(1, 2, 0)));
}

@Test
public void shouldParseMajorMinorPatchCorrectly() {
assertThat(VersionParser.parseVersion("1.2.3"), equalTo(new Version(1, 2, 3)));
}

@Test
public void shouldParseMajorWithoutMinorPatchCorrectly() {
assertThat(VersionParser.parseVersion("1.2.3.a"), equalTo(new Version(1, 2, 3)));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -117,12 +117,13 @@ public void testClosePool() {
factory2.destroy();
}

@Test(expected = UnsupportedOperationException.class)
@Test
public void testZAddSameScores() {
Set<StringTuple> strTuples = new HashSet<StringTuple>();
strTuples.add(new DefaultStringTuple("Bob".getBytes(), "Bob", 2.0));
strTuples.add(new DefaultStringTuple("James".getBytes(), "James", 2.0));
connection.zAdd("myset", strTuples);
Long added = connection.zAdd("myset", strTuples);
assertEquals(2L, added.longValue());
}

@Test(expected = InvalidDataAccessApiUsageException.class)
Expand Down