-
Notifications
You must be signed in to change notification settings - Fork 192
DATACOUCH-963 - Scope and collection api. #1071
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All repository-related changes violate the core ideas of Spring Data repositories to keep these as pure as possible. Introducing another 50 method overloads clutters the API and pulls in a level of abstraction that duplicates the Template API.
Specifying store-specific options can be done on the Template API.
import java.util.LinkedList; | ||
import java.util.List; | ||
|
||
public class MapList<K,V> extends HashMap<K, List<V>> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need for this one as Spring Framework ships with MultiValueMap
.
@@ -0,0 +1,14 @@ | |||
package org.springframework.data.couchbase.core.support; | |||
|
|||
public class ScopeName { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where possible, use immutable value objects.
|
||
public class CollectionName { | ||
String name; | ||
public CollectionName(String name){ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where possible, use immutable value objects.
|
||
@Override | ||
Optional<T> findById(ID id); | ||
Optional<T> findById(ID id, QueryOptions... options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is exactly what we want to avoid. The repository must not accept store-specific types as we do not want the calling code to interact with store specifics.
Store specifics at the Template API level are fine.
List<T> findAll(CollectionName collectionName, ScopeName... scopeNames); | ||
|
||
|
||
List<T> findAll(org.springframework.data.couchbase.core.query.Query query); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Introducing Query
makes the Repository somewhat pointless as this method duplicates what's possible on the Template API level.
81b6bb6
to
ce42488
Compare
…name. Queries on field annotated properties have original name. They should use getFieldName() which will use the annotated if it exists.
9f6b2c7
to
5050cf0
Compare
5050cf0
to
afe0bd2
Compare
* | ||
* @author Michael Nitschinger | ||
* @author Michael Reiche | ||
*/ | ||
@Repository | ||
public interface AirportRepository extends PagingAndSortingRepository<Airport, String> { | ||
@ScanConsistency(query = QueryScanConsistency.REQUEST_PLUS) | ||
public interface AirportRepository extends CouchbaseRepository<Airport, String>, DynamicProxyable<AirportRepository> { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PagingAndSortingRepository is from spring-data-common
CouchbaseRepository extends PagingAndSortingRepository. AirportRepository needs to extend DynamicProxyable to have the AirportRepository type.
@Override | ||
public RemoveByQueryInCollection<T> inScope(String scope) { | ||
return null; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed to return new ExecutableRemoveByQuerySupport<>()
afe0bd2
to
e974a8c
Compare
@@ -74,7 +74,7 @@ private SimpleCouchbaseClientFactory(final Supplier<Cluster> cluster, final Stri | |||
|
|||
@Override | |||
public CouchbaseClientFactory withScope(final String scopeName) { | |||
return new SimpleCouchbaseClientFactory(cluster, bucket.name(), scopeName); | |||
return new SimpleCouchbaseClientFactory(cluster, bucket.name(), scopeName != null ? scopeName : getScope().name()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is that change needed? Wouldn't this return the exact same instance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Edit: This is getting handled by the caller, so I've reverted this change.
If scopeName is null,
the old behavior would return a clientFactory with scope = _default
the new behavior returns a clientFactory with the same scope as the "this". (yes, it could actually return "this" instead of a new object - that is a better implementation).
This is to allow just using withScope(scopeName) without checking if scopeName is null.
/** | ||
* @param pseudoArgs - the metaArgs to set on the ThreadLocal field of the CouchbaseOperations | ||
*/ | ||
void setThrdLocalArgs(PseudoArgs<?> pseudoArgs); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we name this setThreadLocalArgs ? The two chars seem like a typo :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely.
@@ -59,7 +59,7 @@ ClusterType type() { | |||
|
|||
@Override | |||
TestClusterConfig _start() throws Exception { | |||
bucketname = UUID.randomUUID().toString(); | |||
bucketname = "my_bucket"; // UUID.randomUUID().toString(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why is this hardcoded now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the creation of multiple scopes and collections and the indexing, the initialization is getting long. This now reuses the bucket, scopes, collections etc. if they already exist.
if (postResponse.code() != 202) { | ||
throw new Exception("Could not create bucket: " + postResponse + ", Reason: " + postResponse.body().string()); | ||
String reason = postResponse.body().string(); | ||
if (postResponse.code() != 202 && !(reason.contains("Bucket with given name already exists"))) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this shouldn't exist with the uuid change above, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When reusing "my_bucket", 202(created) and "already exists" is acceptable, don't throw an exception.
@@ -107,6 +107,7 @@ public static void beforeAll() { | |||
ApplicationContext ac = new AnnotationConfigApplicationContext(Config.class); | |||
couchbaseTemplate = (CouchbaseTemplate) ac.getBean(COUCHBASE_TEMPLATE); | |||
reactiveCouchbaseTemplate = (ReactiveCouchbaseTemplate) ac.getBean(REACTIVE_COUCHBASE_TEMPLATE); | |||
System.err.println("JavaIntegrationTests.beforeAll() couchbaseTemplate: " + couchbaseTemplate); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should these be logged instead? because then you can turn it on off with the logger config, vs these will show up all the time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. I'll look for other System.out and change to log.debug
* @author Michael Reiche | ||
* @param <T> - the entity class | ||
*/ | ||
public interface WithScope<T> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the naming difference is odd - with vs. in
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes - it should match - InScope. Changing these an all the FindByQueryWithScope etc. interfaces to FindByQueryInScope etc.
import org.springframework.data.couchbase.core.query.Query; | ||
|
||
public class PseudoArgs<OPTS> { | ||
OPTS options; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
these should be private final?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still outstanding?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in local, needs push.
if (getParameters() != null) { | ||
if (getParameters() instanceof JsonArray) { | ||
options.parameters((JsonArray) getParameters()); | ||
} else { | ||
options.parameters((JsonObject) getParameters()); | ||
} | ||
} | ||
if (scanConsistency == null) { | ||
if (getScanConsistency() != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can be combined with &&
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still outstanding?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed locally. Need to push.
@@ -48,16 +52,18 @@ | |||
|
|||
} | |||
|
|||
interface ExistsByIdWithCollection extends TerminatingExistsById, WithCollection { | |||
interface ExistsByIdWithOptions<T> extends TerminatingExistsById, WithGetOptions<T> { | |||
TerminatingExistsById withOptions(GetOptions options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't that be ExistsOptions?
} | ||
|
||
static class ExecutableExistsByIdSupport implements ExecutableExistsById { | ||
|
||
private final CouchbaseTemplate template; | ||
private final String scope; | ||
private final String collection; | ||
private final GetOptions options; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ExistsOptions?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes. Similar issue with RemoveByQuery - it had RemoveOptions instead of QueryOptions - and in both cases the options were not passed in execution. Going through all the Reactive*OperationSupport classes to check for usage of options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added "options" tests that pass an options with timeout of 10 nanoseconds, resulting in a timeout.
e974a8c
to
d0da3a1
Compare
d0da3a1
to
d045e5e
Compare
d045e5e
to
7a9d533
Compare
7a9d533
to
71af4c7
Compare
71af4c7
to
cf60490
Compare
9af0782
to
3f1cea1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
found a couple things - also I noticed many of my questions did not have comments/answers, would be good to get clarifications on those as well (just look through the change they will pop up)
/** | ||
* Insert Operations | ||
* | ||
* @author Christoph Strobl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
copy/paste?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No - I tried to fill in some of the missing javadoc. From looking at javadoc on other classes that would have been created at the same time, I assumed the same author.
Assert.hasText(collection, "Collection must not be null nor empty."); | ||
return new ExecutableExistsByIdSupport(template, collection); | ||
public ExistsByIdWithOptions inCollection(final String collection) { | ||
return new ExecutableExistsByIdSupport(template, scope, collection, options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
was the assertion removed by accident? I wonder if it makes sense to validate those as well (also inScope)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At one point I removed the assertion to allow just calling without checking if the caller was using collections or not. That said - I put the assertion back in and all the tests pass - so it seems I'm not doing that anymore. I'll put it back for scope and collection.
/** | ||
* FindByAnalytics Operations | ||
* | ||
* @author Christoph Strobl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like some copy paste, you can put your name there if we want that at all
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to "back-date" the javadoc with the correct author.
/** | ||
* Get Operations | ||
* | ||
* @author Christoph Strobl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here, I'll stop pointing them out below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
if (getParameters() != null) { | ||
if (getParameters() instanceof JsonArray) { | ||
options.parameters((JsonArray) getParameters()); | ||
} else { | ||
options.parameters((JsonObject) getParameters()); | ||
} | ||
} | ||
if (scanConsistency == null) { | ||
if (getScanConsistency() != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still outstanding?
import org.springframework.data.couchbase.core.query.Query; | ||
|
||
public class PseudoArgs<OPTS> { | ||
OPTS options; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
still outstanding?
/** | ||
* @@return the options from the ThreadLocal field of the template | ||
*/ | ||
private OPTS getTlOptions(ReactiveCouchbaseTemplate template) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can those be also renamed to getThreadLocalOptions so it's not as confusing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed local, needs push.
@@ -47,7 +47,7 @@ public N1qlRepositoryQueryExecutor(final CouchbaseOperations operations, final C | |||
this.queryMethod = queryMethod; | |||
this.namedQueries = namedQueries; | |||
this.evaluationContextProvider = evaluationContextProvider; | |||
throw new RuntimeException("Deprecated"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
this.evaluationContextProvider = evaluationContextProvider; | ||
throw new RuntimeException("Deprecated"); | ||
this.evaluationContextProvider = QueryMethodEvaluationContextProvider.DEFAULT; | ||
//throw new RuntimeException("Deprecated"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
@@ -40,7 +40,7 @@ public ReactiveN1qlRepositoryQueryExecutor(final ReactiveCouchbaseOperations ope | |||
this.queryMethod = queryMethod; | |||
this.namedQueries = namedQueries; | |||
this.evaluationContextProvider = evaluationContextProvider; | |||
throw new RuntimeException("Deprecated"); | |||
//throw new RuntimeException("Deprecated"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
cf60490
to
5c88c3c
Compare
5c88c3c
to
d2b0b92
Compare
} | ||
|
||
static class ExecutableFindByAnalyticsSupport<T> implements ExecutableFindByAnalytics<T> { | ||
|
||
private final CouchbaseTemplate template; | ||
private final Class<T> domainType; | ||
private final Class<?> domainType; | ||
private final Class<T> returnType; | ||
private final ReactiveFindByAnalyticsSupport<T> reactiveSupport; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if returnType (for producing an object other than domainType) makes sense here, but it is in Query apis.
/** | ||
* Insert Operations | ||
* | ||
* @author Christoph Strobl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No - I tried to fill in some of the missing javadoc. From looking at javadoc on other classes that would have been created at the same time, I assumed the same author.
Assert.hasText(collection, "Collection must not be null nor empty."); | ||
return new ExecutableExistsByIdSupport(template, collection); | ||
public ExistsByIdWithOptions inCollection(final String collection) { | ||
return new ExecutableExistsByIdSupport(template, scope, collection, options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At one point I removed the assertion to allow just calling without checking if the caller was using collections or not. That said - I put the assertion back in and all the tests pass - so it seems I'm not doing that anymore. I'll put it back for scope and collection.
/** | ||
* FindByAnalytics Operations | ||
* | ||
* @author Christoph Strobl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was trying to "back-date" the javadoc with the correct author.
/** | ||
* Get Operations | ||
* | ||
* @author Christoph Strobl |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
if (getParameters() != null) { | ||
if (getParameters() instanceof JsonArray) { | ||
options.parameters((JsonArray) getParameters()); | ||
} else { | ||
options.parameters((JsonObject) getParameters()); | ||
} | ||
} | ||
if (scanConsistency == null) { | ||
if (getScanConsistency() != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed locally. Need to push.
import org.springframework.data.couchbase.core.query.Query; | ||
|
||
public class PseudoArgs<OPTS> { | ||
OPTS options; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed in local, needs push.
/** | ||
* @@return the options from the ThreadLocal field of the template | ||
*/ | ||
private OPTS getTlOptions(ReactiveCouchbaseTemplate template) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixed local, needs push.
Draft of changes for scope and collection API to share with Michael Nitschinger.
Some of the mechanisms in this change-set have been ruled out (the proliferation
of all the method signatures, for instance).
Closes #963
Original pull request: #1071.