Skip to content

Commit

Permalink
Add keyword Before for query method, #144. (#165)
Browse files Browse the repository at this point in the history
Signed-off-by: Pan Li <panli@microsoft.com>
  • Loading branch information
Incarnation-p-lee committed Aug 17, 2018
1 parent 6bfef84 commit 61a4929
Show file tree
Hide file tree
Showing 15 changed files with 170 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,7 @@ private Constants() {

public static final String SQL_KEYWORD_AND = "AND";
public static final String SQL_KEYWORD_OR = "OR";
public static final String SQL_KEYWORD_IS_EQUAL = "=";
public static final String SQL_KEYWORD_BEFORE = "<";
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
*/
package com.microsoft.azure.spring.data.cosmosdb.core.generator;

import com.microsoft.azure.spring.data.cosmosdb.core.convert.MappingDocumentDbConverter;
import com.microsoft.azure.spring.data.cosmosdb.core.query.Criteria;
import com.microsoft.azure.spring.data.cosmosdb.core.query.CriteriaType;
import com.microsoft.azure.spring.data.cosmosdb.core.query.DocumentQuery;
Expand All @@ -20,30 +21,31 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public abstract class AbstractQueryGenerator {

private String generateIsEqual(@NonNull Criteria criteria, @NonNull List<Pair<String, Object>> parameters) {
final String subject = criteria.getSubject();
private String generateUnaryQuery(@NonNull Criteria criteria, @NonNull List<Pair<String, Object>> parameters) {
Assert.isTrue(criteria.getSubjectValues().size() == 1, "Unary criteria should have only one subject value");
Assert.isTrue(CriteriaType.isUnary(criteria.getType()), "Criteria type should be unary operation");

Assert.isTrue(criteria.getSubjectValues().size() == 1, "IS_EQUAL should have only one subject value");
final String subject = criteria.getSubject();
final Object subjectValue = MappingDocumentDbConverter.toDocumentDBValue(criteria.getSubjectValues().get(0));

parameters.add(Pair.with(subject, criteria.getSubjectValues().get(0)));
parameters.add(Pair.with(subject, subjectValue));

return String.format("r.%s=@%s", subject, subject);
return String.format("r.%s%s@%s", subject, criteria.getType().getSqlKeyword(), subject);
}

private String generateBinaryQuery(@NonNull String left, @NonNull String right, CriteriaType type) {
Assert.isTrue(Criteria.isBinaryOperation(type), "Criteria type should be binary operation");

final String keyword = CriteriaType.toSqlKeyword(type);
Assert.isTrue(CriteriaType.isBinary(type), "Criteria type should be binary operation");

return String.join(" ", left, keyword, right);
return String.join(" ", left, type.getSqlKeyword(), right);
}

private String generateQueryBody(@NonNull Criteria criteria, @NonNull List<Pair<String, Object>> parameters) {
final CriteriaType type = criteria.getType();

switch (type) {
case IS_EQUAL:
return this.generateIsEqual(criteria, parameters);
case BEFORE:
return this.generateUnaryQuery(criteria, parameters);
case AND:
case OR:
Assert.isTrue(criteria.getSubCriteria().size() == 2, "criteria should have two SubCriteria");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,27 +25,8 @@ private Criteria(CriteriaType type) {
this.subCriteria = new ArrayList<>();
}

public static boolean isBinaryOperation(CriteriaType type) {
switch (type) {
case AND:
case OR:
return true;
default:
return false;
}
}

public static boolean isUnaryOperation(CriteriaType type) {
switch (type) {
case IS_EQUAL:
return true;
default:
return false;
}
}

public static Criteria getUnaryInstance(CriteriaType type, @NonNull String subject, @NonNull List<Object> values) {
Assert.isTrue(isUnaryOperation(type), "type should be Unary operation");
Assert.isTrue(CriteriaType.isUnary(type), "type should be Unary operation");

final Criteria criteria = new Criteria(type);

Expand All @@ -56,7 +37,7 @@ public static Criteria getUnaryInstance(CriteriaType type, @NonNull String subje
}

public static Criteria getBinaryInstance(CriteriaType type, @NonNull Criteria left, @NonNull Criteria right) {
Assert.isTrue(isBinaryOperation(type), "type should be Binary operation");
Assert.isTrue(CriteriaType.isBinary(type), "type should be Binary operation");

final Criteria criteria = new Criteria(type);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,41 +5,98 @@
*/
package com.microsoft.azure.spring.data.cosmosdb.core.query;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NonNull;
import org.springframework.data.repository.query.parser.Part;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import static com.microsoft.azure.spring.data.cosmosdb.Constants.SQL_KEYWORD_AND;
import static com.microsoft.azure.spring.data.cosmosdb.Constants.SQL_KEYWORD_OR;
import static com.microsoft.azure.spring.data.cosmosdb.Constants.*;

@AllArgsConstructor
public enum CriteriaType {
IS_EQUAL,
OR,
AND;
IS_EQUAL(SQL_KEYWORD_IS_EQUAL),
OR(SQL_KEYWORD_OR),
AND(SQL_KEYWORD_AND),
BEFORE(SQL_KEYWORD_BEFORE);

@Getter
private static final Map<Part.Type, CriteriaType> criteriaMap;
private String sqlKeyword;

// Map Part.Type to CriteriaType
private static final Map<Part.Type, CriteriaType> PART_TREE_TYPE_TO_CRITERIA;

static {
final Map<Part.Type, CriteriaType> map = new HashMap<>();

map.put(Part.Type.SIMPLE_PROPERTY, CriteriaType.IS_EQUAL);
map.put(Part.Type.BEFORE, CriteriaType.BEFORE);

PART_TREE_TYPE_TO_CRITERIA = Collections.unmodifiableMap(map);
}

/**
* Check if PartType is NOT supported.
*
* @param partType
* @return True if unsupported, or false.
*/
public static boolean isPartTypeUnSupported(@NonNull Part.Type partType) {
return !isPartTypeSupported(partType);
}

/**
* Check if PartType is supported.
*
* @param partType
* @return True if supported, or false.
*/
public static boolean isPartTypeSupported(@NonNull Part.Type partType) {
return PART_TREE_TYPE_TO_CRITERIA.containsKey(partType);
}

criteriaMap = Collections.unmodifiableMap(map);
public static CriteriaType toCriteriaType(@NonNull Part.Type partType) {
final CriteriaType criteriaType = PART_TREE_TYPE_TO_CRITERIA.get(partType);

if (criteriaType == null) {
throw new UnsupportedOperationException("Unsupported part type: " + partType);
}

return criteriaType;
}

public static String toSqlKeyword(CriteriaType type) {
/**
* Check if CriteriaType operation contains two subjects.
*
* @param type
* @return True if contains, or false.
*/
public static boolean isBinary(CriteriaType type) {
switch (type) {
case AND:
return SQL_KEYWORD_AND;
case OR:
return SQL_KEYWORD_OR;
return true;
default:
throw new UnsupportedOperationException("Unsupported criteria type.");
return false;
}
}

/**
* Check if CriteriaType operation contains only one subjects.
*
* @param type
* @return True if contains, or false.
*/
public static boolean isUnary(CriteriaType type) {
switch (type) {
case IS_EQUAL:
case BEFORE:
return true;
default:
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,16 @@ protected Criteria create(Part part, Iterator<Object> parameters) {
final String subject = getSubject(part);
final List<Object> values = new ArrayList<>();

if (!CriteriaType.getCriteriaMap().containsKey(type)) {
throw new UnsupportedOperationException("Unsupported keyword: " + type.toString());
if (CriteriaType.isPartTypeUnSupported(type)) {
throw new UnsupportedOperationException("Unsupported keyword: " + type);
}

for (int i = 0; i < part.getNumberOfArguments(); i++) {
Assert.isTrue(parameters.hasNext(), "should not reach the end of iterator");
values.add(parameters.next());
}

return Criteria.getUnaryInstance(CriteriaType.getCriteriaMap().get(type), subject, values);
return Criteria.getUnaryInstance(CriteriaType.toCriteriaType(type), subject, values);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,11 @@ private TestConstants() {
"]}";

public static final String DB_NAME = "database_name_pli";
public static final String ID = "template_id_pli";
public static final String FIRST_NAME = "first_name_li";
public static final String LAST_NAME = "last_name_p";
public static final String NEW_ID = "new_id";
public static final String ID_1 = "id-1";
public static final String ID_2 = "id-2";
public static final String ID_3 = "id-3";
public static final String NEW_FIRST_NAME = "new_first_name";
public static final String NEW_LAST_NAME = "new_last_name";
public static final String UPDATED_FIRST_NAME = "updated_first_name";
Expand All @@ -86,8 +87,9 @@ private TestConstants() {
public static final String ROLE_NAME = "Developer";
public static final String NOT_EXIST_ID = "non_exist_id";

public static final String DATE_STRING = "1/1/2000";
public static final String NEW_DATE_STRING = "1/1/2001";
public static final String DATE_STRING = "8/8/2017";
public static final String DATE_BEFORE_STRING = "8/1/2017";
public static final String DATE_AFTER_STRING = "8/13/2017";
public static final String DATE_FORMAT = "dd/MM/yyyy";
public static final String DATE_TIMEZONE_STRING = "1/1/2000 00:00 GMT";
public static final String DATE_TIMEZONE_FORMAT = "dd/MM/yyyy HH:mm ZZZ";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@
@RunWith(SpringJUnit4ClassRunner.class)
@PropertySource(value = {"classpath:application.properties"})
public class DocumentDbTemplateIT {
private static final Person TEST_PERSON = new Person(TestConstants.ID, TestConstants.FIRST_NAME,
private static final Person TEST_PERSON = new Person(TestConstants.ID_1, TestConstants.FIRST_NAME,
TestConstants.LAST_NAME, TestConstants.HOBBIES, TestConstants.ADDRESSES);

private static final Person TEST_PERSON_2 = new Person(TestConstants.NEW_ID, TestConstants.NEW_FIRST_NAME,
private static final Person TEST_PERSON_2 = new Person(TestConstants.ID_2, TestConstants.NEW_FIRST_NAME,
TestConstants.NEW_LAST_NAME, TestConstants.HOBBIES, TestConstants.ADDRESSES);

@Value("${cosmosdb.uri}")
Expand Down Expand Up @@ -150,7 +150,6 @@ public void testDeleteById() {
assertTrue(result.get(0).equals(TEST_PERSON_2));
}


@Test
public void testDocumentDBAnnotation() {
final IndexingPolicy policy = collectionPerson.getIndexingPolicy();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
public class DocumentDbTemplateIllegalTest {
private static final String NULL_STR = null;
private static final String DUMMY_COLL = "dummy";
private static final String DUMMY_ID = "ID";
private static final String DUMMY_ID = "ID_1";
private static final PartitionKey DUMMY_KEY = new PartitionKey("dummy");
private static final String EMPTY_STR = StringUtils.EMPTY;
private static final String WHITESPACES_STR = " ";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ public class DocumentDbTemplatePartitionIT {
private static final String TEST_DB_NAME = "template_it_db";
private static final List<String> HOBBIES = TestConstants.HOBBIES;
private static final List<Address> ADDRESSES = TestConstants.ADDRESSES;
private static final Person TEST_PERSON = new Person(TestConstants.ID, TestConstants.FIRST_NAME,
private static final Person TEST_PERSON = new Person(TestConstants.ID_1, TestConstants.FIRST_NAME,
TestConstants.LAST_NAME, TestConstants.HOBBIES, TestConstants.ADDRESSES);

private static final Person TEST_PERSON_2 = new Person(TestConstants.NEW_ID, TestConstants.NEW_FIRST_NAME,
private static final Person TEST_PERSON_2 = new Person(TestConstants.ID_2, TestConstants.NEW_FIRST_NAME,
TEST_PERSON.getLastName(), TestConstants.HOBBIES, TestConstants.ADDRESSES);

@Value("${cosmosdb.uri}")
Expand Down Expand Up @@ -103,7 +103,7 @@ public void testFindWithPartition() {
assertThat(result.size()).isEqualTo(1);
assertEquals(result.get(0), TEST_PERSON);

criteria = Criteria.getUnaryInstance(IS_EQUAL, PROPERTY_ID, Arrays.asList(ID));
criteria = Criteria.getUnaryInstance(IS_EQUAL, PROPERTY_ID, Arrays.asList(ID_1));
query = new DocumentQuery(criteria);
result = dbTemplate.find(query, Person.class, Person.class.getSimpleName());

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public void convertDocumentToAddressCorrectly() {

@Test
public void canWritePojoWithDateToDocument() throws ParseException {
final Memo memo = new Memo(TestConstants.ID, TestConstants.MESSAGE, DATE.parse(TestConstants.DATE_STRING),
final Memo memo = new Memo(TestConstants.ID_1, TestConstants.MESSAGE, DATE.parse(TestConstants.DATE_STRING),
Importance.NORMAL);
final Document document = dbConverter.writeDoc(memo);

Expand All @@ -89,7 +89,7 @@ public void canWritePojoWithDateToDocument() throws ParseException {
@Test
public void canReadPojoWithDateFromDocument() throws ParseException {
final Document document = new Document();
document.setId(TestConstants.ID);
document.setId(TestConstants.ID_1);
document.set(TestConstants.PROPERTY_MESSAGE, TestConstants.MESSAGE);

final long date = DATE.parse(TestConstants.DATE_STRING).getTime();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void testUnaryCriteria() {
Assert.assertEquals(criteria.getSubjectValues(), values);
Assert.assertEquals(criteria.getType(), CriteriaType.IS_EQUAL);
Assert.assertEquals(criteria.getSubject(), CRITERIA_KEY);
Assert.assertTrue(Criteria.isUnaryOperation(criteria.getType()));
Assert.assertTrue(CriteriaType.isUnary(criteria.getType()));
}

@Test
Expand All @@ -39,7 +39,7 @@ public void testBinaryCriteria() {
Assert.assertNull(criteria.getSubjectValues());
Assert.assertNull(criteria.getSubject());
Assert.assertEquals(criteria.getType(), CriteriaType.AND);
Assert.assertTrue(Criteria.isBinaryOperation(criteria.getType()));
Assert.assertTrue(CriteriaType.isBinary(criteria.getType()));

Assert.assertEquals(criteria.getSubCriteria().size(), 2);
Assert.assertEquals(criteria.getSubCriteria().get(0), leftCriteria);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
@RunWith(MockitoJUnitRunner.class)
public class SimpleDocumentDbRepositoryUnitTest {
private static final Person TEST_PERSON =
new Person(TestConstants.ID, TestConstants.FIRST_NAME, TestConstants.LAST_NAME,
new Person(TestConstants.ID_1, TestConstants.FIRST_NAME, TestConstants.LAST_NAME,
TestConstants.HOBBIES, TestConstants.ADDRESSES);

private static final String PARTITION_VALUE_REQUIRED_MSG =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
@RunWith(SpringJUnit4ClassRunner.class)
@PropertySource(value = {"classpath:application.properties"})
public class DocumentDBAnnotationIT {
private static final Role TEST_ROLE = new Role(TestConstants.ID, TestConstants.LEVEL,
private static final Role TEST_ROLE = new Role(TestConstants.ID_1, TestConstants.LEVEL,
TestConstants.ROLE_NAME);

@Value("${cosmosdb.uri}")
Expand Down Expand Up @@ -97,7 +97,7 @@ public void testIndexingPolicyAnnotation() {
@Test
@SneakyThrows
public void testDocumentAnnotationTimeToLive() {
final TimeToLiveSample sample = new TimeToLiveSample(TestConstants.ID);
final TimeToLiveSample sample = new TimeToLiveSample(TestConstants.ID_1);
final Integer timeToLive = this.collectionExample.getDefaultTimeToLive();

Assert.notNull(timeToLive, "timeToLive should not be null");
Expand Down

0 comments on commit 61a4929

Please sign in to comment.