1b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar/* 2b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * Copyright (C) 2017 The Android Open Source Project 3b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * 4b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * Licensed under the Apache License, Version 2.0 (the "License"); 5b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * you may not use this file except in compliance with the License. 6b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * You may obtain a copy of the License at 7b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * 8b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * http://www.apache.org/licenses/LICENSE-2.0 9b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * 10b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * Unless required by applicable law or agreed to in writing, software 11b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * distributed under the License is distributed on an "AS IS" BASIS, 12b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * See the License for the specific language governing permissions and 14b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * limitations under the License. 15b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar */ 16b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 1764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarpackage android.arch.persistence.room; 18b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 1964db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.db.SupportSQLiteProgram; 2064db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyarimport android.arch.persistence.db.SupportSQLiteQuery; 21b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyarimport android.support.annotation.IntDef; 228fed7d5361340af73d78232244697117675ac5c3Yigit Boyarimport android.support.annotation.RestrictTo; 23b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyarimport android.support.annotation.VisibleForTesting; 24b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 259691051d4acf7de89396388ca195f0c569257804Yigit Boyarimport java.lang.annotation.Retention; 269691051d4acf7de89396388ca195f0c569257804Yigit Boyarimport java.lang.annotation.RetentionPolicy; 27b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyarimport java.util.Arrays; 28b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyarimport java.util.Iterator; 29b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyarimport java.util.Map; 30b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyarimport java.util.TreeMap; 31b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 32b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar/** 33b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * This class is used as an intermediate place to keep binding arguments so that we can run 34b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * Cursor queries with correct types rather than passing everything as a string. 35b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * <p> 36b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * Because it is relatively a big object, they are pooled and must be released after each use. 3764db0cc15b78b62a1d44a70fc8b4552e660d952cYigit Boyar * 388fed7d5361340af73d78232244697117675ac5c3Yigit Boyar * @hide 39b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar */ 40b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar@SuppressWarnings("unused") 418fed7d5361340af73d78232244697117675ac5c3Yigit Boyar@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) 42b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyarpublic class RoomSQLiteQuery implements SupportSQLiteQuery, SupportSQLiteProgram { 43b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @SuppressWarnings("WeakerAccess") 44b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @VisibleForTesting 458fed7d5361340af73d78232244697117675ac5c3Yigit Boyar // Maximum number of queries we'll keep cached. 46b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar static final int POOL_LIMIT = 15; 47b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @SuppressWarnings("WeakerAccess") 48b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @VisibleForTesting 498fed7d5361340af73d78232244697117675ac5c3Yigit Boyar // Once we hit POOL_LIMIT, we'll bring the pool size back to the desired number. We always 508fed7d5361340af73d78232244697117675ac5c3Yigit Boyar // clear the bigger queries (# of arguments). 51b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar static final int DESIRED_POOL_SIZE = 10; 52b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar private volatile String mQuery; 53b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @SuppressWarnings("WeakerAccess") 54b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @VisibleForTesting 55b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar final long[] mLongBindings; 56b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @SuppressWarnings("WeakerAccess") 57b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @VisibleForTesting 58b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar final double[] mDoubleBindings; 59b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @SuppressWarnings("WeakerAccess") 60b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @VisibleForTesting 61b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar final String[] mStringBindings; 62b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @SuppressWarnings("WeakerAccess") 63b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @VisibleForTesting 64b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar final byte[][] mBlobBindings; 65b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 66b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @Binding 67b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar private final int[] mBindingTypes; 68b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @SuppressWarnings("WeakerAccess") 69b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @VisibleForTesting 70b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar final int mCapacity; 71b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar // number of arguments in the query 72b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @SuppressWarnings("WeakerAccess") 73b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @VisibleForTesting 74b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar int mArgCount; 75b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 76b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 77b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @SuppressWarnings("WeakerAccess") 78b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @VisibleForTesting 79b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar static final TreeMap<Integer, RoomSQLiteQuery> sQueryPool = new TreeMap<>(); 80b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 81b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar /** 82b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * Returns a new RoomSQLiteQuery that can accept the given number of arguments and holds the 83b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * given query. 84b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * 85b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * @param query The query to prepare 86b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * @param argumentCount The number of query arguments 87b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * @return A RoomSQLiteQuery that holds the given query and has space for the given number of 88b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * arguments. 89b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar */ 908fed7d5361340af73d78232244697117675ac5c3Yigit Boyar @SuppressWarnings("WeakerAccess") 91b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar public static RoomSQLiteQuery acquire(String query, int argumentCount) { 92b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar synchronized (sQueryPool) { 93b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar final Map.Entry<Integer, RoomSQLiteQuery> entry = 94b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar sQueryPool.ceilingEntry(argumentCount); 95b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar if (entry != null) { 96b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar sQueryPool.remove(entry.getKey()); 97b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar final RoomSQLiteQuery sqliteQuery = entry.getValue(); 98b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar sqliteQuery.init(query, argumentCount); 99b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar return sqliteQuery; 100b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 101b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 102b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar RoomSQLiteQuery sqLiteQuery = new RoomSQLiteQuery(argumentCount); 103b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar sqLiteQuery.init(query, argumentCount); 104b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar return sqLiteQuery; 105b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 106b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 107b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar private RoomSQLiteQuery(int capacity) { 108b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mCapacity = capacity; 109b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar // because, 1 based indices... we don't want to offsets everything with 1 all the time. 110b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar int limit = capacity + 1; 111b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar //noinspection WrongConstant 112b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mBindingTypes = new int[limit]; 113b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mLongBindings = new long[limit]; 114b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mDoubleBindings = new double[limit]; 115b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mStringBindings = new String[limit]; 116b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mBlobBindings = new byte[limit][]; 117b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 118b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 119b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @SuppressWarnings("WeakerAccess") 120b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar void init(String query, int argCount) { 121b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mQuery = query; 122b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mArgCount = argCount; 123b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 124b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 125b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar /** 126b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar * Releases the query back to the pool. 1278fed7d5361340af73d78232244697117675ac5c3Yigit Boyar * <p> 1288fed7d5361340af73d78232244697117675ac5c3Yigit Boyar * After released, the statement might be returned when {@link #acquire(String, int)} is called 1298fed7d5361340af73d78232244697117675ac5c3Yigit Boyar * so you should never re-use it after releasing. 130b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar */ 1318fed7d5361340af73d78232244697117675ac5c3Yigit Boyar @SuppressWarnings("WeakerAccess") 132b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar public void release() { 133b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar synchronized (sQueryPool) { 134b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar sQueryPool.put(mCapacity, this); 135b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar prunePoolLocked(); 136b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 137b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 138b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 139b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar private static void prunePoolLocked() { 140b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar if (sQueryPool.size() > POOL_LIMIT) { 141b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar int toBeRemoved = sQueryPool.size() - DESIRED_POOL_SIZE; 142b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar final Iterator<Integer> iterator = sQueryPool.descendingKeySet().iterator(); 143b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar while (toBeRemoved-- > 0) { 144b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar iterator.next(); 145b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar iterator.remove(); 146b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 147b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 148b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 149b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 150b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @Override 151b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar public String getSql() { 152b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar return mQuery; 153b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 154b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 1559fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik public int getArgCount() { 1569fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik return mArgCount; 1579fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik } 1589fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik 159b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @Override 160b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar public void bindTo(SupportSQLiteProgram program) { 161b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar for (int index = 1; index <= mArgCount; index++) { 162b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar switch (mBindingTypes[index]) { 163b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar case NULL: 164b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar program.bindNull(index); 165b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar break; 166b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar case LONG: 167b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar program.bindLong(index, mLongBindings[index]); 168b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar break; 169b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar case DOUBLE: 170b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar program.bindDouble(index, mDoubleBindings[index]); 171b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar break; 172b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar case STRING: 173b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar program.bindString(index, mStringBindings[index]); 174b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar break; 175b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar case BLOB: 176b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar program.bindBlob(index, mBlobBindings[index]); 177b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar break; 178b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 179b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 180b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 181b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 182b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @Override 183b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar public void bindNull(int index) { 184b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mBindingTypes[index] = NULL; 185b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 186b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 187b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @Override 188b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar public void bindLong(int index, long value) { 189b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mBindingTypes[index] = LONG; 190b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mLongBindings[index] = value; 191b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 192b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 193b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @Override 194b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar public void bindDouble(int index, double value) { 195b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mBindingTypes[index] = DOUBLE; 196b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mDoubleBindings[index] = value; 197b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 198b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 199b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @Override 200b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar public void bindString(int index, String value) { 201b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mBindingTypes[index] = STRING; 202b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mStringBindings[index] = value; 203b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 204b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 205b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @Override 206b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar public void bindBlob(int index, byte[] value) { 207b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mBindingTypes[index] = BLOB; 208b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mBlobBindings[index] = value; 209b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 210b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 2110d1b036f6868844705cd3b57e96d373edd09b3d5Yigit Boyar @Override 2120d1b036f6868844705cd3b57e96d373edd09b3d5Yigit Boyar public void close() throws Exception { 2130d1b036f6868844705cd3b57e96d373edd09b3d5Yigit Boyar // no-op. not calling release because it is internal API. 2140d1b036f6868844705cd3b57e96d373edd09b3d5Yigit Boyar } 2150d1b036f6868844705cd3b57e96d373edd09b3d5Yigit Boyar 2169fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik /** 2179fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik * Copies arguments from another RoomSQLiteQuery into this query. 2189fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik * 2199fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik * @param other The other query, which holds the arguments to be copied. 2209fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik */ 2219fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik public void copyArgumentsFrom(RoomSQLiteQuery other) { 2229fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik int argCount = other.getArgCount() + 1; // +1 for the binding offsets 2239fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik System.arraycopy(other.mBindingTypes, 0, mBindingTypes, 0, argCount); 2249fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik System.arraycopy(other.mLongBindings, 0, mLongBindings, 0, argCount); 2259fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik System.arraycopy(other.mStringBindings, 0, mStringBindings, 0, argCount); 2269fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik System.arraycopy(other.mBlobBindings, 0, mBlobBindings, 0, argCount); 2279fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik System.arraycopy(other.mDoubleBindings, 0, mDoubleBindings, 0, argCount); 2289fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik } 2299fd8e6171bbdc37f5516fe15b2d96f4ae926ef1aChris Craik 230b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @Override 231b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar public void clearBindings() { 232b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar Arrays.fill(mBindingTypes, NULL); 233b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar Arrays.fill(mStringBindings, null); 234b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar Arrays.fill(mBlobBindings, null); 235b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar mQuery = null; 236b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar // no need to clear others 237b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 238b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 239b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar private static final int NULL = 1; 240b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar private static final int LONG = 2; 241b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar private static final int DOUBLE = 3; 242b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar private static final int STRING = 4; 243b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar private static final int BLOB = 5; 244b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar 2459691051d4acf7de89396388ca195f0c569257804Yigit Boyar @Retention(RetentionPolicy.SOURCE) 246b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @IntDef({NULL, LONG, DOUBLE, STRING, BLOB}) 247b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar @interface Binding { 248b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar } 249b030dcb5b7a62854c0bfe85bf04eaf60caeb83bbYigit Boyar} 250