@NotNull public static IgniteQuery generateSql(Method mtd, RepositoryMetadata metadata) {
PartTree parts = new PartTree(mtd.getName(), metadata.getDomainType());
+ boolean isCountOrFieldQuery = parts.isCountProjection();
+
StringBuilder sql = new StringBuilder();
- if (parts.isDelete())
- throw new UnsupportedOperationException("DELETE clause is not supported now.");
+ if (parts.isDelete()) {
+ sql.append("DELETE ");
+
+ // For the DML queries aside from SELECT *, they should run over SqlFieldQuery
+ isCountOrFieldQuery = true;
+ }
else {
sql.append("SELECT ");
if (parts.isDistinct())
throw new UnsupportedOperationException("DISTINCT clause in not supported.");
- if (parts.isCountProjection())
+ if (isCountOrFieldQuery)
sql.append("COUNT(1) ");
else
sql.append(" * ");
sql.append(parts.getMaxResults().intValue());
}
- return new IgniteQuery(sql.toString(), parts.isCountProjection(), getOptions(mtd));
+ return new IgniteQuery(sql.toString(), isCountOrFieldQuery, getOptions(mtd));
}
/**
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
*/
@Nullable private Object transformQueryCursor(Object[] prmtrs, QueryCursor qryCursor) {
if (this.qry.isFieldQuery()) {
- Iterable<ArrayList> qryIter = (Iterable<ArrayList>)qryCursor;
+ Iterable<List> qryIter = (Iterable<List>)qryCursor;
switch (returnStgy) {
case LIST_OF_VALUES:
- ArrayList list = new ArrayList();
+ List list = new ArrayList<>();
- for (ArrayList entry : qryIter)
+ for (List entry : qryIter)
list.add(entry.get(0));
return list;
case ONE_VALUE:
- Iterator<ArrayList> iter = qryIter.iterator();
+ Iterator<List> iter = qryIter.iterator();
if (iter.hasNext())
return iter.next().get(0);
return null;
case SLICE_OF_VALUES:
- ArrayList content = new ArrayList();
+ List content = new ArrayList<>();
- for (ArrayList entry : qryIter)
+ for (List entry : qryIter)
content.add(entry.get(0));
return new SliceImpl(content, (Pageable)prmtrs[prmtrs.length - 1], true);
switch (returnStgy) {
case LIST_OF_VALUES:
- ArrayList list = new ArrayList();
+ List list = new ArrayList<>();
for (CacheEntryImpl entry : qryIter)
list.add(entry.getValue());
return null;
case SLICE_OF_VALUES:
- ArrayList content = new ArrayList();
+ List content = new ArrayList<>();
for (CacheEntryImpl entry : qryIter)
content.add(entry.getValue());
/**
* @param qry Query string.
- * @return {@code true} if query is SQLFieldsQuery.
+ * @return {@code true} if query is SqlFieldsQuery.
*/
private boolean isFieldQuery(String qry) {
- return qry.matches("^SELECT.*") && !qry.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
+ return isStatement(qry) && !qry.matches("^SELECT\\s+(?:\\w+\\.)?+\\*.*");
+ }
+
+ /**
+ * Evaluates if the query starts with a clause.<br>
+ * <code>SELECT, INSERT, UPDATE, MERGE, DELETE</code>
+ *
+ * @param qry Query string.
+ * @return {@code true} if query is full SQL statement.
+ */
+ private boolean isStatement(String qry) {
+ return qry.matches("^SELECT.*") || qry.matches("^UPDATE.*") || qry.matches("^DELETE.*") ||
+ qry.matches("^MERGE.*") || qry.matches("^INSERT.*");
}
}
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
+import java.util.List;
import java.util.Optional;
import java.util.TreeSet;
import org.apache.ignite.springdata.misc.ApplicationConfiguration;
super.afterTest();
}
+ /**
+ *
+ */
+ private void fillInRepository() {
+ for (int i = 0; i < CACHE_SIZE - 5; i++) {
+ repo.save(i, new Person("person" + Integer.toHexString(i),
+ "lastName" + Integer.toHexString((i + 16) % 256)));
+ }
+
+ repo.save((int) repo.count(), new Person("uniquePerson", "uniqueLastName"));
+ repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+ repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+ repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+ repo.save((int) repo.count(), new Person("nonUniquePerson", "nonUniqueLastName"));
+ }
+
/** {@inheritDoc} */
@Override protected void afterTestsStopped() throws Exception {
ctx.destroy();
}
/**
- *
+ * Delete existing record
*/
- private void fillInRepository() {
- for (int i = 0; i < CACHE_SIZE; i++) {
- repo.save(i, new Person("person" + Integer.toHexString(i),
- "lastName" + Integer.toHexString((i + 16) % 256)));
+ @Test
+ public void testDeleteByFirstName() {
+ assertEquals(repo.countByFirstNameLike("uniquePerson"), 1);
+
+ long cnt = repo.deleteByFirstName("uniquePerson");
+
+ assertEquals(1, cnt);
+ }
+
+ /**
+ * Delete NON existing record
+ */
+ @Test
+ public void testDeleteExpression() {
+ long cnt = repo.deleteByFirstName("880");
+
+ assertEquals(0, cnt);
+ }
+
+ /**
+ * Delete Multiple records due to where
+ */
+ @Test
+ public void testDeleteExpressionMultiple() {
+ long count = repo.countByFirstName("nonUniquePerson");
+ long cnt = repo.deleteByFirstName("nonUniquePerson");
+
+ assertEquals(cnt, count);
+ }
+
+ /**
+ * Remove should do the same than Delete
+ */
+ @Test
+ public void testRemoveExpression() {
+ repo.removeByFirstName("person3f");
+
+ long count = repo.count();
+ assertEquals(CACHE_SIZE - 1, count);
+ }
+
+ /**
+ * Delete unique record
+ */
+ @Test
+ public void testDeleteQuery() {
+ repo.deleteBySecondNameQuery("uniqueLastName");
+
+ long countAfter = repo.count();
+ assertEquals(CACHE_SIZE - 1, countAfter);
+ }
+
+ /**
+ * Try to delete with a wrong @Query
+ */
+ @Test
+ public void testWrongDeleteQuery() {
+ long countBefore = repo.countByFirstNameLike("person3f");
+
+ try {
+ repo.deleteWrongByFirstNameQuery("person3f");
+ }
+ catch (Exception e) {
+ //expected
}
+
+ long countAfter = repo.countByFirstNameLike("person3f");
+ assertEquals(countBefore, countAfter);
+ }
+
+ /**
+ * Update with a @Query a record
+ */
+ @Test
+ public void testUpdateQuery() {
+ final String newSecondName = "updatedUniqueSecondName";
+ int cnt = repo.setFixedSecondNameFor(newSecondName, "uniquePerson");
+
+ assertEquals(1, cnt);
+
+ List<Person> person = repo.findByFirstName("uniquePerson");
+ assertEquals(person.get(0).getSecondName(), "updatedUniqueSecondName");
+ }
+
+ /**
+ * Update with a wrong @Query
+ */
+ @Test
+ public void testWrongUpdateQuery() {
+ final String newSecondName = "updatedUniqueSecondName";
+ int rowsUpdated = 0;
+ try {
+ rowsUpdated = repo.setWrongFixedSecondName(newSecondName, "uniquePerson");
+ }
+ catch (Exception e) {
+ //expected
+ }
+
+ assertEquals(0, rowsUpdated);
+
+ List<Person> person = repo.findByFirstName("uniquePerson");
+ assertEquals(person.get(0).getSecondName(), "uniqueLastName");
}
}
public Iterable<Person> findFirst10ByFirstNameLike(String val);
/** */
+ public int countByFirstName(String val);
+
+ /** */
public int countByFirstNameLike(String val);
/** */
/** */
@Query("SELECT count(1) FROM (SELECT DISTINCT secondName FROM Person WHERE firstName REGEXP ?)")
public int countQuery(String val);
+
+ /** Top 3 query */
+ public List<Person> findTop3ByFirstName(String val);
+
+ /** Delete query */
+ public long deleteByFirstName(String firstName);
+
+ /** Remove Query */
+ public List<Person> removeByFirstName(String firstName);
+
+ /** Delete using @Query */
+ @Query("DELETE FROM Person WHERE secondName = ?")
+ public void deleteBySecondNameQuery(String secondName);
+
+ /** Delete using @Query but with errors on the query */
+ @Query("DELETE FROM Person WHERE firstName = ? AND ERRORS = 'ERRORS'")
+ public void deleteWrongByFirstNameQuery(String firstName);
+
+ /** Update using @Query */
+ @Query("UPDATE Person SET secondName = ? WHERE firstName = ?")
+ public int setFixedSecondNameFor(String secondName, String firstName);
+
+ /** Update using @Query but with errors on the query */
+ @Query("UPDATE Person SET secondName = ? WHERE firstName = ? AND ERRORS = 'ERRORS'")
+ public int setWrongFixedSecondName(String secondName, String firstName);
}