181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar/* 281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * Copyright 2018 The Android Open Source Project 381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * 481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * you may not use this file except in compliance with the License. 681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * You may obtain a copy of the License at 781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * 881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * 1081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * Unless required by applicable law or agreed to in writing, software 1181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 1281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * See the License for the specific language governing permissions and 1481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar * limitations under the License. 1581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar */ 1681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 17bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viverettepackage androidx.room.integration.testapp.test; 1881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 1981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarimport static org.hamcrest.CoreMatchers.is; 2081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarimport static org.hamcrest.MatcherAssert.assertThat; 2181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 2281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarimport static java.util.Collections.singletonList; 2381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 2481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarimport android.support.test.InstrumentationRegistry; 2581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarimport android.support.test.filters.SmallTest; 2681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarimport android.support.test.runner.AndroidJUnit4; 2781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 28bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.ColumnInfo; 29bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Dao; 30bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Database; 31bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Embedded; 32bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Entity; 33bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.ForeignKey; 34bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Index; 35bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Insert; 36bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.PrimaryKey; 37bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Query; 38bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Relation; 39bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Room; 40bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.RoomDatabase; 41bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.Transaction; 42bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viverette 4381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarimport org.junit.Before; 4481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarimport org.junit.Test; 4581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarimport org.junit.runner.RunWith; 4681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 4781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarimport java.util.List; 4881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 4981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar@RunWith(AndroidJUnit4.class) 5081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar@SmallTest 5181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyarpublic class RelationWithReservedKeywordTest { 5281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar private MyDatabase mDb; 5381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 5481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Before 5581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public void initDb() { 5681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar mDb = Room.inMemoryDatabaseBuilder( 5781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar InstrumentationRegistry.getTargetContext(), 5881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar MyDatabase.class).build(); 5981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 6081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 6181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Test 6281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public void loadRelation() { 6381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar Category category = new Category(1, "cat1"); 6481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar mDb.getDao().insert(category); 6581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar Topic topic = new Topic(2, 1, "foo"); 6681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar mDb.getDao().insert(topic); 6781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar List<CategoryWithTopics> categoryWithTopics = mDb.getDao().loadAll(); 6881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar assertThat(categoryWithTopics.size(), is(1)); 6981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar assertThat(categoryWithTopics.get(0).category, is(category)); 7081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar assertThat(categoryWithTopics.get(0).topics, is(singletonList(topic))); 7181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 7281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 7381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Entity(tableName = "categories") 7481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar static class Category { 7581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 7681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @PrimaryKey(autoGenerate = true) 7781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public final long id; 7881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 7981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public final String name; 8081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 8181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar Category(long id, String name) { 8281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar this.id = id; 8381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar this.name = name; 8481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 8581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 8681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Override 8781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public boolean equals(Object o) { 8881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar if (this == o) return true; 8981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar if (o == null || getClass() != o.getClass()) return false; 9081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar Category category = (Category) o; 91359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki //noinspection SimplifiableIfStatement 92359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki if (id != category.id) return false; 93359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki return name != null ? name.equals(category.name) : category.name == null; 9481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 9581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 9681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Override 9781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public int hashCode() { 98359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki int result = (int) (id ^ (id >>> 32)); 99359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki result = 31 * result + (name != null ? name.hashCode() : 0); 100359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki return result; 10181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 10281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 10381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 10481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Dao 10581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar interface MyDao { 10681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Transaction 10781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Query("SELECT * FROM categories") 10881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar List<CategoryWithTopics> loadAll(); 10981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 11081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Insert 11181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar void insert(Category... categories); 11281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 11381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Insert 11481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar void insert(Topic... topics); 11581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 11681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 11781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Database( 11881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar entities = {Category.class, Topic.class}, 11981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar version = 1, 12081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar exportSchema = false) 12181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar abstract static class MyDatabase extends RoomDatabase { 12281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar abstract MyDao getDao(); 12381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 12481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 12581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 12681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @SuppressWarnings("WeakerAccess") 12781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar static class CategoryWithTopics { 12881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Embedded 12981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public Category category; 13081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 13181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Relation( 13281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar parentColumn = "id", 13381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar entityColumn = "category_id", 13481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar entity = Topic.class) 13581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public List<Topic> topics; 13681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 13781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 13881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Entity( 13981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar tableName = "topics", 14081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar foreignKeys = @ForeignKey( 14181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar entity = Category.class, 14281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar parentColumns = "id", 14381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar childColumns = "category_id", 14481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar onDelete = ForeignKey.CASCADE), 14581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar indices = @Index("category_id")) 14681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar static class Topic { 14781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 14881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @PrimaryKey(autoGenerate = true) 14981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public final long id; 15081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 15181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @ColumnInfo(name = "category_id") 15281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public final long categoryId; 15381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 15481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public final String to; 15581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 15681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar Topic(long id, long categoryId, String to) { 15781642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar this.id = id; 15881642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar this.categoryId = categoryId; 15981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar this.to = to; 16081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 16181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 16281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Override 16381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public boolean equals(Object o) { 16481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar if (this == o) return true; 16581642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar if (o == null || getClass() != o.getClass()) return false; 16681642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar Topic topic = (Topic) o; 167359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki if (id != topic.id) return false; 168359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki //noinspection SimplifiableIfStatement 169359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki if (categoryId != topic.categoryId) return false; 170359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki return to != null ? to.equals(topic.to) : topic.to == null; 17181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 17281642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar 17381642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar @Override 17481642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar public int hashCode() { 175359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki int result = (int) (id ^ (id >>> 32)); 176359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki result = 31 * result + (int) (categoryId ^ (categoryId >>> 32)); 177359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki result = 31 * result + (to != null ? to.hashCode() : 0); 178359e3f1cf1dbc468b1bbdf58c6b74e7a5b6abb70Yuichi Araki return result; 17981642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 18081642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar } 18181642c82eef72885cbdf5b66b95f905d2c6250beYigit Boyar} 182