1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package androidx.sqlite.db
17 
18 /**
19  * A basic implementation of [SupportSQLiteQuery] which receives a query and its args and binds args
20  * based on the passed in Object type.
21  *
22  * @param query The query string, can include bind arguments (.e.g ?).
23  * @param bindArgs The bind argument value that will replace the placeholders in the query.
24  * @constructor Creates an SQL query with the sql string and the bind arguments.
25  */
26 public class SimpleSQLiteQuery(
27     private val query: String,
28     @Suppress("ArrayReturn") // Due to legacy API
29     private val bindArgs: Array<out Any?>?
30 ) : SupportSQLiteQuery {
31 
32     /**
33      * Creates an SQL query without any bind arguments.
34      *
35      * @param query The SQL query to execute. Cannot include bind parameters.
36      */
37     public constructor(query: String) : this(query, null)
38 
39     override val sql: String
40         get() = this.query
41 
42     /**
43      * Creates an SQL query without any bind arguments.
44      *
45      * @param [statement] The SQL query to execute. Cannot include bind parameters.
46      */
bindTonull47     override fun bindTo(statement: SupportSQLiteProgram) {
48         bind(statement, bindArgs)
49     }
50 
51     override val argCount: Int
52         get() = bindArgs?.size ?: 0
53 
54     public companion object {
55         /**
56          * Binds the given arguments into the given sqlite statement.
57          *
58          * @param [statement] The sqlite statement
59          * @param [bindArgs] The list of bind arguments
60          */
61         @JvmStatic
bindnull62         public fun bind(
63             statement: SupportSQLiteProgram,
64             @Suppress("ArrayReturn") // Due to legacy API
65             bindArgs: Array<out Any?>?
66         ) {
67             if (bindArgs == null) {
68                 return
69             }
70 
71             val limit = bindArgs.size
72             for (i in 0 until limit) {
73                 val arg = bindArgs[i]
74                 bind(statement, i + 1, arg)
75             }
76         }
77 
bindnull78         private fun bind(statement: SupportSQLiteProgram, index: Int, arg: Any?) {
79             // extracted from android.database.sqlite.SQLiteConnection
80             if (arg == null) {
81                 statement.bindNull(index)
82             } else if (arg is ByteArray) {
83                 statement.bindBlob(index, arg)
84             } else if (arg is Float) {
85                 statement.bindDouble(index, arg.toDouble())
86             } else if (arg is Double) {
87                 statement.bindDouble(index, arg)
88             } else if (arg is Long) {
89                 statement.bindLong(index, arg)
90             } else if (arg is Int) {
91                 statement.bindLong(index, arg.toLong())
92             } else if (arg is Short) {
93                 statement.bindLong(index, arg.toLong())
94             } else if (arg is Byte) {
95                 statement.bindLong(index, arg.toLong())
96             } else if (arg is String) {
97                 statement.bindString(index, arg)
98             } else if (arg is Boolean) {
99                 statement.bindLong(index, if (arg) 1 else 0)
100             } else {
101                 throw IllegalArgumentException(
102                     "Cannot bind $arg at index $index Supported types: Null, ByteArray, " +
103                         "Float, Double, Long, Int, Short, Byte, String"
104                 )
105             }
106         }
107     }
108 }
109