package org.infinispan.query.dsl.embedded;
import static org.testng.AssertJUnit.assertEquals;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.cache.Index;
import org.infinispan.objectfilter.ParsingException;
import org.infinispan.query.dsl.Query;
import org.infinispan.query.dsl.QueryFactory;
import org.infinispan.query.dsl.embedded.testdomain.Address;
import org.infinispan.query.dsl.embedded.testdomain.Transaction;
import org.infinispan.query.dsl.embedded.testdomain.User;
import org.infinispan.test.fwk.TestCacheManagerFactory;
import org.infinispan.transaction.TransactionMode;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Test string-based queries.
*
* @author anistor@redhat.com
* @since 9.0
*/
@Test(groups = {"functional", "smoke"}, testName = "query.dsl.embedded.QueryStringTest")
public class QueryStringTest extends AbstractQueryDslTest {
@Override
protected void createCacheManagers() throws Throwable {
ConfigurationBuilder cfg = TestCacheManagerFactory.getDefaultCacheConfiguration(true);
cfg.transaction()
.transactionMode(TransactionMode.TRANSACTIONAL)
.indexing().index(Index.ALL)
.addIndexedEntity(getModelFactory().getUserImplClass())
.addIndexedEntity(getModelFactory().getAccountImplClass())
.addIndexedEntity(getModelFactory().getTransactionImplClass())
.addProperty("default.directory_provider", "ram")
.addProperty("lucene_version", "LUCENE_CURRENT");
createClusteredCaches(1, cfg);
}
@BeforeClass(alwaysRun = true)
protected void populateCache() throws Exception {
User user1 = getModelFactory().makeUser();
user1.setId(1);
user1.setName("John");
user1.setSurname("Doe");
user1.setGender(User.Gender.MALE);
user1.setAge(22);
user1.setAccountIds(new HashSet<>(Arrays.asList(1, 2)));
user1.setNotes("Lorem ipsum dolor sit amet");
Address address1 = getModelFactory().makeAddress();
address1.setStreet("Main Street");
address1.setPostCode("X1234");
address1.setNumber(156);
user1.setAddresses(Collections.singletonList(address1));
User user2 = getModelFactory().makeUser();
user2.setId(2);
user2.setName("Spider");
user2.setSurname("Man");
user2.setGender(User.Gender.MALE);
user2.setAccountIds(Collections.singleton(3));
Address address2 = getModelFactory().makeAddress();
address2.setStreet("Old Street");
address2.setPostCode("Y12");
address2.setNumber(-12);
Address address3 = getModelFactory().makeAddress();
address3.setStreet("Bond Street");
address3.setPostCode("ZZ");
address3.setNumber(312);
user2.setAddresses(Arrays.asList(address2, address3));
User user3 = getModelFactory().makeUser();
user3.setId(3);
user3.setName("Spider");
user3.setSurname("Woman");
user3.setGender(User.Gender.FEMALE);
user3.setAccountIds(Collections.emptySet());
user3.setAddresses(new ArrayList<>());
Transaction transaction0 = getModelFactory().makeTransaction();
transaction0.setId(0);
transaction0.setDescription("Birthday present");
transaction0.setAccountId(1);
transaction0.setAmount(1800);
transaction0.setDate(makeDate("2012-09-07"));
transaction0.setDebit(false);
transaction0.setValid(true);
Transaction transaction1 = getModelFactory().makeTransaction();
transaction1.setId(1);
transaction1.setDescription("Feb. rent payment");
transaction1.setLongDescription("Feb. rent payment");
transaction1.setAccountId(1);
transaction1.setAmount(1500);
transaction1.setDate(makeDate("2013-01-05"));
transaction1.setDebit(true);
transaction1.setValid(true);
Transaction transaction2 = getModelFactory().makeTransaction();
transaction2.setId(2);
transaction2.setDescription("Starbucks");
transaction2.setLongDescription("Starbucks");
transaction2.setAccountId(1);
transaction2.setAmount(23);
transaction2.setDate(makeDate("2013-01-09"));
transaction2.setDebit(true);
transaction2.setValid(true);
Transaction transaction3 = getModelFactory().makeTransaction();
transaction3.setId(3);
transaction3.setDescription("Hotel");
transaction3.setAccountId(2);
transaction3.setAmount(45);
transaction3.setDate(makeDate("2013-02-27"));
transaction3.setDebit(true);
transaction3.setValid(true);
Transaction transaction4 = getModelFactory().makeTransaction();
transaction4.setId(4);
transaction4.setDescription("Last january");
transaction4.setLongDescription("Last january");
transaction4.setAccountId(2);
transaction4.setAmount(95);
transaction4.setDate(makeDate("2013-01-31"));
transaction4.setDebit(true);
transaction4.setValid(true);
Transaction transaction5 = getModelFactory().makeTransaction();
transaction5.setId(5);
transaction5.setDescription("-Popcorn");
transaction5.setLongDescription("-Popcorn");
transaction5.setAccountId(2);
transaction5.setAmount(5);
transaction5.setDate(makeDate("2013-01-01"));
transaction5.setDebit(true);
transaction5.setValid(true);
// persist and index the test objects
// we put all of them in the same cache for the sake of simplicity
getCacheForWrite().put("user_" + user1.getId(), user1);
getCacheForWrite().put("user_" + user2.getId(), user2);
getCacheForWrite().put("user_" + user3.getId(), user3);
getCacheForWrite().put("transaction_" + transaction0.getId(), transaction0);
getCacheForWrite().put("transaction_" + transaction1.getId(), transaction1);
getCacheForWrite().put("transaction_" + transaction2.getId(), transaction2);
getCacheForWrite().put("transaction_" + transaction3.getId(), transaction3);
getCacheForWrite().put("transaction_" + transaction4.getId(), transaction4);
getCacheForWrite().put("transaction_" + transaction5.getId(), transaction5);
for (int i = 0; i < 50; i++) {
Transaction transaction = getModelFactory().makeTransaction();
transaction.setId(50 + i);
transaction.setDescription("Expensive shoes " + i);
transaction.setLongDescription("Expensive shoes. Just beer, really " + i);
transaction.setAccountId(2);
transaction.setAmount(100 + i);
transaction.setDate(makeDate("2013-08-20"));
transaction.setDebit(true);
transaction.setValid(true);
getCacheForWrite().put("transaction_" + transaction.getId(), transaction);
}
}
public void testParam() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " where id = :idParam");
q.setParameter("idParam", 1);
List<Transaction> list = q.list();
assertEquals(1, list.size());
assertEquals(1, list.get(0).getId());
q.setParameter("idParam", 2);
list = q.list();
assertEquals(1, list.size());
assertEquals(2, list.get(0).getId());
}
@Test(enabled = false)
public void testParamWithSpacePadding() throws Exception {
QueryFactory qf = getQueryFactory();
//todo [anistor] need special tree nodes for all literal types (and for params) to be able to distinguish them better; QueryRendererDelegate.predicateXXX should receive such a tree node instead of a string
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " where id = : idParam");
List<Transaction> list = q.list();
assertEquals(1, list.size());
}
public void testExactMatch() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " where description = 'Birthday present'");
List<Transaction> list = q.list();
assertEquals(1, list.size());
}
public void testFullTextTerm() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " where longDescription:'rent'");
List<Transaction> list = q.list();
assertEquals(1, list.size());
}
public void testFullTextTermRightOperandAnalyzed() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " where longDescription:'RENT'");
List<Transaction> list = q.list();
assertEquals(1, list.size());
}
public void testFullTextTermBoost() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " where longDescription:('rent'^8 'shoes')");
List<Transaction> list = q.list();
assertEquals(51, list.size());
}
public void testFullTextPhrase() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " where longDescription:'expensive shoes'");
List<Transaction> list = q.list();
assertEquals(50, list.size());
}
public void testFullTextWithAggregation() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("select t.accountId, max(t.amount), max(t.description) from " + getModelFactory().getTransactionTypeName()
+ " t where t.longDescription : (+'beer' && -'food') group by t.accountId");
List<Object[]> list = q.list();
assertEquals(1, list.size());
assertEquals(2, list.get(0)[0]);
assertEquals(149.0, list.get(0)[1]);
assertEquals("Expensive shoes 9", list.get(0)[2]);
}
public void testFullTextTermBoostAndSorting() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " where longDescription:('rent'^8 'shoes') order by amount");
List<Transaction> list = q.list();
assertEquals(51, list.size());
}
public void testFullTextTermOccur() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where not (t.longDescription : (+'failed') or t.longDescription : 'blocked')");
List<Transaction> list = q.list();
assertEquals(56, list.size());
}
public void testFullTextTermDoesntOccur() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : (-'really')");
List<Transaction> list = q.list();
assertEquals(6, list.size());
}
public void testFullTextRangeWildcard() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : [* to *]");
List<Transaction> list = q.list();
assertEquals(54, list.size());
}
public void testFullTextRange() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.amount : [23 to 45]");
List<Transaction> list = q.list();
assertEquals(2, list.size());
}
public void testFullTextPrefix() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : 'ren*'");
List<Transaction> list = q.list();
assertEquals(1, list.size());
}
public void testFullTextWildcard() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : 're?t'");
List<Transaction> list = q.list();
assertEquals(1, list.size());
}
@Test(expectedExceptions = ParsingException.class, expectedExceptionsMessageRegExp = "ISPN014036: Prefix, wildcard or regexp queries cannot be fuzzy.*")
public void testFullTextWildcardFuzzyNotAllowed() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : 're?t'~2");
q.list();
}
public void testFullTextFuzzy() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : 'retn'~");
List<Transaction> list = q.list();
assertEquals(1, list.size());
}
public void testFullTextFuzzyDefaultEdits() throws Exception {
QueryFactory qf = getQueryFactory();
// default number of edits should be 2
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : 'ertn'~");
List<Transaction> list = q.list();
assertEquals(1, list.size());
q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : 'ajunayr'~");
list = q.list();
assertEquals(0, list.size());
}
public void testFullTextFuzzySpecifiedEdits() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : 'ajnuary'~1");
List<Transaction> list = q.list();
assertEquals(1, list.size());
q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : 'ajunary'~1");
list = q.list();
assertEquals(0, list.size());
}
public void testFullTextRegexp() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : /[R|r]ent/");
List<Transaction> list = q.list();
assertEquals(1, list.size());
}
@Test(expectedExceptions = ParsingException.class, expectedExceptionsMessageRegExp = "ISPN028526: Invalid query.*")
public void testFullTextRegexpFuzzyNotAllowed() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : /[R|r]ent/~2");
q.list();
}
@Test(expectedExceptions = ParsingException.class, expectedExceptionsMessageRegExp = "ISPN028522: .*property is analyzed.*")
public void testExactMatchOnAnalyzedFieldNotAllowed() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " where longDescription = 'Birthday present'");
q.list();
}
@Test(expectedExceptions = ParsingException.class, expectedExceptionsMessageRegExp = "ISPN028521: .*unless the property is indexed and analyzed.*")
public void testFullTextTermOnNonAnalyzedFieldNotAllowed() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " where description:'rent'");
q.list();
}
@Test(enabled = false) //TODO [anistor] fix!
public void testFullTextRegexp2() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getTransactionTypeName() + " t where t.longDescription : ( -'beer' and '*')");
List<Transaction> list = q.list();
assertEquals(1, list.size());
}
public void testInstant1() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getUserTypeName() + " u where u.creationDate = '2011-12-03T10:15:30Z'");
List<User> list = q.list();
assertEquals(3, list.size());
}
public void testInstant2() throws Exception {
QueryFactory qf = getQueryFactory();
Query q = qf.create("from " + getModelFactory().getUserTypeName() + " u where u.passwordExpirationDate = '2011-12-03T10:15:30Z'");
List<User> list = q.list();
assertEquals(3, list.size());
}
}