Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'trunk' of github.com:impetus-opensource/Kundera into trunk

  • Loading branch information...
commit bc71823592232b179786d4e0eec3d241fb2dc483 2 parents 882eac3 + cf7cd73
@kkmishra kkmishra authored
View
119 kundera-redis/src/main/java/com/impetus/client/redis/RedisClient.java
@@ -111,8 +111,7 @@ protected void onPersist(EntityMetadata entityMetadata, Object entity, Object id
byte[] nameInBytes = getEncodedBytes(name);
String valueAsStr = PropertyAccessorHelper.getString(value);
wrapper.addColumn(nameInBytes, valueInBytes);
- wrapper.addIndex(getHashKey(entityMetadata.getTableName(), name),
- getDouble(valueAsStr));
+ wrapper.addIndex(getHashKey(entityMetadata.getTableName(), name), getDouble(valueAsStr));
// this index is required to work for UNION/INTERSECT
// support.
@@ -141,12 +140,23 @@ protected void onPersist(EntityMetadata entityMetadata, Object entity, Object id
String hashKey = getHashKey(entityMetadata.getTableName(), rowKey);
connection.hmset(getEncodedBytes(hashKey), wrapper.getColumns());
-
- // Add row key.
- connection.rpush(getHashKey(entityMetadata.getTableName(), entityMetadata.getIdAttribute().getName()), rowKey);
+
+ // Add row key to list(Required for wild search over table).
+ connection.zadd(
+ getHashKey(entityMetadata.getTableName(),
+ ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName()),
+ getDouble(rowKey), rowKey);
// Add inverted indexes for column based search.
addIndex(connection, wrapper, rowKey);
+
+ // Add row-key as inverted index as well needed for multiple clause
+ // search with key and non row key.
+ connection
+ .zadd(getHashKey(
+ entityMetadata.getTableName(),
+ getHashKey(((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName(), rowKey)),
+ getDouble(rowKey), rowKey);
//
pipeLine.sync(); // send I/O.. as persist call. so no need to read
// response?
@@ -160,7 +170,8 @@ protected void onPersist(EntityMetadata entityMetadata, Object entity, Object id
private double getDouble(String valueAsStr)
{
- return StringUtils.isNumeric(valueAsStr)? Double.parseDouble(valueAsStr) : Double.parseDouble(((Integer) valueAsStr.hashCode()).toString());
+ return StringUtils.isNumeric(valueAsStr) ? Double.parseDouble(valueAsStr) : Double
+ .parseDouble(((Integer) valueAsStr.hashCode()).toString());
}
@Override
@@ -170,7 +181,7 @@ public Object find(Class entityClass, Object key)
Jedis connection = factory.getConnection();
try
{
- result = fetch(entityClass, key, connection);
+ result = fetch(entityClass, key, connection, null);
}
catch (InstantiationException e)
@@ -191,7 +202,7 @@ public Object find(Class entityClass, Object key)
return result;
}
- private Object fetch(Class clazz, Object key, Jedis connection) throws InstantiationException,
+ private Object fetch(Class clazz, Object key, Jedis connection, byte[][] fields) throws InstantiationException,
IllegalAccessException
{
Object result;
@@ -216,7 +227,26 @@ private Object fetch(Class clazz, Object key, Jedis connection) throws Instantia
try
{
- Map<byte[], byte[]> columns = connection.hgetAll(getEncodedBytes(hashKey));
+ Map<byte[], byte[]> columns = new HashMap<byte[], byte[]>();
+
+ // IF it is for selective columns
+ if (fields != null)
+ {
+ List<byte[]> fieldValues = connection.hmget(getEncodedBytes(hashKey), fields);
+
+ if (fieldValues != null && fieldValues.isEmpty())
+ {
+ for (int i = 0; i < fields.length; i++)
+ {
+ columns.put(fields[i], fieldValues.get(i));
+ }
+ }
+ }
+ else
+ {
+ columns = connection.hgetAll(getEncodedBytes(hashKey));
+ }
+ // Map<byte[], byte[]>
result = unwrap(entityMetadata, columns, key);
}
catch (JedisConnectionException jedex)
@@ -239,7 +269,7 @@ private Object fetch(Class clazz, Object key, Jedis connection) throws Instantia
{
for (Object key : keys)
{
- Object result = fetch(entityClass, key, connection);
+ Object result = fetch(entityClass, key, connection, null);
if (result != null)
{
results.add(result);
@@ -314,8 +344,10 @@ public void delete(Object entity, Object pKey)
// Delete inverted indexes.
unIndex(connection, wrapper, rowKey);
- connection.lrem(getHashKey(entityMetadata.getTableName(), entityMetadata.getIdAttribute().getName()), 0, rowKey);
-
+ connection.zrem(
+ getHashKey(entityMetadata.getTableName(),
+ ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName()), rowKey);
+
pipeLine.sync();
}
finally
@@ -887,8 +919,7 @@ private void addToWrapper(EntityMetadata entityMetadata, AttributeWrapper wrappe
wrapper.addIndex(
getHashKey(entityMetadata.getTableName(),
- getHashKey(((AbstractAttribute) attrib).getJPAColumnName(), valueAsStr)),
- getDouble(valueAsStr));
+ getHashKey(((AbstractAttribute) attrib).getJPAColumnName(), valueAsStr)), getDouble(valueAsStr));
}
@@ -1028,9 +1059,9 @@ List onExecuteQuery(RedisQueryInterpreter queryParameter, Class entityClazz)
keySets.add(key);
}
- if (queryParameter.getClass().equals(Clause.INTERSECT))
+ if (queryParameter.getClause().equals(Clause.INTERSECT))
{
- connection.zinterstore(getEncodedBytes(destStore), keySets.toArray(new byte[][] {}));
+ connection.zinterstore(destStore, keySets.toArray(new String[] {}));
}
else
{
@@ -1059,21 +1090,27 @@ else if (queryParameter.isByRange())
else if (queryParameter.isById())
{
Map<String, Object> fieldSets = queryParameter.getFields();
- results = findAll(entityClazz, fieldSets.values().toArray());
- } else
+
+ results = findAllColumns(entityClazz, (byte[][]) (queryParameter.getColumns() != null ? queryParameter
+ .getColumns().toArray() : null), fieldSets.values().toArray());
+ return results;
+ }
+ else
{
- rowKeys = new HashSet<String>(connection.lrange(getHashKey(entityMetadata.getTableName(), entityMetadata.getIdAttribute().getName()), 0, -1));
+ rowKeys = new HashSet<String>(connection.zrange(
+ getHashKey(entityMetadata.getTableName(),
+ ((AbstractAttribute) entityMetadata.getIdAttribute()).getJPAColumnName()), 0, -1));
}
- if (!queryParameter.isById())
+ // fetch fr
+ for (String k : rowKeys)
{
- for (String k : rowKeys)
+
+ Object record = fetch(entityClazz, k, connection,
+ (byte[][]) (queryParameter.getColumns() != null ? queryParameter.getColumns().toArray() : null));
+ if (record != null)
{
- Object record = fetch(entityClazz, k, connection);
- if (record != null)
- {
- results.add(record);
- }
+ results.add(record);
}
}
@@ -1098,4 +1135,34 @@ else if (queryParameter.isById())
return results;
}
+
+ private <E> List<E> findAllColumns(Class<E> entityClass, byte[][] columns, Object... keys)
+ {
+ Jedis connection = factory.getConnection();
+ connection.pipelined();
+ List results = new ArrayList();
+ try
+ {
+ for (Object key : keys)
+ {
+ Object result = fetch(entityClass, key, connection, columns);
+ if (result != null)
+ {
+ results.add(result);
+ }
+ }
+ }
+ catch (InstantiationException e)
+ {
+ logger.error("Error during find by key:", e);
+ throw new PersistenceException(e);
+ }
+ catch (IllegalAccessException e)
+ {
+ logger.error("Error during find by key:", e);
+ throw new PersistenceException(e);
+ }
+ return results;
+ }
+
}
View
2  kundera-redis/src/main/java/com/impetus/client/redis/RedisQuery.java
@@ -129,7 +129,7 @@ protected int onExecuteUpdate()
private RedisQueryInterpreter onTranslation(Queue clauseQueue, EntityMetadata entityMetadata)
{
- RedisQueryInterpreter interpreter = new RedisQueryInterpreter();
+ RedisQueryInterpreter interpreter = new RedisQueryInterpreter(getKunderaQuery().getResult());
// If there is no clause present, means we might need to scan complete
// table.
View
45 kundera-redis/src/main/java/com/impetus/client/redis/RedisQueryInterpreter.java
@@ -15,11 +15,14 @@
******************************************************************************/
package com.impetus.client.redis;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.apache.commons.lang.StringUtils;
+import com.impetus.kundera.Constants;
import com.impetus.kundera.property.PropertyAccessorHelper;
/**
@@ -46,12 +49,15 @@
private Map<String, Object> fields;
- private static Map<String,Clause> clauseMapper = new HashMap<String,Clause>();
+ private String[] columns;
+
+ private static Map<String, Clause> clauseMapper = new HashMap<String, Clause>();
static
{
clauseMapper.put("AND", Clause.INTERSECT);
clauseMapper.put("OR", Clause.UNION);
}
+
enum Clause
{
UNION, INTERSECT;
@@ -61,12 +67,13 @@ static Clause getMappedClause(String intraClause)
{
return clauseMapper.get(intraClause);
}
-
+
/**
* Default constructor
*/
- public RedisQueryInterpreter()
+ public RedisQueryInterpreter(String[] columns)
{
+ this.columns = columns;
}
boolean isById()
@@ -116,7 +123,10 @@ void setValue(Object value)
void setMin(String field, Object fieldValue)
{
this.min = new HashMap<String, Double>(1);
- this.min.put(field, !StringUtils.isNumeric(fieldValue.toString()) ? Double.valueOf(PropertyAccessorHelper.getString(fieldValue).hashCode()): Double.valueOf(fieldValue.toString()));
+ this.min.put(
+ field,
+ !StringUtils.isNumeric(fieldValue.toString()) ? Double.valueOf(PropertyAccessorHelper.getString(
+ fieldValue).hashCode()) : Double.valueOf(fieldValue.toString()));
}
Map<String, Double> getMax()
@@ -127,7 +137,10 @@ void setMin(String field, Object fieldValue)
void setMax(String field, Object fieldValue)
{
this.max = new HashMap<String, Double>(1);
- this.max.put(field, !StringUtils.isNumeric(fieldValue.toString()) ? Double.valueOf(PropertyAccessorHelper.getString(fieldValue).hashCode()): Double.valueOf(fieldValue.toString()));
+ this.max.put(
+ field,
+ !StringUtils.isNumeric(fieldValue.toString()) ? Double.valueOf(PropertyAccessorHelper.getString(
+ fieldValue).hashCode()) : Double.valueOf(fieldValue.toString()));
}
String getFieldName()
@@ -149,4 +162,26 @@ void setFieldName(String fieldName)
{
return fields;
}
+
+ List<byte[]> getColumns()
+ {
+ if (columns != null && columns.length > 0)
+ {
+ // byte[] fields = new byte[columns.length][1];
+ List<byte[]> fields = new ArrayList<byte[]>(columns.length);
+ for (int i = 0; i < columns.length; i++)
+ {
+ if (columns[i] != null && columns[i].indexOf(".") >= 0)
+ {
+ byte[] f = PropertyAccessorHelper.getBytes(columns[i]);
+ fields.add(f);
+ }
+ }
+
+ return fields.isEmpty()?null:fields;
+ }
+
+ return null;
+ }
+
}
View
79 kundera-redis/src/test/java/com/impetus/client/RedisQueryTest.java
@@ -70,6 +70,7 @@ public void testPopulateEntites()
final String originalName = "vivek";
+ // persist record.
PersonRedis object = new PersonRedis();
object.setAge(32);
object.setPersonId(ROW_KEY);
@@ -89,27 +90,31 @@ public void testPopulateEntites()
em.persist(object);
+ // Find without where clause.
String findWithOutWhereClause = "Select p from PersonRedis p";
Query query = em.createQuery(findWithOutWhereClause);
List<PersonRedis> results = query.getResultList();
Assert.assertEquals(3, results.size());
+ // find by key.
String findById = "Select p from PersonRedis p where p.personId=:personId";
query = em.createQuery(findById);
query.setParameter("personId", ROW_KEY);
results = query.getResultList();
Assert.assertEquals(1, results.size());
Assert.assertEquals(originalName, results.get(0).getPersonName());
-//
-// String findByIdAndAge = "Select p from PersonRedis p where p.personId=:personId AND p.age=:age";
-// query = em.createQuery(findByIdAndAge);
-// query.setParameter("personId", ROW_KEY);
-// query.setParameter("age", 32);
-//
-// results = query.getResultList();
-// Assert.assertEquals(1, results.size());
-// Assert.assertEquals(originalName, results.get(0).getPersonName());
+ // Find by key and now row key
+ String findByIdAndAge = "Select p from PersonRedis p where p.personId=:personId AND p.age=:age";
+ query = em.createQuery(findByIdAndAge);
+ query.setParameter("personId", ROW_KEY);
+ query.setParameter("age", 32);
+
+ results = query.getResultList();
+ Assert.assertEquals(1, results.size());
+ Assert.assertEquals(originalName, results.get(0).getPersonName());
+
+ // find by between over non rowkey
String findAgeByBetween = "Select p from PersonRedis p where p.age between :min AND :max";
query = em.createQuery(findAgeByBetween);
query.setParameter("min", 32);
@@ -119,6 +124,19 @@ public void testPopulateEntites()
Assert.assertEquals(2, results.size());
Assert.assertEquals(originalName, results.get(0).getPersonName());
+
+ // Between clause over rowkey
+ String findIdByBetween = "Select p from PersonRedis p where p.personId between :min AND :max";
+ query = em.createQuery(findIdByBetween);
+ query.setParameter("min", ROW_KEY);
+ query.setParameter("max", ROW_KEY+1);
+
+ results = query.getResultList();
+ Assert.assertEquals(2, results.size());
+ Assert.assertEquals(originalName, results.get(0).getPersonName());
+
+
+ // Find by greater than and less than clause over non row key
String findAgeByGTELTEClause = "Select p from PersonRedis p where p.age <=:max AND p.age>=:min";
query = em.createQuery(findAgeByGTELTEClause);
query.setParameter("min", 32);
@@ -145,6 +163,49 @@ public void testPopulateEntites()
Assert.assertNotNull(qhex);
}
+ // More than TWO AND clause
+ // OR Clause
+
+ // Find without where clause on SELECTIVE COLUMN TODOOOOOOOOOOOOOOOOOOOOOOO.
+ String findSelective = "Select p.age from PersonRedis p";
+ query = em.createQuery(findSelective);
+ results = query.getResultList();
+ Assert.assertEquals(3, results.size());
+
+ // Find by key and now row key
+ String findByIdOrAge = "Select p from PersonRedis p where p.personId=:personId OR p.age=:age";
+ query = em.createQuery(findByIdOrAge);
+ query.setParameter("personId", ROW_KEY);
+ query.setParameter("age", 29);
+
+ results = query.getResultList();
+ Assert.assertEquals(2, results.size());
+ Assert.assertEquals(originalName, results.get(0).getPersonName());
+ boolean isPresent=false;
+ for(PersonRedis r : results)
+ {
+ if(r.getAge().equals(29) && !r.getPersonId().equals(ROW_KEY))
+ {
+ isPresent=true;
+ break;
+ }
+ }
+
+ Assert.assertTrue(isPresent);
+
+
+ String findByIdMoreOrAge = "Select p from PersonRedis p where p.personId=:personId OR p.age=:age OR p.personName=:personName";
+ query = em.createQuery(findByIdMoreOrAge);
+ query.setParameter("personId", ROW_KEY);
+ query.setParameter("age", 29);
+ query.setParameter("personName", originalName);
+
+ results = query.getResultList();
+ Assert.assertEquals(3, results.size());
+ Assert.assertEquals(originalName, results.get(0).getPersonName());
+
+ // TODOOOO: selective column search
+
// Delete by query.
String deleteQuery="Delete from PersonRedis p";
query = em.createQuery(deleteQuery);
Please sign in to comment.
Something went wrong with that request. Please try again.