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