Merge "Add @Transaction annotation" into oc-mr1-dev
diff --git a/paging/common/build.gradle b/paging/common/build.gradle
index 78e12ba..bb9ad6b 100644
--- a/paging/common/build.gradle
+++ b/paging/common/build.gradle
@@ -28,7 +28,6 @@
testCompile libs.mockito_core
compile libs.support.annotations
compile project(path: ':arch:common')
- compile libs.junit
testCompile libs.kotlin.stdlib
}
diff --git a/paging/common/src/main/java/android/arch/paging/BoundedDataSource.java b/paging/common/src/main/java/android/arch/paging/BoundedDataSource.java
index 96c23fc..664ab16 100644
--- a/paging/common/src/main/java/android/arch/paging/BoundedDataSource.java
+++ b/paging/common/src/main/java/android/arch/paging/BoundedDataSource.java
@@ -18,6 +18,7 @@
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
+import android.support.annotation.WorkerThread;
import java.util.ArrayList;
import java.util.Collections;
@@ -49,15 +50,18 @@
* @return List of loaded items. Null if the BoundedDataSource is no longer valid, and should
* not be queried again.
*/
+ @WorkerThread
@Nullable
public abstract List<Value> loadRange(int startPosition, int loadCount);
+ @WorkerThread
@Nullable
@Override
public List<Value> loadAfter(int startIndex, int pageSize) {
return loadRange(startIndex, pageSize);
}
+ @WorkerThread
@Nullable
@Override
public List<Value> loadBefore(int startIndex, int pageSize) {
diff --git a/paging/common/src/main/java/android/arch/paging/DataSource.java b/paging/common/src/main/java/android/arch/paging/DataSource.java
index 1e81569..48fbec5 100644
--- a/paging/common/src/main/java/android/arch/paging/DataSource.java
+++ b/paging/common/src/main/java/android/arch/paging/DataSource.java
@@ -17,6 +17,7 @@
package android.arch.paging;
import android.support.annotation.AnyThread;
+import android.support.annotation.WorkerThread;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -64,6 +65,7 @@
* @return number of items that this DataSource can provide in total, or
* {@link #COUNT_UNDEFINED} if expensive or undesired to compute.
*/
+ @WorkerThread
public abstract int countItems();
/**
@@ -143,6 +145,7 @@
*
* @return True if the data source is invalid, and can no longer return data.
*/
+ @WorkerThread
public boolean isInvalid() {
return mInvalid.get();
}
diff --git a/paging/common/src/main/java/android/arch/paging/KeyedDataSource.java b/paging/common/src/main/java/android/arch/paging/KeyedDataSource.java
index 057eb7f..edd0776 100644
--- a/paging/common/src/main/java/android/arch/paging/KeyedDataSource.java
+++ b/paging/common/src/main/java/android/arch/paging/KeyedDataSource.java
@@ -16,6 +16,7 @@
package android.arch.paging;
+import android.support.annotation.AnyThread;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RestrictTo;
@@ -198,13 +199,16 @@
return list;
}
+ @AnyThread
@NonNull
public abstract Key getKey(@NonNull Value item);
+ @WorkerThread
public int countItemsBefore(@NonNull Key key) {
return COUNT_UNDEFINED;
}
+ @WorkerThread
public int countItemsAfter(@NonNull Key key) {
return COUNT_UNDEFINED;
}
diff --git a/paging/common/src/main/java/android/arch/paging/PagedList.java b/paging/common/src/main/java/android/arch/paging/PagedList.java
index 0d5313d..d5528a4 100644
--- a/paging/common/src/main/java/android/arch/paging/PagedList.java
+++ b/paging/common/src/main/java/android/arch/paging/PagedList.java
@@ -177,8 +177,8 @@
*
* @return The newly constructed PagedList
*/
- @NonNull
@WorkerThread
+ @NonNull
public PagedList<Value> build() {
if (mDataSource == null) {
throw new IllegalArgumentException("DataSource required");
diff --git a/paging/common/src/main/java/android/arch/paging/TiledDataSource.java b/paging/common/src/main/java/android/arch/paging/TiledDataSource.java
index 56556cd..cde04fb 100644
--- a/paging/common/src/main/java/android/arch/paging/TiledDataSource.java
+++ b/paging/common/src/main/java/android/arch/paging/TiledDataSource.java
@@ -17,6 +17,7 @@
package android.arch.paging;
import android.support.annotation.Nullable;
+import android.support.annotation.WorkerThread;
import java.util.List;
@@ -90,6 +91,7 @@
*
* @return Number of items this DataSource can provide. Must be <code>0</code> or greater.
*/
+ @WorkerThread
@Override
public abstract int countItems();
@@ -107,7 +109,7 @@
* @return List of loaded items. Null if the DataSource is no longer valid, and should
* not be queried again.
*/
- @SuppressWarnings("WeakerAccess")
+ @WorkerThread
public abstract List<Type> loadRange(int startPosition, int count);
final List<Type> loadRangeWrapper(int startPosition, int count) {
@@ -132,6 +134,7 @@
mTiledDataSource = tiledDataSource;
}
+ @WorkerThread
@Nullable
@Override
public List<Value> loadRange(int startPosition, int loadCount) {
diff --git a/paging/runtime/src/main/java/android/arch/paging/LivePagedListProvider.java b/paging/runtime/src/main/java/android/arch/paging/LivePagedListProvider.java
index 6304b29..0ee9b7a 100644
--- a/paging/runtime/src/main/java/android/arch/paging/LivePagedListProvider.java
+++ b/paging/runtime/src/main/java/android/arch/paging/LivePagedListProvider.java
@@ -19,6 +19,8 @@
import android.arch.core.executor.AppToolkitTaskExecutor;
import android.arch.lifecycle.ComputableLiveData;
import android.arch.lifecycle.LiveData;
+import android.support.annotation.AnyThread;
+import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.WorkerThread;
@@ -68,6 +70,8 @@
*
* @return The LiveData of PagedLists.
*/
+ @AnyThread
+ @NonNull
public LiveData<PagedList<Value>> create(@Nullable Key initialLoadKey, int pageSize) {
return create(initialLoadKey,
new PagedList.Config.Builder()
@@ -87,6 +91,8 @@
*
* @return The LiveData of PagedLists.
*/
+ @AnyThread
+ @NonNull
public LiveData<PagedList<Value>> create(@Nullable final Key initialLoadKey,
final PagedList.Config config) {
return new ComputableLiveData<PagedList<Value>>() {
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/EntityProcessor.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/EntityProcessor.kt
index 4f4a7f4..c9e3e18 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/EntityProcessor.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/EntityProcessor.kt
@@ -233,6 +233,19 @@
collectPrimaryKeysFromEmbeddedFields(embeddedFields)
context.checker.check(candidates.isNotEmpty(), element, ProcessorErrors.MISSING_PRIMARY_KEY)
+
+ // 1. If a key is not autogenerated, but is Primary key or is part of Primary key we
+ // force the @NonNull annotation
+ // 2. If a key is autogenerate, we generate NOT NULL in table spec, but we don't require
+ // @NonNull annotation on the field itself.
+ candidates.filter { candidate -> !candidate.autoGenerateId }
+ .map { candidate ->
+ candidate.fields.map { field ->
+ context.checker.check(field.nonNull, field.element,
+ ProcessorErrors.PRIMARY_KEY_NULL)
+ }
+ }
+
if (candidates.size == 1) {
// easy :)
return candidates.first()
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt
index 20ce2ff..a576aa2 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/ProcessorErrors.kt
@@ -449,4 +449,8 @@
""".trim()
val PAGING_SPECIFY_DATA_SOURCE_TYPE = "For now, Room only supports TiledDataSource class."
+
+ val PRIMARY_KEY_NULL = "You must annotate primary keys with @NonNull. SQLite considers this a " +
+ "bug and Room does not allow it. See SQLite docs for details: " +
+ "https://www.sqlite.org/lang_createtable.html"
}
diff --git a/room/compiler/src/test/data/common/input/MultiPKeyEntity.java b/room/compiler/src/test/data/common/input/MultiPKeyEntity.java
index dccb9dd..59570ad 100644
--- a/room/compiler/src/test/data/common/input/MultiPKeyEntity.java
+++ b/room/compiler/src/test/data/common/input/MultiPKeyEntity.java
@@ -15,9 +15,12 @@
*/
package foo.bar;
+import android.support.annotation.NonNull;
import android.arch.persistence.room.*;
@Entity(primaryKeys = {"name", "lastName"})
public class MultiPKeyEntity {
+ @NonNull
String name;
+ @NonNull
String lastName;
}
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/BaseEntityParserTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/BaseEntityParserTest.kt
index 9bfc0e7..7893200 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/BaseEntityParserTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/BaseEntityParserTest.kt
@@ -20,6 +20,7 @@
import android.arch.persistence.room.testing.TestInvocation
import android.arch.persistence.room.testing.TestProcessor
import android.arch.persistence.room.vo.Entity
+import android.support.annotation.NonNull
import com.google.auto.common.MoreElements
import com.google.common.truth.Truth
import com.google.testing.compile.CompileTester
@@ -68,7 +69,8 @@
android.arch.persistence.room.PrimaryKey::class,
android.arch.persistence.room.Ignore::class,
Embedded::class,
- android.arch.persistence.room.ColumnInfo::class)
+ android.arch.persistence.room.ColumnInfo::class,
+ NonNull::class)
.nextRunHandler { invocation ->
val entity = invocation.roundEnv
.getElementsAnnotatedWith(
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt
index 2238eb2..c25d001 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/processor/EntityProcessorTest.kt
@@ -18,6 +18,7 @@
import COMMON
import android.arch.persistence.room.parser.SQLTypeAffinity
+import android.arch.persistence.room.processor.ProcessorErrors.PRIMARY_KEY_NULL
import android.arch.persistence.room.processor.ProcessorErrors.RELATION_IN_ENTITY
import android.arch.persistence.room.vo.CallType
import android.arch.persistence.room.vo.Field
@@ -1025,6 +1026,7 @@
@Embedded(prefix = "bar_")
@PrimaryKey
+ @NonNull
public Foo foo;
static class Foo {
@@ -1042,6 +1044,7 @@
val parent = JavaFileObjects.forSourceLines("foo.bar.Base",
"""
package foo.bar;
+ import android.support.annotation.NonNull;
import android.arch.persistence.room.*;
public class Base {
@@ -1049,6 +1052,7 @@
String name, lastName;
@Embedded(prefix = "bar_")
@PrimaryKey
+ @NonNull
public Foo foo;
static class Foo {
@@ -1086,6 +1090,7 @@
public int id;
@Embedded(prefix = "bar_")
@PrimaryKey
+ @NonNull
public Foo foo;
static class Foo {
@@ -1106,6 +1111,7 @@
val parent = JavaFileObjects.forSourceLines("foo.bar.Base",
"""
package foo.bar;
+ import android.support.annotation.NonNull;
import android.arch.persistence.room.*;
public class Base {
@@ -1113,6 +1119,7 @@
String name, lastName;
@Embedded(prefix = "bar_")
@PrimaryKey
+ @NonNull
public Foo foo;
static class Foo {
@@ -1135,6 +1142,80 @@
}
@Test
+ fun primaryKey_NonNull() {
+ singleEntity(
+ """
+ @PrimaryKey
+ @NonNull
+ public String id;
+ """) { entity, _ ->
+ assertThat(entity.primaryKey.fields.size, `is`(1))
+ assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
+ }.compilesWithoutError()
+ }
+
+ @Test
+ fun primaryKey_Nullable() {
+ singleEntity(
+ """
+ @PrimaryKey
+ public String id;
+ """) { entity, _ ->
+ assertThat(entity.primaryKey.fields.size, `is`(1))
+ assertThat(entity.primaryKey.fields.firstOrNull()?.name, `is`("id"))
+ }.failsToCompile().withErrorContaining(PRIMARY_KEY_NULL)
+ }
+
+ @Test
+ fun primaryKey_MultipleNullable() {
+ singleEntity(
+ """
+ @PrimaryKey
+ public String id;
+ @PrimaryKey
+ public String anotherId;
+ """) { entity, _ ->
+ }.failsToCompile().withErrorContaining(PRIMARY_KEY_NULL)
+ }
+
+ @Test
+ fun primaryKey_MultipleNullableAndNonNullable() {
+ singleEntity(
+ """
+ @PrimaryKey
+ @NonNull
+ public String id;
+ @PrimaryKey
+ public String anotherId;
+ """) { entity, _ ->
+ }.failsToCompile().withErrorContaining(PRIMARY_KEY_NULL)
+ }
+
+ @Test
+ fun primaryKey_definedAsAttributesNullable() {
+ singleEntity(
+ """
+ public int id;
+ public String foo;
+ """,
+ attributes = mapOf("primaryKeys" to "{\"id\", \"foo\"}")) { _, _ ->
+ }.failsToCompile().withErrorContaining(PRIMARY_KEY_NULL)
+ }
+
+ @Test
+ fun primaryKey_definedAsAttributesNonNull() {
+ singleEntity(
+ """
+ public int id;
+ @NonNull
+ public String foo;
+ """,
+ attributes = mapOf("primaryKeys" to "{\"id\", \"foo\"}")) { entity, _ ->
+ assertThat(entity.primaryKey.fields.map { it.name }, `is`(listOf("id", "foo")))
+ }.compilesWithoutError()
+ }
+
+ @Test
fun relationInEntity() {
singleEntity(
"""
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriterTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriterTest.kt
index b93972f..2e86a00 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriterTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/writer/SQLiteOpenHelperWriterTest.kt
@@ -20,6 +20,7 @@
import android.arch.persistence.room.testing.TestInvocation
import android.arch.persistence.room.testing.TestProcessor
import android.arch.persistence.room.vo.Database
+import android.support.annotation.NonNull
import com.google.auto.common.MoreElements
import com.google.common.truth.Truth
import com.google.testing.compile.CompileTester
@@ -36,6 +37,7 @@
companion object {
const val ENTITY_PREFIX = """
package foo.bar;
+ import android.support.annotation.NonNull;
import android.arch.persistence.room.*;
@Entity%s
public class MyEntity {
@@ -55,6 +57,7 @@
singleEntity(
"""
@PrimaryKey
+ @NonNull
String uuid;
String name;
int age;
@@ -63,7 +66,7 @@
val query = SQLiteOpenHelperWriter(database)
.createQuery(database.entities.first())
assertThat(query, `is`("CREATE TABLE IF NOT EXISTS" +
- " `MyEntity` (`uuid` TEXT, `name` TEXT, `age` INTEGER NOT NULL," +
+ " `MyEntity` (`uuid` TEXT NOT NULL, `name` TEXT, `age` INTEGER NOT NULL," +
" PRIMARY KEY(`uuid`))"))
}.compilesWithoutError()
}
@@ -72,7 +75,9 @@
fun multiplePrimaryKeys() {
singleEntity(
"""
+ @NonNull
String uuid;
+ @NonNull
String name;
int age;
""".trimIndent(), attributes = mapOf("primaryKeys" to "{\"uuid\", \"name\"}")
@@ -80,27 +85,49 @@
val query = SQLiteOpenHelperWriter(database)
.createQuery(database.entities.first())
assertThat(query, `is`("CREATE TABLE IF NOT EXISTS" +
- " `MyEntity` (`uuid` TEXT, `name` TEXT, `age` INTEGER NOT NULL," +
- " PRIMARY KEY(`uuid`, `name`))"))
+ " `MyEntity` (`uuid` TEXT NOT NULL, `name` TEXT NOT NULL, " +
+ "`age` INTEGER NOT NULL, PRIMARY KEY(`uuid`, `name`))"))
}.compilesWithoutError()
}
@Test
- fun autoIncrement() {
- singleEntity(
- """
+ fun autoIncrementObject() {
+ listOf("Long", "Integer").forEach { type ->
+ singleEntity(
+ """
@PrimaryKey(autoGenerate = true)
- int uuid;
+ $type uuid;
String name;
int age;
""".trimIndent()
- ) { database, _ ->
- val query = SQLiteOpenHelperWriter(database)
- .createQuery(database.entities.first())
- assertThat(query, `is`("CREATE TABLE IF NOT EXISTS" +
- " `MyEntity` (`uuid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
- " `name` TEXT, `age` INTEGER NOT NULL)"))
- }.compilesWithoutError()
+ ) { database, _ ->
+ val query = SQLiteOpenHelperWriter(database)
+ .createQuery(database.entities.first())
+ assertThat(query, `is`("CREATE TABLE IF NOT EXISTS" +
+ " `MyEntity` (`uuid` INTEGER PRIMARY KEY AUTOINCREMENT," +
+ " `name` TEXT, `age` INTEGER NOT NULL)"))
+ }.compilesWithoutError()
+ }
+ }
+
+ @Test
+ fun autoIncrementPrimitives() {
+ listOf("long", "int").forEach { type ->
+ singleEntity(
+ """
+ @PrimaryKey(autoGenerate = true)
+ $type uuid;
+ String name;
+ int age;
+ """.trimIndent()
+ ) { database, _ ->
+ val query = SQLiteOpenHelperWriter(database)
+ .createQuery(database.entities.first())
+ assertThat(query, `is`("CREATE TABLE IF NOT EXISTS" +
+ " `MyEntity` (`uuid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL," +
+ " `name` TEXT, `age` INTEGER NOT NULL)"))
+ }.compilesWithoutError()
+ }
}
fun singleEntity(input: String, attributes: Map<String, String> = mapOf(),
@@ -119,7 +146,8 @@
), JavaFileObjects.forSourceString("foo.bar.MyDatabase",
DATABASE_CODE)))
.processedWith(TestProcessor.builder()
- .forAnnotations(android.arch.persistence.room.Database::class)
+ .forAnnotations(android.arch.persistence.room.Database::class,
+ NonNull::class)
.nextRunHandler { invocation ->
val db = MoreElements.asType(invocation.roundEnv
.getElementsAnnotatedWith(
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/PKeyTestDatabase.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/PKeyTestDatabase.java
index e61d808..b6339a8 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/PKeyTestDatabase.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/PKeyTestDatabase.java
@@ -23,14 +23,17 @@
import android.arch.persistence.room.RoomDatabase;
import android.arch.persistence.room.integration.testapp.vo.IntAutoIncPKeyEntity;
import android.arch.persistence.room.integration.testapp.vo.IntegerAutoIncPKeyEntity;
+import android.arch.persistence.room.integration.testapp.vo.ObjectPKeyEntity;
import java.util.List;
-@Database(entities = {IntAutoIncPKeyEntity.class, IntegerAutoIncPKeyEntity.class}, version = 1,
+@Database(entities = {IntAutoIncPKeyEntity.class, IntegerAutoIncPKeyEntity.class,
+ ObjectPKeyEntity.class}, version = 1,
exportSchema = false)
public abstract class PKeyTestDatabase extends RoomDatabase {
public abstract IntPKeyDao intPKeyDao();
public abstract IntegerPKeyDao integerPKeyDao();
+ public abstract ObjectPKeyDao objectPKeyDao();
@Dao
public interface IntPKeyDao {
@@ -52,7 +55,8 @@
@Dao
public interface IntegerPKeyDao {
@Insert
- void insertMe(IntegerAutoIncPKeyEntity items);
+ void insertMe(IntegerAutoIncPKeyEntity item);
+
@Query("select * from IntegerAutoIncPKeyEntity WHERE pKey = :key")
IntegerAutoIncPKeyEntity getMe(int key);
@@ -65,4 +69,10 @@
@Query("select data from IntegerAutoIncPKeyEntity WHERE pKey IN(:ids)")
List<String> loadDataById(long... ids);
}
+
+ @Dao
+ public interface ObjectPKeyDao {
+ @Insert
+ void insertMe(ObjectPKeyEntity item);
+ }
}
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/PrimaryKeyTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/PrimaryKeyTest.java
index 97ce10c..8d213f2 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/PrimaryKeyTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/PrimaryKeyTest.java
@@ -16,18 +16,21 @@
package android.arch.persistence.room.integration.testapp.test;
+import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.MatcherAssert.assertThat;
-
-import android.support.test.InstrumentationRegistry;
-import android.support.test.filters.SmallTest;
-import android.support.test.runner.AndroidJUnit4;
+import static org.junit.Assert.assertNotNull;
import android.arch.persistence.room.Room;
import android.arch.persistence.room.integration.testapp.PKeyTestDatabase;
import android.arch.persistence.room.integration.testapp.vo.IntAutoIncPKeyEntity;
import android.arch.persistence.room.integration.testapp.vo.IntegerAutoIncPKeyEntity;
+import android.arch.persistence.room.integration.testapp.vo.ObjectPKeyEntity;
+import android.database.sqlite.SQLiteConstraintException;
+import android.support.test.InstrumentationRegistry;
+import android.support.test.filters.SmallTest;
+import android.support.test.runner.AndroidJUnit4;
import org.junit.Before;
import org.junit.Test;
@@ -39,6 +42,7 @@
@SmallTest
public class PrimaryKeyTest {
private PKeyTestDatabase mDatabase;
+
@Before
public void setup() {
mDatabase = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getTargetContext(),
@@ -111,4 +115,18 @@
final long[] ids = mDatabase.integerPKeyDao().insertAndGetIds(entity, entity2);
assertThat(mDatabase.integerPKeyDao().loadDataById(ids), is(Arrays.asList("foo", "foo2")));
}
+
+ @Test
+ public void insertNullPrimaryKey() throws Exception {
+ ObjectPKeyEntity o1 = new ObjectPKeyEntity(null, "1");
+
+ Throwable throwable = null;
+ try {
+ mDatabase.objectPKeyDao().insertMe(o1);
+ } catch (Throwable t) {
+ throwable = t;
+ }
+ assertNotNull("Was expecting an exception", throwable);
+ assertThat(throwable, instanceOf(SQLiteConstraintException.class));
+ }
}
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/ObjectPKeyEntity.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/ObjectPKeyEntity.java
new file mode 100644
index 0000000..895a35a
--- /dev/null
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/ObjectPKeyEntity.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License 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 android.arch.persistence.room.integration.testapp.vo;
+
+import android.arch.persistence.room.Entity;
+import android.arch.persistence.room.PrimaryKey;
+import android.support.annotation.NonNull;
+
+@Entity
+public class ObjectPKeyEntity {
+ @PrimaryKey
+ @NonNull
+ public String pKey;
+ public String data;
+
+ public ObjectPKeyEntity(String pKey, String data) {
+ this.pKey = pKey;
+ this.data = data;
+ }
+}
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/PetCouple.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/PetCouple.java
index f27b131..e5208ed 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/PetCouple.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/PetCouple.java
@@ -20,11 +20,13 @@
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.PrimaryKey;
import android.arch.persistence.room.RoomWarnings;
+import android.support.annotation.NonNull;
@Entity
@SuppressWarnings(RoomWarnings.PRIMARY_KEY_FROM_EMBEDDED_IS_DROPPED)
public class PetCouple {
@PrimaryKey
+ @NonNull
public String id;
@Embedded(prefix = "male_")
public Pet male;
diff --git a/room/integration-tests/testapp/src/main/java/android/arch/persistence/room/integration/testapp/database/SampleDatabase.java b/room/integration-tests/testapp/src/main/java/android/arch/persistence/room/integration/testapp/database/SampleDatabase.java
index eec59f6..9020eb1 100644
--- a/room/integration-tests/testapp/src/main/java/android/arch/persistence/room/integration/testapp/database/SampleDatabase.java
+++ b/room/integration-tests/testapp/src/main/java/android/arch/persistence/room/integration/testapp/database/SampleDatabase.java
@@ -18,10 +18,6 @@
import android.arch.persistence.room.Database;
import android.arch.persistence.room.RoomDatabase;
-import android.arch.persistence.room.TypeConverter;
-import android.arch.persistence.room.TypeConverters;
-
-import java.util.Date;
/**
* Sample database of customers.
diff --git a/room/runtime/src/main/java/android/arch/persistence/room/RoomDatabase.java b/room/runtime/src/main/java/android/arch/persistence/room/RoomDatabase.java
index e64f2d6..f6f8c5c 100644
--- a/room/runtime/src/main/java/android/arch/persistence/room/RoomDatabase.java
+++ b/room/runtime/src/main/java/android/arch/persistence/room/RoomDatabase.java
@@ -311,7 +311,6 @@
private ArrayList<Callback> mCallbacks;
private SupportSQLiteOpenHelper.Factory mFactory;
- private boolean mInMemory;
private boolean mAllowMainThreadQueries;
private boolean mRequireMigration;
/**
diff --git a/v7/appcompat/res/values/attrs.xml b/v7/appcompat/res/values/attrs.xml
index d48d826..52ae694 100644
--- a/v7/appcompat/res/values/attrs.xml
+++ b/v7/appcompat/res/values/attrs.xml
@@ -568,6 +568,9 @@
<enum name="multiply" value="14" />
<!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
<enum name="screen" value="15" />
+ <!-- Combines the tint and icon color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
</attr>
</declare-styleable>
@@ -1037,6 +1040,9 @@
<enum name="multiply" value="14" />
<!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
<enum name="screen" value="15" />
+ <!-- Combines the tint and icon color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
</attr>
</declare-styleable>
@@ -1175,6 +1181,9 @@
<enum name="multiply" value="14" />
<!-- [Sa + Da - Sa * Da, Sc + Dc - Sc * Dc] -->
<enum name="screen" value="15" />
+ <!-- Combines the tint and icon color and alpha channels, clamping the
+ result to valid color values. Saturate(S + D) -->
+ <enum name="add" value="16" />
</attr>
</declare-styleable>