Search in sources :

Example 26 with QueryPredicate

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());
}
Also used : SQLPredicate(com.amplifyframework.datastore.storage.sqlite.adapter.SQLPredicate) QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate) Test(org.junit.Test)

Example 27 with QueryPredicate

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());
}
Also used : QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate) BlogOwner(com.amplifyframework.testmodels.commentsblog.BlogOwner) Test(org.junit.Test)

Example 28 with QueryPredicate

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());
}
Also used : Arrays(java.util.Arrays) AmplifyException(com.amplifyframework.AmplifyException) NonNull(androidx.annotation.NonNull) ModelWithMetadata(com.amplifyframework.datastore.appsync.ModelWithMetadata) ModelProvider(com.amplifyframework.core.model.ModelProvider) DataStoreChannelEventName(com.amplifyframework.datastore.DataStoreChannelEventName) AppSync(com.amplifyframework.datastore.appsync.AppSync) AtomicReference(java.util.concurrent.atomic.AtomicReference) Empty(com.amplifyframework.util.Empty) SchemaRegistry(com.amplifyframework.core.model.SchemaRegistry) HashSet(java.util.HashSet) Schedulers(io.reactivex.rxjava3.schedulers.Schedulers) AppSyncExtensions(com.amplifyframework.datastore.appsync.AppSyncExtensions) Consumer(com.amplifyframework.core.Consumer) CompositeDisposable(io.reactivex.rxjava3.disposables.CompositeDisposable) SubscriptionType(com.amplifyframework.api.graphql.SubscriptionType) Locale(java.util.Locale) Observable(io.reactivex.rxjava3.core.Observable) ModelSchema(com.amplifyframework.core.model.ModelSchema) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate) HubEvent(com.amplifyframework.hub.HubEvent) Amplify(com.amplifyframework.core.Amplify) HubChannel(com.amplifyframework.hub.HubChannel) SerializedModel(com.amplifyframework.core.model.SerializedModel) AppSyncErrorType(com.amplifyframework.datastore.appsync.AppSyncExtensions.AppSyncErrorType) Model(com.amplifyframework.core.model.Model) Set(java.util.Set) Completable(io.reactivex.rxjava3.core.Completable) Action(com.amplifyframework.core.Action) Logger(com.amplifyframework.logging.Logger) Objects(java.util.Objects) TimeUnit(java.util.concurrent.TimeUnit) DataStoreException(com.amplifyframework.datastore.DataStoreException) List(java.util.List) Cancelable(com.amplifyframework.core.async.Cancelable) ReplaySubject(io.reactivex.rxjava3.subjects.ReplaySubject) AmplifyDisposables(com.amplifyframework.datastore.AmplifyDisposables) GraphQLResponseException(com.amplifyframework.datastore.DataStoreException.GraphQLResponseException) VisibleForTesting(androidx.annotation.VisibleForTesting) QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate) GraphQLResponse(com.amplifyframework.api.graphql.GraphQLResponse) AtomicReference(java.util.concurrent.atomic.AtomicReference) Cancelable(com.amplifyframework.core.async.Cancelable)

Example 29 with QueryPredicate

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);
    });
}
Also used : DataStoreException(com.amplifyframework.datastore.DataStoreException) QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate)

Example 30 with QueryPredicate

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.");
    }
}
Also used : ModelSchema(com.amplifyframework.core.model.ModelSchema) DataStoreException(com.amplifyframework.datastore.DataStoreException) QueryPredicate(com.amplifyframework.core.model.query.predicate.QueryPredicate) SQLiteTable(com.amplifyframework.datastore.storage.sqlite.adapter.SQLiteTable)

Aggregations

QueryPredicate (com.amplifyframework.core.model.query.predicate.QueryPredicate)31 Test (org.junit.Test)17 ArrayList (java.util.ArrayList)12 BlogOwner (com.amplifyframework.testmodels.commentsblog.BlogOwner)11 ModelSchema (com.amplifyframework.core.model.ModelSchema)9 DataStoreException (com.amplifyframework.datastore.DataStoreException)9 HashSet (java.util.HashSet)8 List (java.util.List)7 NonNull (androidx.annotation.NonNull)6 SQLPredicate (com.amplifyframework.datastore.storage.sqlite.adapter.SQLPredicate)6 Consumer (com.amplifyframework.core.Consumer)5 Cancelable (com.amplifyframework.core.async.Cancelable)5 Model (com.amplifyframework.core.model.Model)5 SerializedModel (com.amplifyframework.core.model.SerializedModel)5 SQLiteTable (com.amplifyframework.datastore.storage.sqlite.adapter.SQLiteTable)5 Action (com.amplifyframework.core.Action)4 TimeUnit (java.util.concurrent.TimeUnit)4 AmplifyException (com.amplifyframework.AmplifyException)3 Amplify (com.amplifyframework.core.Amplify)3 ModelProvider (com.amplifyframework.core.model.ModelProvider)3