Skip to content

Commit

Permalink
Introduce WriteResult interface which replaces Repository.Success
Browse files Browse the repository at this point in the history
Allow more fine-grained statistics after a write operation
  • Loading branch information
asereda-gs committed Jun 20, 2019
1 parent bad18bc commit f532b29
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 29 deletions.
Expand Up @@ -36,7 +36,7 @@ interface Readable<T> extends ReactiveRepository<T>, Repository.Readable<T, Read


} }


interface Writable<T> extends ReactiveRepository<T>, Repository.Writable<T, CompletionStage<Success>> { interface Writable<T> extends ReactiveRepository<T>, Repository.Writable<T, CompletionStage<WriteResult>> {


} }


Expand Down
Expand Up @@ -36,7 +36,7 @@ interface Readable<T> extends ReactiveRepository<T>, Repository.Readable<T, Reac


} }


interface Writable<T> extends ReactiveRepository<T>, Repository.Writable<T, Publisher<Success>> { interface Writable<T> extends ReactiveRepository<T>, Repository.Writable<T, Publisher<WriteResult>> {


} }


Expand Down
7 changes: 0 additions & 7 deletions criteria/common/src/org/immutables/criteria/Repository.java
Expand Up @@ -44,13 +44,6 @@ interface Readable<T, R extends Reader<T>> extends Repository<T> {


} }


/**
* Marker for a successful operation
*/
enum Success {
SUCCESS
}

interface Writable<T, R> extends Repository<T> { interface Writable<T, R> extends Repository<T> {


default R insert(T ... docs) { default R insert(T ... docs) {
Expand Down
Expand Up @@ -35,7 +35,7 @@ interface Readable<T> extends SyncRepository<T>, Repository.Readable<T, Reader<T


} }


interface Writable<T> extends SyncRepository<T>, Repository.Writable<T, Repository.Success> { interface Writable<T> extends SyncRepository<T>, Repository.Writable<T, WriteResult> {


} }


Expand Down
49 changes: 49 additions & 0 deletions criteria/common/src/org/immutables/criteria/WriteResult.java
@@ -0,0 +1,49 @@
/*
* Copyright 2019 Immutables Authors and Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.immutables.criteria;

import java.util.OptionalLong;

/**
* Result of a <i>successful</i> write operation. It is up to back-end to provide
* some, all or none of exposed statistics.
*/
public interface WriteResult {

/**
* Number of records after insert operation
*
* @return number of inserted records. empty optional if unknown
*/
OptionalLong insertedCount();


/**
* Number of records deleted after a write operation
*
* @return number of deleted records. empty optional if unknown or operation not supported.
*/
OptionalLong deletedCount();

/**
* Number of records updated after a write operation
*
* @return number of deleted records. empty optional if unknown or operation not supported.
*/
OptionalLong updatedCount();

}
Expand Up @@ -19,7 +19,7 @@
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
import org.immutables.criteria.Criterias; import org.immutables.criteria.Criterias;
import org.immutables.criteria.DocumentCriteria; import org.immutables.criteria.DocumentCriteria;
import org.immutables.criteria.Repository; import org.immutables.criteria.WriteResult;
import org.immutables.criteria.expression.Query; import org.immutables.criteria.expression.Query;
import org.immutables.value.Value; import org.immutables.value.Value;


Expand Down Expand Up @@ -55,7 +55,7 @@ static <T> ImmutableSelect<T> of(Query query) {
* Insert operation for a list of objects. * Insert operation for a list of objects.
*/ */
@Value.Immutable @Value.Immutable
public interface Insert<V> extends Backend.Operation<Repository.Success> { public interface Insert<V> extends Backend.Operation<WriteResult> {


/** /**
* List of values to be inserted * List of values to be inserted
Expand Down Expand Up @@ -115,7 +115,7 @@ default List<V> values() {
* Delete documents using some criteria * Delete documents using some criteria
*/ */
@Value.Immutable @Value.Immutable
public interface Delete extends Backend.Operation<Repository.Success> { public interface Delete extends Backend.Operation<WriteResult> {
@Value.Parameter @Value.Parameter
Query query(); Query query();


Expand Down
@@ -0,0 +1,46 @@
/*
* Copyright 2019 Immutables Authors and Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.immutables.criteria.adapter;

import org.immutables.criteria.WriteResult;

import java.util.OptionalLong;

/**
* Used as a <b>null object</b> if backend can't provide information about a write operation
*/
public final class UnknownWriteResult implements WriteResult {

public static final WriteResult INSTANCE = new UnknownWriteResult();

private UnknownWriteResult() {}

@Override
public OptionalLong insertedCount() {
return OptionalLong.empty();
}

@Override
public OptionalLong deletedCount() {
return OptionalLong.empty();
}

@Override
public OptionalLong updatedCount() {
return OptionalLong.empty();
}
}
Expand Up @@ -21,9 +21,10 @@
import io.reactivex.Single; import io.reactivex.Single;
import org.apache.geode.cache.Region; import org.apache.geode.cache.Region;
import org.immutables.criteria.Criteria; import org.immutables.criteria.Criteria;
import org.immutables.criteria.Repository; import org.immutables.criteria.WriteResult;
import org.immutables.criteria.adapter.Backend; import org.immutables.criteria.adapter.Backend;
import org.immutables.criteria.adapter.Operations; import org.immutables.criteria.adapter.Operations;
import org.immutables.criteria.adapter.UnknownWriteResult;
import org.immutables.criteria.expression.Expression; import org.immutables.criteria.expression.Expression;
import org.immutables.criteria.expression.Query; import org.immutables.criteria.expression.Query;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
Expand Down Expand Up @@ -73,7 +74,7 @@ private <T> Flowable<T> query(Operations.Select<T> op) {
.flatMapIterable(x -> x); .flatMapIterable(x -> x);
} }


private <T> Flowable<Repository.Success> insert(Operations.Insert<T> op) { private <T> Flowable<WriteResult> insert(Operations.Insert<T> op) {
if (!(op instanceof Operations.KeyedInsert)) { if (!(op instanceof Operations.KeyedInsert)) {
throw new UnsupportedOperationException( throw new UnsupportedOperationException(
String.format("%s supports only %s. Did you define a key (@%s) on your domain class ?", String.format("%s supports only %s. Did you define a key (@%s) on your domain class ?",
Expand All @@ -87,11 +88,11 @@ private <T> Flowable<Repository.Success> insert(Operations.Insert<T> op) {
return Completable.fromRunnable(() -> region.putAll(insert.toMap())).toFlowable(); return Completable.fromRunnable(() -> region.putAll(insert.toMap())).toFlowable();
} }


private <T> Flowable<Repository.Success> delete(Operations.Delete op) { private <T> Flowable<WriteResult> delete(Operations.Delete op) {
if (!op.query().filter().isPresent()) { if (!op.query().filter().isPresent()) {
// no filter means delete all (ie clear whole region) // no filter means delete all (ie clear whole region)
return Completable.fromRunnable(region::clear) return Completable.fromRunnable(region::clear)
.toSingleDefault(Repository.Success.SUCCESS) .toSingleDefault(UnknownWriteResult.INSTANCE)
.toFlowable(); .toFlowable();
} }


Expand All @@ -101,7 +102,7 @@ private <T> Flowable<Repository.Success> delete(Operations.Delete op) {
if (ids.isPresent()) { if (ids.isPresent()) {
// delete by key: map.remove(key) // delete by key: map.remove(key)
return Completable.fromRunnable(() -> region.removeAll(ids.get())) return Completable.fromRunnable(() -> region.removeAll(ids.get()))
.toSingleDefault(Repository.Success.SUCCESS) .toSingleDefault(UnknownWriteResult.INSTANCE)
.toFlowable(); .toFlowable();
} }


Expand All @@ -112,7 +113,7 @@ private <T> Flowable<Repository.Success> delete(Operations.Delete op) {


return Single.fromCallable(() -> region.query(query)) return Single.fromCallable(() -> region.query(query))
.flatMapCompletable(list -> Completable.fromRunnable(() -> region.removeAll((Collection<Object>) list))) .flatMapCompletable(list -> Completable.fromRunnable(() -> region.removeAll((Collection<Object>) list)))
.toSingleDefault(Repository.Success.SUCCESS) .toSingleDefault(UnknownWriteResult.INSTANCE)
.toFlowable(); .toFlowable();
} }


Expand Down
Expand Up @@ -20,7 +20,6 @@
import org.apache.geode.cache.Cache; import org.apache.geode.cache.Cache;
import org.apache.geode.cache.Region; import org.apache.geode.cache.Region;
import org.immutables.criteria.DocumentCriteria; import org.immutables.criteria.DocumentCriteria;
import org.immutables.criteria.Repository;
import org.immutables.criteria.personmodel.Person; import org.immutables.criteria.personmodel.Person;
import org.immutables.criteria.personmodel.PersonCriteria; import org.immutables.criteria.personmodel.PersonCriteria;
import org.immutables.criteria.personmodel.PersonGenerator; import org.immutables.criteria.personmodel.PersonGenerator;
Expand Down Expand Up @@ -108,20 +107,20 @@ public void delete() {




// delete all // delete all
check(Flowable.fromPublisher(repository.delete(PersonCriteria.create())).blockingFirst()).is(Repository.Success.SUCCESS); check(Flowable.fromPublisher(repository.delete(PersonCriteria.create())).blockingFirst()).notNull();
check(region.keySet()).isEmpty(); check(region.keySet()).isEmpty();


insert(generator.next().withId("test")); insert(generator.next().withId("test"));


check(Flowable.fromPublisher(repository.delete(PersonCriteria.create().id.isIn("testBAD", "test"))) check(Flowable.fromPublisher(repository.delete(PersonCriteria.create().id.isIn("testBAD", "test")))
.blockingFirst()).is(Repository.Success.SUCCESS); .blockingFirst()).notNull();
check(region.keySet()).hasSize(0); check(region.keySet()).hasSize(0);


// insert again // insert again
insert(generator.next().withId("test").withNickName("nick123")); insert(generator.next().withId("test").withNickName("nick123"));


check(Flowable.fromPublisher(repository.delete(PersonCriteria.create().nickName.value().isEqualTo("nick123"))) check(Flowable.fromPublisher(repository.delete(PersonCriteria.create().nickName.value().isEqualTo("nick123")))
.blockingFirst()).is(Repository.Success.SUCCESS); .blockingFirst()).notNull();


// delete by query doesn't work yet // delete by query doesn't work yet
// check(region.keySet()).hasSize(0); // check(region.keySet()).hasSize(0);
Expand Down
Expand Up @@ -23,8 +23,10 @@
import org.bson.Document; import org.bson.Document;
import org.bson.conversions.Bson; import org.bson.conversions.Bson;
import org.immutables.criteria.Repository; import org.immutables.criteria.Repository;
import org.immutables.criteria.WriteResult;
import org.immutables.criteria.adapter.Backend; import org.immutables.criteria.adapter.Backend;
import org.immutables.criteria.adapter.Operations; import org.immutables.criteria.adapter.Operations;
import org.immutables.criteria.adapter.UnknownWriteResult;
import org.immutables.criteria.expression.ExpressionConverter; import org.immutables.criteria.expression.ExpressionConverter;
import org.immutables.criteria.expression.Query; import org.immutables.criteria.expression.Query;
import org.reactivestreams.Publisher; import org.reactivestreams.Publisher;
Expand Down Expand Up @@ -73,16 +75,16 @@ private <T> Publisher<T> query(Operations.Select<T> select) {
return collection.find(toBson(select.query())); return collection.find(toBson(select.query()));
} }


private Publisher<Repository.Success> delete(Operations.Delete delete) { private Publisher<WriteResult> delete(Operations.Delete delete) {
final Bson filter = toBson(delete.query()); final Bson filter = toBson(delete.query());
return Flowable.fromPublisher(collection.deleteMany(filter)) return Flowable.fromPublisher(collection.deleteMany(filter))
.map(r -> Repository.Success.SUCCESS); .map(r -> UnknownWriteResult.INSTANCE);
} }


private Publisher<Repository.Success> insert(Operations.Insert insert) { private Publisher<WriteResult> insert(Operations.Insert insert) {
final MongoCollection<Object> collection = (MongoCollection<Object>) this.collection; final MongoCollection<Object> collection = (MongoCollection<Object>) this.collection;
final List<Object> values = (List<Object>) insert.values(); final List<Object> values = (List<Object>) insert.values();
return Flowable.fromPublisher(collection.insertMany(values)).map(r -> Repository.Success.SUCCESS); return Flowable.fromPublisher(collection.insertMany(values)).map(r -> UnknownWriteResult.INSTANCE);
} }


private <T> Publisher<T> watch(Operations.Watch<T> operation) { private <T> Publisher<T> watch(Operations.Watch<T> operation) {
Expand Down
Expand Up @@ -41,6 +41,7 @@ import [starImport];
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;


import org.immutables.criteria.ReactiveRepository; import org.immutables.criteria.ReactiveRepository;
import org.immutables.criteria.WriteResult;
import org.immutables.criteria.DocumentCriteria; import org.immutables.criteria.DocumentCriteria;
import org.immutables.criteria.adapter.Operations; import org.immutables.criteria.adapter.Operations;
import org.immutables.criteria.adapter.Backend; import org.immutables.criteria.adapter.Backend;
Expand Down Expand Up @@ -107,7 +108,7 @@ import java.util.function.Function;


[if not type.criteriaRepository.readonly] [if not type.criteriaRepository.readonly]
@Override @Override
public Publisher<Success> insert(Iterable<? extends [type.name]> docs) { public Publisher<WriteResult> insert(Iterable<? extends [type.name]> docs) {
[for a = type.idAttribute] [for a = type.idAttribute]
[if a] [if a]
return backend.execute(Operations.Insert.ofKeyed(docs, ID_EXTRACTOR)); return backend.execute(Operations.Insert.ofKeyed(docs, ID_EXTRACTOR));
Expand All @@ -118,7 +119,7 @@ import java.util.function.Function;
} }


@Override @Override
public Publisher<Success> delete(DocumentCriteria<[type.name]> criteria) { public Publisher<WriteResult> delete(DocumentCriteria<[type.name]> criteria) {
return backend.execute(Operations.Delete.of(criteria)); return backend.execute(Operations.Delete.of(criteria));
} }
[/if] [/if]
Expand Down

0 comments on commit f532b29

Please sign in to comment.