From 87f4fc8f3fd0f6a2025d84646b84efaaa32e2299 Mon Sep 17 00:00:00 2001 From: Raphael Kim Date: Tue, 3 Dec 2019 17:49:29 -0800 Subject: [PATCH] [DataStore] Implement delete cascade --- .../SQLiteStorageAdapterInstrumentedTest.java | 35 ++++++++++++++++++- .../storage/sqlite/SQLiteCommandFactory.java | 4 ++- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/aws-datastore/src/androidTest/java/com/amplifyframework/datastore/storage/sqlite/SQLiteStorageAdapterInstrumentedTest.java b/aws-datastore/src/androidTest/java/com/amplifyframework/datastore/storage/sqlite/SQLiteStorageAdapterInstrumentedTest.java index 6f2d730be2..59530402d5 100644 --- a/aws-datastore/src/androidTest/java/com/amplifyframework/datastore/storage/sqlite/SQLiteStorageAdapterInstrumentedTest.java +++ b/aws-datastore/src/androidTest/java/com/amplifyframework/datastore/storage/sqlite/SQLiteStorageAdapterInstrumentedTest.java @@ -480,7 +480,7 @@ public void queryWithMaliciousPredicates() throws DataStoreException { } /** - * Assert that save stores item in the SQLite database correctly. + * Assert that delete deletes item in the SQLite database correctly. * @throws DataStoreException from possible underlying DataStore exceptions */ @Test @@ -499,6 +499,39 @@ public void deleteModelDeletesData() throws DataStoreException { assertFalse(iterator.hasNext()); } + /** + * Assert that delete deletes item in the SQLite database without + * violating foreign key constraints. + * @throws DataStoreException from possible underlying DataStore exceptions + */ + @Test + public void deleteModelCascades() throws DataStoreException { + // Triggers an insert + final BlogOwner raphael = BlogOwner.builder() + .name("Raphael Kim") + .build(); + saveModel(raphael); + + // Triggers a foreign key constraint check + final Blog raphaelsBlog = Blog.builder() + .name("Raphael's Blog") + .owner(raphael) + .build(); + saveModel(raphaelsBlog); + + // Triggers a delete + // Deletes Raphael's Blog also to prevent foreign key violation + deleteModel(raphael); + + // Get the BlogOwner record from the database + Iterator blogOwnerterator = queryModel(BlogOwner.class); + assertFalse(blogOwnerterator.hasNext()); + + // Get the Blog record from the database + Iterator blogIterator = queryModel(Blog.class); + assertFalse(blogIterator.hasNext()); + } + private T saveModel(@NonNull T model) throws DataStoreException { LatchedResultListener saveListener = LatchedResultListener.waitFor(SQLITE_OPERATION_TIMEOUT_MS); diff --git a/aws-datastore/src/main/java/com/amplifyframework/datastore/storage/sqlite/SQLiteCommandFactory.java b/aws-datastore/src/main/java/com/amplifyframework/datastore/storage/sqlite/SQLiteCommandFactory.java index 3074122028..d4626d93fe 100644 --- a/aws-datastore/src/main/java/com/amplifyframework/datastore/storage/sqlite/SQLiteCommandFactory.java +++ b/aws-datastore/src/main/java/com/amplifyframework/datastore/storage/sqlite/SQLiteCommandFactory.java @@ -381,7 +381,9 @@ private StringBuilder parseForeignKeys(SQLiteTable table) { .append("REFERENCES") .append(SqlKeyword.DELIMITER) .append(connectedType) - .append("(" + connectedId + ")"); + .append("(" + connectedId + ")") + .append(SqlKeyword.DELIMITER) + .append("ON DELETE CASCADE"); if (foreignKeyIterator.hasNext()) { builder.append(",").append(SqlKeyword.DELIMITER);