ForeignKeyTest.java revision 36023a6ffdcc24a64c3f86efd4e754cfc3493761
10045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar/* 20045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * Copyright (C) 2017 The Android Open Source Project 30045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * 40045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 50045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * you may not use this file except in compliance with the License. 60045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * You may obtain a copy of the License at 70045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * 80045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 90045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * 100045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * Unless required by applicable law or agreed to in writing, software 110045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 120045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * See the License for the specific language governing permissions and 140045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar * limitations under the License. 150045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar */ 160045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 170045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarpackage com.android.support.room.integration.testapp.test; 180045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 190045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport static org.hamcrest.CoreMatchers.containsString; 200045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport static org.hamcrest.CoreMatchers.equalTo; 210045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport static org.hamcrest.CoreMatchers.instanceOf; 220045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport static org.hamcrest.CoreMatchers.notNullValue; 230045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport static org.hamcrest.CoreMatchers.nullValue; 240045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport static org.hamcrest.MatcherAssert.assertThat; 250045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 260045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport android.database.sqlite.SQLiteException; 270045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport android.support.test.InstrumentationRegistry; 280045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport android.support.test.filters.SmallTest; 290045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport android.support.test.runner.AndroidJUnit4; 300045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 310045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.Dao; 320045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.Database; 330045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.Delete; 340045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.Entity; 350045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.ForeignKey; 360045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.Index; 370045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.Insert; 380045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.PrimaryKey; 390045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.Query; 400045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.Room; 410045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport com.android.support.room.RoomDatabase; 420045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 430045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport org.junit.Before; 440045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport org.junit.Test; 450045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarimport org.junit.runner.RunWith; 460045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 4736023a6ffdcc24a64c3f86efd4e754cfc3493761Yigit Boyarimport java.util.Locale; 4836023a6ffdcc24a64c3f86efd4e754cfc3493761Yigit Boyar 490045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar@RunWith(AndroidJUnit4.class) 500045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar@SmallTest 510045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyarpublic class ForeignKeyTest { 520045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Database(version = 1, entities = {A.class, B.class, C.class, D.class, E.class}, 530045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar exportSchema = false) 540045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar abstract static class ForeignKeyDb extends RoomDatabase { 550045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar abstract FkDao dao(); 560045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 570045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 580045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @SuppressWarnings({"SqlNoDataSourceInspection", "SameParameterValue"}) 590045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Dao 600045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar interface FkDao { 610045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Insert 620045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar void insert(A... a); 630045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 640045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Insert 650045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar void insert(B... b); 660045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 670045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Insert 680045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar void insert(C... c); 690045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 700045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Insert 710045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar void insert(D... d); 720045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 730045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Query("SELECT * FROM A WHERE id = ?") 740045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar A loadA(int id); 750045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 760045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Query("SELECT * FROM B WHERE id = ?") 770045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar B loadB(int id); 780045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 790045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Query("SELECT * FROM C WHERE id = ?") 800045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar C loadC(int id); 810045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 820045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Query("SELECT * FROM D WHERE id = ?") 830045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar D loadD(int id); 840045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 850045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Query("SELECT * FROM E WHERE id = ?") 860045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar E loadE(int id); 870045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 880045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Delete 890045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar void delete(A... a); 900045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 910045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Delete 920045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar void delete(B... b); 930045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 940045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Delete 950045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar void delete(C... c); 960045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 970045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Query("UPDATE A SET name = :newName WHERE id = :id") 980045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar void changeNameA(int id, String newName); 990045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1000045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Insert 1010045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar void insert(E... e); 1020045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1030045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1040045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1050045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1060045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Entity(indices = {@Index(value = "name", unique = true), 1070045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Index(value = {"name", "lastName"}, unique = true)}) 1080045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar static class A { 1090045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @PrimaryKey(autoGenerate = true) 1100045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public int id; 1110045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public String name; 1120045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public String lastName; 1130045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1140045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar A() { 1150045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1160045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1170045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar A(String name) { 1180045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar this.name = name; 1190045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1200045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1210045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar A(String name, String lastName) { 1220045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar this.name = name; 1230045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar this.lastName = lastName; 1240045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1250045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1260045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1270045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @SuppressWarnings("WeakerAccess") 1280045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Entity(foreignKeys = { 1290045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @ForeignKey(entity = A.class, 1300045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar parentColumns = "name", 1310045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar childColumns = "aName")}) 1320045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1330045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar static class B { 1340045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @PrimaryKey(autoGenerate = true) 1350045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public int id; 1360045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public String aName; 1370045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1380045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar B() { 1390045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1400045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1410045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar B(String aName) { 1420045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar this.aName = aName; 1430045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1440045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1450045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1460045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @SuppressWarnings("WeakerAccess") 1470045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Entity(foreignKeys = { 1480045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @ForeignKey(entity = A.class, 1490045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar parentColumns = "name", 1500045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar childColumns = "aName", 1510045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar deferred = true)}) 1520045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar static class C { 1530045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @PrimaryKey(autoGenerate = true) 1540045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public int id; 1550045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public String aName; 1560045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1570045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar C() { 1580045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1590045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1600045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar C(String aName) { 1610045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar this.aName = aName; 1620045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1630045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1640045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1650045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @SuppressWarnings("WeakerAccess") 1660045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Entity(foreignKeys = { 1670045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @ForeignKey(entity = A.class, 1680045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar parentColumns = "name", 1690045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar childColumns = "aName", 1700045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar onDelete = ForeignKey.CASCADE, 1710045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar onUpdate = ForeignKey.CASCADE)}) 1720045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar static class D { 1730045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @PrimaryKey(autoGenerate = true) 1740045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public int id; 1750045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public String aName; 1760045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1770045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar D() { 1780045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1790045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1800045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar D(String aName) { 1810045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar this.aName = aName; 1820045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1830045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 1840045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1850045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @SuppressWarnings("WeakerAccess") 1860045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Entity(foreignKeys = { 1870045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @ForeignKey(entity = A.class, 1880045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar parentColumns = {"name", "lastName"}, 1890045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar childColumns = {"aName", "aLastName"}, 1900045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar onDelete = ForeignKey.SET_NULL, 1910045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar onUpdate = ForeignKey.CASCADE)}) 1920045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar static class E { 1930045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @PrimaryKey(autoGenerate = true) 1940045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public int id; 1950045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public String aName; 1960045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public String aLastName; 1970045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 1980045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar E() { 1990045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2000045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 2010045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar E(String aName, String aLastName) { 2020045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar this.aName = aName; 2030045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar this.aLastName = aLastName; 2040045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2050045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2060045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 2070045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 2080045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar private ForeignKeyDb mDb; 2090045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar private FkDao mDao; 2100045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 2110045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Before 2120045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void openDb() { 2130045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getContext(), 2140045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar ForeignKeyDb.class).build(); 2150045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao = mDb.dao(); 2160045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2170045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 2180045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 2190045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void simpleForeignKeyFailure() { 2200045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar Throwable t = catchException(new ThrowingRunnable() { 2210045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Override 2220045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void run() throws Exception { 2230045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new B("foo")); 2240045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2250045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar }); 2260045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(t, instanceOf(SQLiteException.class)); 22736023a6ffdcc24a64c3f86efd4e754cfc3493761Yigit Boyar assertThat(t.getMessage().toUpperCase(Locale.US), containsString("FOREIGN KEY")); 2280045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2290045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 2300045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 2310045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void simpleForeignKeyDeferredFailure() { 2320045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar Throwable t = catchException(new ThrowingRunnable() { 2330045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Override 2340045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void run() throws Exception { 2350045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new C("foo")); 2360045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2370045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar }); 2380045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(t, instanceOf(SQLiteException.class)); 23936023a6ffdcc24a64c3f86efd4e754cfc3493761Yigit Boyar assertThat(t.getMessage().toUpperCase(Locale.US), containsString("FOREIGN KEY")); 2400045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2410045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 2420045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 2430045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void immediateForeignKeyFailure() { 2440045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar Throwable t = catchException(new ThrowingRunnable() { 2450045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Override 2460045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void run() throws Exception { 2470045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar try { 2480045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.beginTransaction(); 2490045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new B("foo")); 2500045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("foo")); 2510045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.setTransactionSuccessful(); 2520045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } finally { 2530045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.endTransaction(); 2540045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2550045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2560045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar }); 2570045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(t, instanceOf(SQLiteException.class)); 2580045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2590045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 2600045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 2610045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void deferredForeignKeySuccess() { 2620045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar try { 2630045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.beginTransaction(); 2640045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new C("foo")); 2650045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("foo")); 2660045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.setTransactionSuccessful(); 2670045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } finally { 2680045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.endTransaction(); 2690045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2700045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(mDao.loadA(1), notNullValue()); 2710045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(mDao.loadC(1), notNullValue()); 2720045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2730045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 2740045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 2750045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void onDelete_noAction() { 2760045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("a1")); 2770045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final A a = mDao.loadA(1); 2780045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new B("a1")); 2790045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar Throwable t = catchException(new ThrowingRunnable() { 2800045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Override 2810045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void run() throws Exception { 2820045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.delete(a); 2830045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2840045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar }); 2850045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(t, instanceOf(SQLiteException.class)); 28636023a6ffdcc24a64c3f86efd4e754cfc3493761Yigit Boyar assertThat(t.getMessage().toUpperCase(Locale.US), containsString("FOREIGN KEY")); 2870045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 2880045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 2890045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 2900045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void onDelete_noAction_withTransaction() { 2910045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("a1")); 2920045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final A a = mDao.loadA(1); 2930045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new B("a1")); 2940045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final B b = mDao.loadB(1); 2950045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar Throwable t = catchException(new ThrowingRunnable() { 2960045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Override 2970045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void run() throws Exception { 2980045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar deleteInTransaction(a, b); 2990045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3000045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar }); 3010045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(t, instanceOf(SQLiteException.class)); 30236023a6ffdcc24a64c3f86efd4e754cfc3493761Yigit Boyar assertThat(t.getMessage().toUpperCase(Locale.US), containsString("FOREIGN KEY")); 3030045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3040045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 3050045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 3060045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void onDelete_noAction_deferred() { 3070045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("a1")); 3080045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final A a = mDao.loadA(1); 3090045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new C("a1")); 3100045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar Throwable t = catchException(new ThrowingRunnable() { 3110045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Override 3120045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void run() throws Exception { 3130045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.delete(a); 3140045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3150045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar }); 3160045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(t, instanceOf(SQLiteException.class)); 31736023a6ffdcc24a64c3f86efd4e754cfc3493761Yigit Boyar assertThat(t.getMessage().toUpperCase(Locale.US), containsString("FOREIGN KEY")); 3180045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3190045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 3200045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 3210045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void onDelete_noAction__deferredWithTransaction() { 3220045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("a1")); 3230045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final A a = mDao.loadA(1); 3240045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new C("a1")); 3250045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final C c = mDao.loadC(1); 3260045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar deleteInTransaction(a, c); 3270045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3280045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 3290045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 3300045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void onDelete_cascade() { 3310045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("a1")); 3320045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final A a = mDao.loadA(1); 3330045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new D("a1")); 3340045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final D d = mDao.loadD(1); 3350045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat("test sanity", d, notNullValue()); 3360045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.delete(a); 3370045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(mDao.loadD(1), nullValue()); 3380045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3390045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 3400045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 3410045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void onUpdate_cascade() { 3420045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("a1")); 3430045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new D("a1")); 3440045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final D d = mDao.loadD(1); 3450045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat("test sanity", d, notNullValue()); 3460045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.changeNameA(1, "bla"); 3470045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(mDao.loadD(1).aName, equalTo("bla")); 3480045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(mDao.loadA(1).name, equalTo("bla")); 3490045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3500045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 3510045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 3520045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void multipleReferences() { 3530045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("a1", "a2")); 3540045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final A a = mDao.loadA(1); 3550045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat("test sanity", a, notNullValue()); 3560045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar Throwable t = catchException(new ThrowingRunnable() { 3570045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Override 3580045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void run() throws Exception { 3590045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new E("a1", "dsa")); 3600045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3610045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar }); 36236023a6ffdcc24a64c3f86efd4e754cfc3493761Yigit Boyar assertThat(t.getMessage().toUpperCase(Locale.US), containsString("FOREIGN KEY")); 3630045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3640045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 3650045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 3660045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void onDelete_setNull_multipleReferences() { 3670045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("a1", "a2")); 3680045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final A a = mDao.loadA(1); 3690045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new E("a1", "a2")); 3700045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(mDao.loadE(1), notNullValue()); 3710045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.delete(a); 3720045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar E e = mDao.loadE(1); 3730045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(e, notNullValue()); 3740045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(e.aName, nullValue()); 3750045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(e.aLastName, nullValue()); 3760045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3770045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 3780045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @Test 3790045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar public void onUpdate_cascade_multipleReferences() { 3800045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new A("a1", "a2")); 3810045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar final A a = mDao.loadA(1); 3820045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.insert(new E("a1", "a2")); 3830045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(mDao.loadE(1), notNullValue()); 3840045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.changeNameA(1, "foo"); 3850045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(mDao.loadE(1), notNullValue()); 3860045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(mDao.loadE(1).aName, equalTo("foo")); 3870045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar assertThat(mDao.loadE(1).aLastName, equalTo("a2")); 3880045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 3890045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 3900045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @SuppressWarnings("Duplicates") 3910045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar private void deleteInTransaction(A a, B b) { 3920045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.beginTransaction(); 3930045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar try { 3940045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.delete(a); 3950045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.delete(b); 3960045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.setTransactionSuccessful(); 3970045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } finally { 3980045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.endTransaction(); 3990045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 4000045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 4010045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 4020045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar @SuppressWarnings("Duplicates") 4030045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar private void deleteInTransaction(A a, C c) { 4040045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.beginTransaction(); 4050045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar try { 4060045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.delete(a); 4070045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDao.delete(c); 4080045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.setTransactionSuccessful(); 4090045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } finally { 4100045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar mDb.endTransaction(); 4110045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 4120045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 4130045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 4140045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar private static Throwable catchException(ThrowingRunnable throwingRunnable) { 4150045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar try { 4160045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar throwingRunnable.run(); 4170045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } catch (Throwable t) { 4180045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar return t; 4190045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 4200045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar throw new RuntimeException("didn't throw an exception"); 4210045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 4220045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar 4230045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar private interface ThrowingRunnable { 4240045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar void run() throws Exception; 4250045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar } 4260045a1c980b44c882f4ece571a0a113d36bbf0fbYigit Boyar} 427