Skip to content

Commit

Permalink
Added logic to delete with class name and predicate to support custom…
Browse files Browse the repository at this point in the history
… primary key.
  • Loading branch information
poojamat committed May 30, 2022
1 parent cb6b478 commit 2852ec3
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 4 deletions.
@@ -0,0 +1,120 @@
/*
* Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0
*
* or in the "license" file accompanying this file. This file 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 com.amplifyframework.datastore.storage.sqlite;

import com.amplifyframework.core.model.Model;
import com.amplifyframework.core.model.query.predicate.QueryPredicates;
import com.amplifyframework.datastore.DataStoreException;
import com.amplifyframework.datastore.StrictMode;
import com.amplifyframework.datastore.storage.StorageItemChange;
import com.amplifyframework.datastore.storage.SynchronousStorageAdapter;
import com.amplifyframework.testmodels.customprimarykey.AmplifyModelProvider;
import com.amplifyframework.testmodels.customprimarykey.Comment;

import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.HashSet;
import java.util.Set;

import io.reactivex.rxjava3.observers.TestObserver;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

/**
* Test the delete functionality of {@link SQLiteStorageAdapter} operations.
*/
public final class SQLiteStorageAdapterDeleteWithCpkTest {
private SynchronousStorageAdapter adapter;

/**
* Enables strict mode, for the purpose of catching some common errors while using
* a SQL data-base, such as forgetting to close it when done.
*/
@BeforeClass
public static void enableStrictMode() {
StrictMode.enable();
}

/**
* Clear the storage adapter, and then provision a new one that will allow us
* to store the Comments-Blog models.
*/
@Before
public void setup() {
TestStorageAdapter.cleanup();
this.adapter = TestStorageAdapter.create(AmplifyModelProvider.getInstance());
}

/**
* Close the storage adapter, and cleanup any database files it left.
*/
@After
public void teardown() {
TestStorageAdapter.cleanup(adapter);
}

/**
* Assert that delete model type with predicate deletes items in
* the SQLite database without violating foreign key constraints.
* @throws DataStoreException On unexpected failure manipulating items in/out of DataStore
*/
@Test
public void deleteCustomPrimaryKeyModelTypeWithDeleteAllPredicateCascades() throws DataStoreException {
// Create 1 post, which has 3 comments each
Set<String> expected = new HashSet<>();
com.amplifyframework.testmodels.customprimarykey.Post
postModel = com.amplifyframework.testmodels.customprimarykey.Post.builder()
.title("test post")
.id("testPostId")
.build();
adapter.save(postModel);
expected.add(postModel.getPrimaryKeyString());
for (int comment = 1; comment <= 3; comment++) {
Comment commentModel = Comment.builder()
.title("comment " + comment)
.content("content " + comment)
.likes(2)
.description("description " + comment)
.post(postModel)
.build();
adapter.save(commentModel);
expected.add(commentModel.getPrimaryKeyString());
}
// Observe deletions
TestObserver<String> deleteObserver = adapter.observe()
.filter(change -> StorageItemChange.Type.DELETE.equals(change.type()))
.map(StorageItemChange::item)
.map(Model::getPrimaryKeyString)
.test();

// Triggers a delete of all blogs.
// All posts will be deleted by cascade.
adapter.delete(com.amplifyframework.testmodels.customprimarykey.Post.class, QueryPredicates.all());

// Assert 3 comments.
deleteObserver.assertValueCount(4);
assertEquals(expected, new HashSet<>(deleteObserver.values()));

// Get the Post and Comments from the database. Should be deleted.
assertTrue(adapter.query(com.amplifyframework.testmodels.customprimarykey.Post.class).isEmpty());
assertTrue(adapter.query(Comment.class).isEmpty());

}
}
Expand Up @@ -563,15 +563,21 @@ public <T extends Model> void delete(
QueryOptions options = Where.matches(predicate);
try (Cursor cursor = sqlCommandProcessor.rawQuery(sqlCommandFactory.queryFor(modelSchema, options))) {
final SQLiteTable sqliteTable = SQLiteTable.fromSchema(modelSchema);
final String primaryKeyName = sqliteTable.getPrimaryKey().getAliasedName();
final List<String> primaryKeyNames = modelSchema.getPrimaryIndexFields();

// identify items that meet the predicate
List<T> items = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
int index = cursor.getColumnIndexOrThrow(primaryKeyName);
/** Populate the mapOfModelPrimaryKeys with the values of
* the primary key/ keys for the model**/
do {
String id = cursor.getString(index);
String dummyJson = gson.toJson(Collections.singletonMap("id", id));
HashMap<String, String> mapOfModelPrimaryKeys = new HashMap<>();
for (String field : primaryKeyNames) {
int index = cursor.getColumnIndexOrThrow(sqliteTable.getName() + "_" + field);
String fieldValue = cursor.getString(index);
mapOfModelPrimaryKeys.put(field, fieldValue);
}
String dummyJson = gson.toJson(mapOfModelPrimaryKeys);
T dummyItem = gson.fromJson(dummyJson, itemClass);
items.add(dummyItem);
} while (cursor.moveToNext());
Expand Down
@@ -0,0 +1,54 @@
package com.amplifyframework.testmodels.customprimarykey;

import com.amplifyframework.core.model.Model;
import com.amplifyframework.core.model.ModelProvider;
import com.amplifyframework.util.Immutable;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

/**
* Contains the set of model classes that implement {@link Model}
* interface.
*/

public final class AmplifyModelProvider implements ModelProvider {
private static final String AMPLIFY_MODEL_VERSION = "676dbf8de03bdea7d825974b4ba506c0";
private static AmplifyModelProvider amplifyGeneratedModelInstance;
private AmplifyModelProvider() {

}

public static AmplifyModelProvider getInstance() {
if (amplifyGeneratedModelInstance == null) {
amplifyGeneratedModelInstance = new AmplifyModelProvider();
}
return amplifyGeneratedModelInstance;
}

/**
* Get a set of the model classes.
*
* @return a set of the model classes.
*/
@Override
public Set<Class<? extends Model>> models() {
final Set<Class<? extends Model>> modifiableSet = new HashSet<>(
Arrays.<Class<? extends Model>>asList(Blog.class, Post.class, Comment.class, ModelCompositeMultiplePk.class, BlogWithDefaultHasOne.class, User.class, BlogWithCustomHasOne.class)
);

return Immutable.of(modifiableSet);

}

/**
* Get the version of the models.
*
* @return the version string of the models.
*/
@Override
public String version() {
return AMPLIFY_MODEL_VERSION;
}
}

0 comments on commit 2852ec3

Please sign in to comment.