RoomSQLiteQuery.java revision bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8
1edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project/*
2edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Copyright (C) 2017 The Android Open Source Project
3edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
4edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * you may not use this file except in compliance with the License.
6edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * You may obtain a copy of the License at
7edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
8edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project *
10edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * See the License for the specific language governing permissions and
14edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * limitations under the License.
15edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project */
16edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
17edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpackage androidx.room;
18edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
19edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport androidx.annotation.IntDef;
20edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport androidx.annotation.RestrictTo;
21edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport androidx.annotation.VisibleForTesting;
22edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport androidx.sqlite.db.SupportSQLiteProgram;
23c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopianimport androidx.sqlite.db.SupportSQLiteQuery;
24c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopian
25c5b2c0bf8007562536b822eb060fc54a01f8e08bMathias Agopianimport java.lang.annotation.Retention;
26edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectimport java.lang.annotation.RetentionPolicy;
27d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopianimport java.util.Arrays;
282adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFaddenimport java.util.Iterator;
292b5dd4062dd951b2cafc4b80bd3a1813b013d71aMathias Agopianimport java.util.Map;
302b5dd4062dd951b2cafc4b80bd3a1813b013d71aMathias Agopianimport java.util.TreeMap;
31a099a24c93bfa599fc5c36a647e946c26f68514fKalle Raita
324cdc58f6840d15b4952149d2b345ec1f97d505bcRobert Carr/**
33edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project * This class is used as an intermediate place to keep binding arguments so that we can run
3428f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright * Cursor queries with correct types rather than passing everything as a string.
3528f24d0ab481bd9c6fd5618414fee694e837c5c6Michael Wright * <p>
3690ac799241f077a7b7e6c1875fd933864c8dd2a7Mathias Agopian * Because it is relatively a big object, they are pooled and must be released after each use.
3767d8bd66aaf04805cb8f2616ba964141b865e3b9Lajos Molnar *
38c4f471e75a8ec64ec34e3f2944a5a756215d0becDan Stoza * @hide
39582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis */
40134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis@SuppressWarnings("unused")
419cce325fae8adcf7560a28eef394489f09bad74dMathias Agopian@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
42edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Projectpublic class RoomSQLiteQuery implements SupportSQLiteQuery, SupportSQLiteProgram {
43edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @SuppressWarnings("WeakerAccess")
44edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @VisibleForTesting
45edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // Maximum number of queries we'll keep cached.
46edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static final int POOL_LIMIT = 15;
47edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @SuppressWarnings("WeakerAccess")
48edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @VisibleForTesting
49e2347b7953f70232541bdc1b392230d6231aaeb9Chih-Hung Hsieh    // Once we hit POOL_LIMIT, we'll bring the pool size back to the desired number. We always
50edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    // clear the bigger queries (# of arguments).
51edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static final int DESIRED_POOL_SIZE = 10;
52edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    private volatile String mQuery;
53edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @SuppressWarnings("WeakerAccess")
54d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza    @VisibleForTesting
55d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza    final long[] mLongBindings;
567e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian    @SuppressWarnings("WeakerAccess")
57edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @VisibleForTesting
58edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    final double[] mDoubleBindings;
59edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @SuppressWarnings("WeakerAccess")
60edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @VisibleForTesting
617e27f05739c8a2655cf0f7faea35614ce0a50278Mathias Agopian    final String[] mStringBindings;
62edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @SuppressWarnings("WeakerAccess")
63edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @VisibleForTesting
641db73f66624e7d151710483dd58e03eed672f064Robert Carr    final byte[][] mBlobBindings;
651db73f66624e7d151710483dd58e03eed672f064Robert Carr
661db73f66624e7d151710483dd58e03eed672f064Robert Carr    @Binding
671db73f66624e7d151710483dd58e03eed672f064Robert Carr    private final int[] mBindingTypes;
681db73f66624e7d151710483dd58e03eed672f064Robert Carr    @SuppressWarnings("WeakerAccess")
691db73f66624e7d151710483dd58e03eed672f064Robert Carr    @VisibleForTesting
701db73f66624e7d151710483dd58e03eed672f064Robert Carr    final int mCapacity;
711db73f66624e7d151710483dd58e03eed672f064Robert Carr    // number of arguments in the query
721db73f66624e7d151710483dd58e03eed672f064Robert Carr    @SuppressWarnings("WeakerAccess")
731db73f66624e7d151710483dd58e03eed672f064Robert Carr    @VisibleForTesting
748b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    int mArgCount;
758b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian
768b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian
778b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian    @SuppressWarnings("WeakerAccess")
78edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    @VisibleForTesting
79edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project    static final TreeMap<Integer, RoomSQLiteQuery> sQueryPool = new TreeMap<>();
80edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
81d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza    /**
82d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza     * Copies the given SupportSQLiteQuery and converts it into RoomSQLiteQuery.
83d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza     *
84d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza     * @param supportSQLiteQuery The query to copy from
858b33f032327f8de0dcc0e6d0d43ed80f834b51f6Mathias Agopian     * @return A new query copied from the provided one.
86d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza     */
87d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza    public static RoomSQLiteQuery copyFrom(SupportSQLiteQuery supportSQLiteQuery) {
88d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza        final RoomSQLiteQuery query = RoomSQLiteQuery.acquire(
89d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza                supportSQLiteQuery.getSql(),
90698c0873cf2e07bdc7fd1e72169aee2a19fa40d7Mathias Agopian                supportSQLiteQuery.getArgCount());
91d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza        supportSQLiteQuery.bindTo(new SupportSQLiteProgram() {
92d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza            @Override
93b8d69a55f1c187a35ac41e69de63251f5501b6f4Jamie Gennis            public void bindNull(int index) {
94edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                query.bindNull(index);
95edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
96edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
97edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            @Override
98edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            public void bindLong(int index, long value) {
99edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project                query.bindLong(index, value);
100edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            }
101edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project
102edbf3b6af777b721cd2a1ef461947e51e88241e1The Android Open Source Project            @Override
10340482ff650751819d4104c10a30974838168438cChavi Weingarten            public void bindDouble(int index, double value) {
10440482ff650751819d4104c10a30974838168438cChavi Weingarten                query.bindDouble(index, value);
10540482ff650751819d4104c10a30974838168438cChavi Weingarten            }
10640482ff650751819d4104c10a30974838168438cChavi Weingarten
1072a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            @Override
1082a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian            public void bindString(int index, String value) {
1092a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian                query.bindString(index, value);
110c18790018be5d7ea7061ccbc81f3044e74adc823Dan Stoza            }
111d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza
112d723bd7669b4fc88dc282d8bf8ba5ecb2849d22fDan Stoza            @Override
113ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr            public void bindBlob(int index, byte[] value) {
114ae0608381b2b4699218febd6d45ad9d307544d55Robert Carr                query.bindBlob(index, value);
115c701401f8cec2e5309f8b57e2b97baced5093274Dan Stoza            }
116c3ebe66b49cfba035e1fd0e160a13db38eb81b0eRiley Andrews
11740482ff650751819d4104c10a30974838168438cChavi Weingarten            @Override
11840482ff650751819d4104c10a30974838168438cChavi Weingarten            public void clearBindings() {
11940482ff650751819d4104c10a30974838168438cChavi Weingarten                query.clearBindings();
12040482ff650751819d4104c10a30974838168438cChavi Weingarten            }
12140482ff650751819d4104c10a30974838168438cChavi Weingarten
12240482ff650751819d4104c10a30974838168438cChavi Weingarten            @Override
12340482ff650751819d4104c10a30974838168438cChavi Weingarten            public void close() {
12440482ff650751819d4104c10a30974838168438cChavi Weingarten                // ignored.
12540482ff650751819d4104c10a30974838168438cChavi Weingarten            }
12640482ff650751819d4104c10a30974838168438cChavi Weingarten        });
12740482ff650751819d4104c10a30974838168438cChavi Weingarten        return query;
12840482ff650751819d4104c10a30974838168438cChavi Weingarten    }
12940482ff650751819d4104c10a30974838168438cChavi Weingarten
13040482ff650751819d4104c10a30974838168438cChavi Weingarten    /**
1312a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian     * Returns a new RoomSQLiteQuery that can accept the given number of arguments and holds the
1322a9fc493dfdba67108e4335bb1fe931bc1e2a025Mathias Agopian     * given query.
133a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw     *
13440482ff650751819d4104c10a30974838168438cChavi Weingarten     * @param query         The query to prepare
135578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr     * @param argumentCount The number of query arguments
136a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw     * @return A RoomSQLiteQuery that holds the given query and has space for the given number of
137a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw     * arguments.
138a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw     */
1397206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw    @SuppressWarnings("WeakerAccess")
1407206d49b2963ce2e926a5f25fe94aca9c06471e6chaviw    public static RoomSQLiteQuery acquire(String query, int argumentCount) {
141578038fc49f83c4c8c4accdce49df404ecd6ad02Robert Carr        synchronized (sQueryPool) {
14240482ff650751819d4104c10a30974838168438cChavi Weingarten            final Map.Entry<Integer, RoomSQLiteQuery> entry =
14340482ff650751819d4104c10a30974838168438cChavi Weingarten                    sQueryPool.ceilingEntry(argumentCount);
14440482ff650751819d4104c10a30974838168438cChavi Weingarten            if (entry != null) {
14540482ff650751819d4104c10a30974838168438cChavi Weingarten                sQueryPool.remove(entry.getKey());
14640482ff650751819d4104c10a30974838168438cChavi Weingarten                final RoomSQLiteQuery sqliteQuery = entry.getValue();
14740482ff650751819d4104c10a30974838168438cChavi Weingarten                sqliteQuery.init(query, argumentCount);
14840482ff650751819d4104c10a30974838168438cChavi Weingarten                return sqliteQuery;
14940482ff650751819d4104c10a30974838168438cChavi Weingarten            }
15040482ff650751819d4104c10a30974838168438cChavi Weingarten        }
15140482ff650751819d4104c10a30974838168438cChavi Weingarten        RoomSQLiteQuery sqLiteQuery = new RoomSQLiteQuery(argumentCount);
15240482ff650751819d4104c10a30974838168438cChavi Weingarten        sqLiteQuery.init(query, argumentCount);
15340482ff650751819d4104c10a30974838168438cChavi Weingarten        return sqLiteQuery;
15440482ff650751819d4104c10a30974838168438cChavi Weingarten    }
15540482ff650751819d4104c10a30974838168438cChavi Weingarten
15640482ff650751819d4104c10a30974838168438cChavi Weingarten    private RoomSQLiteQuery(int capacity) {
157a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw        mCapacity = capacity;
158a76b271f0e14325fa0ebb98e1cac0a15adfea1cbchaviw        // because, 1 based indices... we don't want to offsets everything with 1 all the time.
159582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis        int limit = capacity + 1;
1602adaf04fab35cf47c824d74d901b54094e01ccd3Andy McFadden        //noinspection WrongConstant
161134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        mBindingTypes = new int[limit];
162134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        mLongBindings = new long[limit];
163134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        mDoubleBindings = new double[limit];
164134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        mStringBindings = new String[limit];
165134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        mBlobBindings = new byte[limit][];
166134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
167e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block
168134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    @SuppressWarnings("WeakerAccess")
169134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    void init(String query, int argCount) {
170134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        mQuery = query;
1712ea926bda2fa30f3ba8d0ed2d2395a8ada952e6eMarco Nelissen        mArgCount = argCount;
172134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
173e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block
174582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    /**
175134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis     * Releases the query back to the pool.
176134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis     * <p>
177134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis     * After released, the statement might be returned when {@link #acquire(String, int)} is called
178134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis     * so you should never re-use it after releasing.
179134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis     */
180e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block    @SuppressWarnings("WeakerAccess")
181582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    public void release() {
182134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        synchronized (sQueryPool) {
183134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis            sQueryPool.put(mCapacity, this);
184134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis            prunePoolLocked();
185134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        }
186134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis    }
187e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block
188582270d69db94286a248bd829f1ae6f910d45124Jamie Gennis    private static void prunePoolLocked() {
189134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis        if (sQueryPool.size() > POOL_LIMIT) {
190134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis            int toBeRemoved = sQueryPool.size() - DESIRED_POOL_SIZE;
191134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis            final Iterator<Integer> iterator = sQueryPool.descendingKeySet().iterator();
192134f0422866e8985188ed10dfbdcb8e6c34b87f7Jamie Gennis            while (toBeRemoved-- > 0) {
193d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian                iterator.next();
1946b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                iterator.remove();
1956b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            }
1966b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        }
1976b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    }
1986b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson
1996b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    @Override
2006b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    public String getSql() {
2016b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        return mQuery;
2026b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    }
2036b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson
2046b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    @Override
2056b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    public int getArgCount() {
2066b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        return mArgCount;
2076b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    }
2086b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson
2096b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    @Override
2106b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    public void bindTo(SupportSQLiteProgram program) {
2116b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        for (int index = 1; index <= mArgCount; index++) {
2126b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            switch (mBindingTypes[index]) {
2136b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                case NULL:
2146b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    program.bindNull(index);
2156b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    break;
2166b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                case LONG:
2176b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    program.bindLong(index, mLongBindings[index]);
2186b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    break;
2196b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                case DOUBLE:
2206b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    program.bindDouble(index, mDoubleBindings[index]);
2216b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    break;
2226b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                case STRING:
2236b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    program.bindString(index, mStringBindings[index]);
2246b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    break;
2256b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                case BLOB:
2266b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    program.bindBlob(index, mBlobBindings[index]);
2276b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson                    break;
2286b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson            }
2296b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        }
2306b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    }
2316b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson
2326b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    @Override
2336b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    public void bindNull(int index) {
2346b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson        mBindingTypes[index] = NULL;
2356b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    }
2366b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson
2376b376713907086c9642e7b7e66e51ddfa531b003Brian Anderson    @Override
238b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi    public void bindLong(int index, long value) {
239d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        mBindingTypes[index] = LONG;
240d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        mLongBindings[index] = value;
241d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    }
242d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
243d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    @Override
244d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    public void bindDouble(int index, double value) {
245d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        mBindingTypes[index] = DOUBLE;
246d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        mDoubleBindings[index] = value;
247b1e2f8deb38353e4bcc9d3ef06bc15bd5e417425Jorim Jaggi    }
248d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
249d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    @Override
250d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    public void bindString(int index, String value) {
251d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        mBindingTypes[index] = STRING;
252e6f43ddce78d6846af12550ff9193c5c6fe5844bSteve Block        mStringBindings[index] = value;
253d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    }
254d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian
255d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    @Override
256d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian    public void bindBlob(int index, byte[] value) {
257d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        mBindingTypes[index] = BLOB;
258d0566bc26fcf6ca396118701fa11900b627f2c09Mathias Agopian        mBlobBindings[index] = value;
2598e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    }
260dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
261e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    @Override
262e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    public void close() {
263e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        // no-op. not calling release because it is internal API.
2648dfa92fef9759a881e96ee58d59875d35023aab9Andy McFadden    }
265dd3cb84cfbe8068790c6233b5829fae9c4a0ee93Jamie Gennis
266e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    /**
267e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     * Copies arguments from another RoomSQLiteQuery into this query.
268e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     *
269e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian     * @param other The other query, which holds the arguments to be copied.
2706c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall     */
2716c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall    public void copyArgumentsFrom(RoomSQLiteQuery other) {
2726c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        int argCount = other.getArgCount() + 1; // +1 for the binding offsets
2736c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        System.arraycopy(other.mBindingTypes, 0, mBindingTypes, 0, argCount);
2746c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        System.arraycopy(other.mLongBindings, 0, mLongBindings, 0, argCount);
2756c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        System.arraycopy(other.mStringBindings, 0, mStringBindings, 0, argCount);
2766c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        System.arraycopy(other.mBlobBindings, 0, mBlobBindings, 0, argCount);
2776c913be9ca95fd6b556d056e165a4ba6dc69795bJesse Hall        System.arraycopy(other.mDoubleBindings, 0, mDoubleBindings, 0, argCount);
278e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    }
279e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian
280e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    @Override
281e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian    public void clearBindings() {
282e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        Arrays.fill(mBindingTypes, NULL);
283e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        Arrays.fill(mStringBindings, null);
284e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        Arrays.fill(mBlobBindings, null);
285e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        mQuery = null;
286e57f292595bec48f65c8088b00ff6beea01217e9Mathias Agopian        // no need to clear others
2872c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    }
2888e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross
2898e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    private static final int NULL = 1;
2908e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross    private static final int LONG = 2;
291c01a79d77b829e7de86ef137694e8ad708470ca1Andy McFadden    private static final int DOUBLE = 3;
2922c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    private static final int STRING = 4;
2932c9b11f0291210c9b9513a1a0cce6afebd361b3bPrashant Malani    private static final int BLOB = 5;
2948e533069e5721e55cb9768e140e16546c3a4a8b6Colin Cross
2953094df359d1e6e2ae8ca4e935cc093f563804c96Mathias Agopian    @Retention(RetentionPolicy.SOURCE)
2967f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    @IntDef({NULL, LONG, DOUBLE, STRING, BLOB})
2977f7da32569f8e0b3d383a40b95f8ac1d55afd801Dan Stoza    @interface Binding {
298c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian    }
299c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian}
300c666cae2d5995097ec49a87e375e2afdd92802b7Mathias Agopian