use of com.amplifyframework.core.model.query.predicate.QueryPredicate in project amplify-android by aws-amplify.
the class SQLPredicateTest method testMatchNonePredicate.
/**
* Test that MATCH NONE predicate is correctly parsed to an
* expression that is always false.
* @throws DataStoreException if parsing fails
*/
@Test
public void testMatchNonePredicate() throws DataStoreException {
QueryPredicate predicate = QueryPredicates.none();
SQLPredicate sqlPredicate = new SQLPredicate(predicate);
assertEquals("1 = 0", sqlPredicate.toString());
assertTrue(sqlPredicate.getBindings().isEmpty());
}
use of com.amplifyframework.core.model.query.predicate.QueryPredicate in project amplify-android by aws-amplify.
the class SQLiteStorageAdapterSaveTest method saveModelWithPredicateFailsInsert.
/**
* Test save with predicate. Conditional insert is not viable since conditional write
* applies predicate to existing data. Insert is only performed if there isn't any existing
* data. Save operation should fail.
* @throws DataStoreException On unexpected failure manipulating items in/out of DataStore
*/
@Test
@SuppressWarnings("ThrowableNotThrown")
public void saveModelWithPredicateFailsInsert() throws DataStoreException {
final BlogOwner john = BlogOwner.builder().name("John").build();
final BlogOwner jane = BlogOwner.builder().name("Jane").build();
final BlogOwner mark = BlogOwner.builder().name("Mark").build();
// Try inserting with predicate
final QueryPredicate predicate = BlogOwner.NAME.beginsWith("J");
adapter.saveExpectingError(john, predicate);
adapter.saveExpectingError(jane, predicate);
adapter.saveExpectingError(mark, predicate);
// Nothing was saved
assertTrue(adapter.query(BlogOwner.class).isEmpty());
}
use of com.amplifyframework.core.model.query.predicate.QueryPredicate in project amplify-android by aws-amplify.
the class SubscriptionProcessor method subscriptionObservable.
private <T extends Model> Observable<SubscriptionEvent<? extends Model>> subscriptionObservable(AppSync appSync, SubscriptionType subscriptionType, AbortableCountDownLatch<DataStoreException> latch, ModelSchema modelSchema) {
return Observable.<GraphQLResponse<ModelWithMetadata<T>>>create(emitter -> {
SubscriptionMethod method = subscriptionMethodFor(appSync, subscriptionType);
AtomicReference<String> subscriptionId = new AtomicReference<>();
Cancelable cancelable = method.subscribe(modelSchema, token -> {
LOG.debug("Subscription started for " + subscriptionType.name() + " " + modelSchema.getName() + " subscriptionId: " + token);
subscriptionId.set(token);
latch.countDown();
}, emitter::onNext, dataStoreException -> {
if (isExceptionType(dataStoreException, AppSyncErrorType.UNAUTHORIZED)) {
// Ignore Unauthorized errors, so that DataStore can still be used even if the user is only
// authorized to read a subset of the models.
latch.countDown();
LOG.warn("Unauthorized failure:" + subscriptionType.name() + " " + modelSchema.getName());
} else if (isExceptionType(dataStoreException, AppSyncErrorType.OPERATION_DISABLED)) {
// Ignore OperationDisabled errors, so that DataStore can be used even without subscriptions.
// This logic is only in place to address a specific use case, and should not be used without
// unless you have consulted with AWS. It is subject to be deprecated/removed in the future.
latch.countDown();
LOG.warn("Operation disabled:" + subscriptionType.name() + " " + modelSchema.getName());
} else {
if (latch.getCount() > 0) {
// An error occurred during startup. Abort and notify the Orchestrator by throwing the
// exception from startSubscriptions.
latch.abort(dataStoreException);
} else {
// An error occurred after startup. Notify the Orchestrator via the onFailure action.
onFailure.accept(dataStoreException);
}
}
}, () -> {
LOG.debug("Subscription completed:" + subscriptionId.get());
emitter.onComplete();
});
// When the observable is disposed, we need to call cancel() on the subscription
// so it can properly dispose of resources if necessary. For the AWS API plugin,
// this means closing the underlying network connection.
emitter.setDisposable(AmplifyDisposables.fromCancelable(cancelable));
}).doOnError(subscriptionError -> LOG.warn("An error occurred on the remote " + subscriptionType.name() + " subscription for model " + modelSchema.getName(), subscriptionError)).subscribeOn(Schedulers.io()).observeOn(Schedulers.io()).map(SubscriptionProcessor::unwrapResponse).filter(modelWithMetadata -> {
QueryPredicate predicate = queryPredicateProvider.getPredicate(modelSchema.getName());
return predicate.evaluate(modelWithMetadata.getModel());
}).map(modelWithMetadata -> SubscriptionEvent.<T>builder().type(fromSubscriptionType(subscriptionType)).modelWithMetadata(modelWithMetadata).modelSchema(modelSchema).build());
}
use of com.amplifyframework.core.model.query.predicate.QueryPredicate in project amplify-android by aws-amplify.
the class SyncTimeRegistry method lookupLastSyncTime.
Single<SyncTime> lookupLastSyncTime(@NonNull String modelClassName) {
return Single.create(emitter -> {
QueryPredicate hasMatchingModelClassName = QueryField.field("modelClassName").eq(modelClassName);
localStorageAdapter.query(LastSyncMetadata.class, Where.matches(hasMatchingModelClassName), results -> {
try {
LastSyncMetadata syncMetadata = extractSingleResult(modelClassName, results);
emitter.onSuccess(SyncTime.from(syncMetadata.getLastSyncTime()));
} catch (DataStoreException queryResultFailure) {
emitter.onError(queryResultFailure);
}
}, emitter::onError);
});
}
use of com.amplifyframework.core.model.query.predicate.QueryPredicate in project amplify-android by aws-amplify.
the class SQLiteStorageAdapter method writeData.
private <T extends Model> void writeData(T item, StorageItemChange.Type writeType) throws DataStoreException {
final String modelName = item.getModelName();
final ModelSchema modelSchema = schemaRegistry.getModelSchemaForModelClass(modelName);
final SQLiteTable sqliteTable = SQLiteTable.fromSchema(modelSchema);
// Generate SQL command for given action
switch(writeType) {
case CREATE:
LOG.verbose("Creating item in " + sqliteTable.getName() + " identified by ID: " + item.getId());
sqlCommandProcessor.execute(sqlCommandFactory.insertFor(modelSchema, item));
break;
case UPDATE:
LOG.verbose("Updating item in " + sqliteTable.getName() + " identified by ID: " + item.getId());
sqlCommandProcessor.execute(sqlCommandFactory.updateFor(modelSchema, item));
break;
case DELETE:
LOG.verbose("Deleting item in " + sqliteTable.getName() + " identified by ID: " + item.getId());
final String primaryKeyName = sqliteTable.getPrimaryKey().getName();
final QueryPredicate matchId = QueryField.field(modelName, primaryKeyName).eq(item.getId());
sqlCommandProcessor.execute(sqlCommandFactory.deleteFor(modelSchema, matchId));
break;
default:
throw new DataStoreException("Unexpected change was requested: " + writeType.name(), "Valid storage changes are CREATE, UPDATE, and DELETE.");
}
}
Aggregations