Remove template dependency from string n1ql, also fix StringN1ql tests.

Closes #1470.
This commit is contained in:
Michael Reiche
2022-06-17 12:19:08 -07:00
parent 30a0b8858f
commit dbd431332b
8 changed files with 99 additions and 137 deletions

View File

@@ -17,18 +17,12 @@ package org.springframework.data.couchbase.repository.query;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_TEMPLATE;
import java.lang.reflect.Method;
import java.util.Properties;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
import org.springframework.data.couchbase.core.CouchbaseTemplate;
import org.springframework.data.couchbase.core.convert.CouchbaseConverter;
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
import org.springframework.data.couchbase.core.mapping.CouchbaseMappingContext;
@@ -37,8 +31,6 @@ import org.springframework.data.couchbase.core.mapping.CouchbasePersistentProper
import org.springframework.data.couchbase.core.query.Query;
import org.springframework.data.couchbase.domain.User;
import org.springframework.data.couchbase.domain.UserRepository;
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
import org.springframework.data.couchbase.util.ClusterAwareIntegrationTests;
import org.springframework.data.mapping.context.MappingContext;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
import org.springframework.data.repository.core.NamedQueries;
@@ -51,69 +43,20 @@ import org.springframework.data.repository.query.ParametersParameterAccessor;
import org.springframework.data.repository.query.QueryMethodEvaluationContextProvider;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import com.couchbase.client.core.deps.io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import com.couchbase.client.core.env.SecurityConfig;
import com.couchbase.client.java.env.ClusterEnvironment;
/**
* @author Michael Nitschinger
* @author Michael Reiche
*/
class StringN1qlQueryCreatorMockedTests extends ClusterAwareIntegrationTests {
class StringN1qlQueryCreatorTests {
MappingContext<? extends CouchbasePersistentEntity<?>, CouchbasePersistentProperty> context;
CouchbaseConverter converter;
CouchbaseTemplate couchbaseTemplate;
static NamedQueries namedQueries = new PropertiesBasedNamedQueries(new Properties());
@BeforeEach
public void beforeEach() {
context = new CouchbaseMappingContext();
converter = new MappingCouchbaseConverter(context);
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);
couchbaseTemplate = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE);
}
@Test
void createsQueryCorrectly() throws Exception {
String input = "getByFirstnameAndLastname";
Method method = UserRepository.class.getMethod(input, String.class, String.class);
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
converter.getMappingContext());
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver", "Twist"),
queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
Query query = creator.createQuery();
assertEquals(
"SELECT `_class`, META(`" + bucketName()
+ "`).`cas` AS __cas, `createdBy`, `createdDate`, `lastModifiedBy`, `lastModifiedDate`, META(`"
+ bucketName() + "`).`id` AS __id, `firstname`, `lastname`, `subtype` FROM `" + bucketName()
+ "` where `_class` = \"abstractuser\" and firstname = $1 and lastname = $2",
query.toN1qlSelectString(couchbaseTemplate.reactive(), null, null, User.class, User.class, false, null, null));
}
@Test
void createsQueryCorrectly2() throws Exception {
String input = "getByFirstnameOrLastname";
Method method = UserRepository.class.getMethod(input, String.class, String.class);
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
converter.getMappingContext());
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver", "Twist"),
queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
Query query = creator.createQuery();
assertEquals(
"SELECT `_class`, META(`" + bucketName()
+ "`).`cas` AS __cas, `createdBy`, `createdDate`, `lastModifiedBy`, `lastModifiedDate`, META(`"
+ bucketName() + "`).`id` AS __id, `firstname`, `lastname`, `subtype` FROM `" + bucketName()
+ "` where `_class` = \"abstractuser\" and (firstname = $first or lastname = $last)",
query.toN1qlSelectString(couchbaseTemplate.reactive(), null, null, User.class, User.class, false, null, null));
}
@Test
@@ -153,6 +96,48 @@ class StringN1qlQueryCreatorMockedTests extends ClusterAwareIntegrationTests {
fail("should have failed with IllegalArgumentException: query has no inline Query or named Query not found");
}
@Test
void createsQueryCorrectly() throws Exception {
String input = "getByFirstnameAndLastname";
Method method = UserRepository.class.getMethod(input, String.class, String.class);
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
converter.getMappingContext());
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver", "Twist"),
queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
Query query = creator.createQuery();
assertEquals(
"SELECT `_class`, META(`" + bucketName()
+ "`).`cas` AS __cas, `createdBy`, `createdDate`, `lastModifiedBy`, `lastModifiedDate`, META(`"
+ bucketName() + "`).`id` AS __id, `firstname`, `lastname`, `subtype` FROM `" + bucketName()
+ "` where `_class` = \"abstractuser\" and firstname = $1 and lastname = $2",
query.toN1qlSelectString(converter, bucketName(), null, null, User.class, User.class, false, null, null));
}
@Test
void createsQueryCorrectly2() throws Exception {
String input = "getByFirstnameOrLastname";
Method method = UserRepository.class.getMethod(input, String.class, String.class);
CouchbaseQueryMethod queryMethod = new CouchbaseQueryMethod(method,
new DefaultRepositoryMetadata(UserRepository.class), new SpelAwareProxyProjectionFactory(),
converter.getMappingContext());
StringN1qlQueryCreator creator = new StringN1qlQueryCreator(getAccessor(getParameters(method), "Oliver", "Twist"),
queryMethod, converter, new SpelExpressionParser(), QueryMethodEvaluationContextProvider.DEFAULT, namedQueries);
Query query = creator.createQuery();
assertEquals(
"SELECT `_class`, META(`" + bucketName()
+ "`).`cas` AS __cas, `createdBy`, `createdDate`, `lastModifiedBy`, `lastModifiedDate`, META(`"
+ bucketName() + "`).`id` AS __id, `firstname`, `lastname`, `subtype` FROM `" + bucketName()
+ "` where `_class` = \"abstractuser\" and (firstname = $first or lastname = $last)",
query.toN1qlSelectString(converter, bucketName(), null, null, User.class, User.class, false, null, null));
}
@Test
void spelTests() throws Exception {
String input = "spelTests";
@@ -166,10 +151,17 @@ class StringN1qlQueryCreatorMockedTests extends ClusterAwareIntegrationTests {
Query query = creator.createQuery();
String s = query.toN1qlSelectString(couchbaseTemplate.reactive(), "myScope", "myCollection", User.class, null,
false, null, null);
System.out.println("query: " + s);
assertEquals(
"SELECT `_class`, META(`myCollection`).`cas` AS __cas, `createdBy`, `createdDate`, "
+ "`lastModifiedBy`, `lastModifiedDate`, META(`myCollection`).`id` AS __id, `firstname`, "
+ "`lastname`, `subtype` FROM `myCollection`|`_class` = \"abstractuser\""
+ "|`myCollection`|`myScope`|`myCollection`",
query.toN1qlSelectString(converter, bucketName(), "myScope", "myCollection", User.class, null, false, null,
null));
}
private String bucketName() {
return "some_bucket";
}
private ParameterAccessor getAccessor(Parameters<?, ?> params, Object... values) {
@@ -180,37 +172,4 @@ class StringN1qlQueryCreatorMockedTests extends ClusterAwareIntegrationTests {
return new DefaultParameters(method);
}
@Configuration
@EnableCouchbaseRepositories("org.springframework.data.couchbase")
static class Config extends AbstractCouchbaseConfiguration {
@Override
public String getConnectionString() {
return connectionString();
}
@Override
public String getUserName() {
return config().adminUsername();
}
@Override
public String getPassword() {
return config().adminPassword();
}
@Override
public String getBucketName() {
return bucketName();
}
@Override
protected void configureEnvironment(ClusterEnvironment.Builder builder) {
if (config().isUsingCloud()) {
builder.securityConfig(
SecurityConfig.builder().trustManagerFactory(InsecureTrustManagerFactory.INSTANCE).enableTls(true));
}
}
}
}

View File

@@ -27,8 +27,6 @@ import static org.springframework.data.couchbase.config.BeanNames.COUCHBASE_TEMP
import static org.springframework.data.couchbase.config.BeanNames.REACTIVE_COUCHBASE_TEMPLATE;
import static org.springframework.data.couchbase.util.Util.waitUntilCondition;
import com.couchbase.client.core.retry.BestEffortRetryStrategy;
import com.couchbase.client.core.retry.RetryStrategy;
import okhttp3.Credentials;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;