Merge "Fix @Query without any parameters" into oc-support-26.0-dev
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/DaoWriter.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/DaoWriter.kt
index 26d41e4..7fba7fb 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/DaoWriter.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/writer/DaoWriter.kt
@@ -121,7 +121,7 @@
             val fieldImpl = PreparedStatementWriter(queryWriter)
                     .createAnonymous(this@DaoWriter, dbField)
             val methodBody = createPreparedDeleteQueryMethodBody(method, fieldSpec, queryWriter)
-            PreparedStmtQuery(mapOf(method.parameters.first().name
+            PreparedStmtQuery(mapOf(PreparedStmtQuery.NO_PARAM_FIELD
                     to (fieldSpec to fieldImpl)), methodBody)
         }
     }
@@ -402,8 +402,22 @@
         }
     }
 
+    /**
+     * Represents a query statement prepared in Dao implementation.
+     *
+     * @param fields This map holds all the member fields necessary for this query. The key is the
+     * corresponding parameter name in the defining query method. The value is a pair from the field
+     * declaration to definition.
+     * @param methodImpl The body of the query method implementation.
+     */
     data class PreparedStmtQuery(val fields: Map<String, Pair<FieldSpec, TypeSpec>>,
-                                 val methodImpl: MethodSpec)
+                                 val methodImpl: MethodSpec) {
+        companion object {
+            // The key to be used in `fields` where the method requires a field that is not
+            // associated with any of its parameters
+            const val NO_PARAM_FIELD = "-"
+        }
+    }
 
     private class InsertionMethodField(val entity: Entity, val onConflictText: String)
         : SharedFieldSpec(
diff --git a/room/compiler/src/test/data/daoWriter/input/DeletionDao.java b/room/compiler/src/test/data/daoWriter/input/DeletionDao.java
index a531ad6..997f290 100644
--- a/room/compiler/src/test/data/daoWriter/input/DeletionDao.java
+++ b/room/compiler/src/test/data/daoWriter/input/DeletionDao.java
@@ -45,4 +45,7 @@
 
     @Delete
     void deleteUserAndBook(User user, Book book);
+
+    @Query("DELETE FROM user")
+    int deleteEverything();
 }
diff --git a/room/compiler/src/test/data/daoWriter/input/UpdateDao.java b/room/compiler/src/test/data/daoWriter/input/UpdateDao.java
index b9a80c1..040b5c7 100644
--- a/room/compiler/src/test/data/daoWriter/input/UpdateDao.java
+++ b/room/compiler/src/test/data/daoWriter/input/UpdateDao.java
@@ -39,4 +39,10 @@
 
     @Update
     void updateUserAndBook(User user, Book book);
+
+    @Query("UPDATE User SET ageColumn = ageColumn + 1 WHERE uid = :uid")
+    void ageUserByUid(String uid);
+
+    @Query("UPDATE User SET ageColumn = ageColumn + 1")
+    void ageUserAll();
 }
diff --git a/room/compiler/src/test/data/daoWriter/output/DeletionDao.java b/room/compiler/src/test/data/daoWriter/output/DeletionDao.java
index e0487a0..d5e173f 100644
--- a/room/compiler/src/test/data/daoWriter/output/DeletionDao.java
+++ b/room/compiler/src/test/data/daoWriter/output/DeletionDao.java
@@ -21,6 +21,8 @@
 
   private final SharedSQLiteStatement __preparedStmtOfDeleteByUid;
 
+  private final SharedSQLiteStatement __preparedStmtOfDeleteEverything;
+
   public DeletionDao_Impl(RoomDatabase __db) {
     this.__db = __db;
     this.__deletionAdapterOfUser = new EntityDeletionOrUpdateAdapter<User>(__db) {
@@ -72,6 +74,13 @@
         return _query;
       }
     };
+    this.__preparedStmtOfDeleteEverything = new SharedSQLiteStatement(__db) {
+      @Override
+      public String createQuery() {
+        final String _query = "DELETE FROM user";
+        return _query;
+      }
+    };
   }
 
   @Override
@@ -190,6 +199,20 @@
   }
 
   @Override
+  public int deleteEverything() {
+    final SupportSQLiteStatement _stmt = __preparedStmtOfDeleteEverything.acquire();
+    __db.beginTransaction();
+    try {
+      final int _result = _stmt.executeUpdateDelete();
+      __db.setTransactionSuccessful();
+      return _result;
+    } finally {
+      __db.endTransaction();
+      __preparedStmtOfDeleteEverything.release(_stmt);
+    }
+  }
+
+  @Override
   public int deleteByUidList(int... uid) {
     StringBuilder _stringBuilder = StringUtil.newStringBuilder();
     _stringBuilder.append("DELETE FROM user where uid IN(");
diff --git a/room/compiler/src/test/data/daoWriter/output/UpdateDao.java b/room/compiler/src/test/data/daoWriter/output/UpdateDao.java
index 38f8c59..1b26b6a 100644
--- a/room/compiler/src/test/data/daoWriter/output/UpdateDao.java
+++ b/room/compiler/src/test/data/daoWriter/output/UpdateDao.java
@@ -3,6 +3,7 @@
 import android.arch.persistence.db.SupportSQLiteStatement;
 import android.arch.persistence.room.EntityDeletionOrUpdateAdapter;
 import android.arch.persistence.room.RoomDatabase;
+import android.arch.persistence.room.SharedSQLiteStatement;
 import java.lang.Override;
 import java.lang.String;
 import java.util.List;
@@ -16,6 +17,10 @@
 
   private final EntityDeletionOrUpdateAdapter __updateAdapterOfBook;
 
+  private final SharedSQLiteStatement __preparedStmtOfAgeUserByUid;
+
+  private final SharedSQLiteStatement __preparedStmtOfAgeUserAll;
+
   public UpdateDao_Impl(RoomDatabase __db) {
     this.__db = __db;
     this.__updateAdapterOfUser = new EntityDeletionOrUpdateAdapter<User>(__db) {
@@ -84,6 +89,20 @@
         stmt.bindLong(3, value.bookId);
       }
     };
+    this.__preparedStmtOfAgeUserByUid = new SharedSQLiteStatement(__db) {
+      @Override
+      public String createQuery() {
+        final String _query = "UPDATE User SET ageColumn = ageColumn + 1 WHERE uid = ?";
+        return _query;
+      }
+    };
+    this.__preparedStmtOfAgeUserAll = new SharedSQLiteStatement(__db) {
+      @Override
+      public String createQuery() {
+        final String _query = "UPDATE User SET ageColumn = ageColumn + 1";
+        return _query;
+      }
+    };
   }
 
   @Override
@@ -184,4 +203,36 @@
       __db.endTransaction();
     }
   }
+
+  @Override
+  public void ageUserByUid(String uid) {
+    final SupportSQLiteStatement _stmt = __preparedStmtOfAgeUserByUid.acquire();
+    __db.beginTransaction();
+    try {
+      int _argIndex = 1;
+      if (uid == null) {
+        _stmt.bindNull(_argIndex);
+      } else {
+        _stmt.bindString(_argIndex, uid);
+      }
+      _stmt.executeUpdateDelete();
+      __db.setTransactionSuccessful();
+    } finally {
+      __db.endTransaction();
+      __preparedStmtOfAgeUserByUid.release(_stmt);
+    }
+  }
+
+  @Override
+  public void ageUserAll() {
+    final SupportSQLiteStatement _stmt = __preparedStmtOfAgeUserAll.acquire();
+    __db.beginTransaction();
+    try {
+      _stmt.executeUpdateDelete();
+      __db.setTransactionSuccessful();
+    } finally {
+      __db.endTransaction();
+      __preparedStmtOfAgeUserAll.release(_stmt);
+    }
+  }
 }
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java
index 3fc8775..f609b42 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java
@@ -71,6 +71,9 @@
     @Delete
     public abstract int deleteAll(User[] users);
 
+    @Query("delete from user")
+    public abstract int deleteEverything();
+
     @Update
     public abstract int update(User user);
 
@@ -98,6 +101,9 @@
     @Query("update user set mId = mId + :amount")
     public abstract void incrementIds(int amount);
 
+    @Query("update user set mAge = mAge + 1")
+    public abstract void incrementAgeOfAll();
+
     @Query("select mId from user order by mId ASC")
     public abstract List<Integer> loadIds();
 
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
index fe363a2..8019f6b 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
@@ -223,6 +223,16 @@
     }
 
     @Test
+    public void deleteEverything() {
+        User user = TestUtil.createUser(3);
+        mUserDao.insert(user);
+        assertThat(mUserDao.count(), is(1));
+        int count = mUserDao.deleteEverything();
+        assertThat(count, is(1));
+        assertThat(mUserDao.count(), is(0));
+    }
+
+    @Test
     public void findByBoolean() {
         User user1 = TestUtil.createUser(3);
         user1.setAdmin(true);
@@ -291,6 +301,20 @@
     }
 
     @Test
+    public void incrementAgeOfAll() {
+        User[] users = TestUtil.createUsersArray(3, 5, 7);
+        users[0].setAge(3);
+        users[1].setAge(5);
+        users[2].setAge(7);
+        mUserDao.insertAll(users);
+        assertThat(mUserDao.count(), is(3));
+        mUserDao.incrementAgeOfAll();
+        for (User user : mUserDao.loadByIds(3, 5, 7)) {
+            assertThat(user.getAge(), is(user.getId() + 1));
+        }
+    }
+
+    @Test
     public void findByIntQueryParameter() {
         User user = TestUtil.createUser(1);
         final String name = "my name";