1616
1717package com.ctrip.sqllin.driver
1818
19+ import android.database.sqlite.SQLiteCursor
1920import android.database.sqlite.SQLiteDatabase
21+ import android.database.sqlite.SQLiteQuery
2022
2123/* *
2224 * Android implementation of [DatabaseConnection] using Android's SQLiteDatabase.
@@ -35,7 +37,52 @@ internal class AndroidDatabaseConnection(private val database: SQLiteDatabase) :
3537
3638 override fun executeUpdateDelete (sql : String , bindParams : Array <out Any ?>? ) = execSQL(sql, bindParams)
3739
38- override fun query (sql : String , bindParams : Array <out String ?>? ): CommonCursor = AndroidCursor (database.rawQuery(sql, bindParams))
40+ override fun query (sql : String , bindParams : Array <out Any ?>? ): CommonCursor {
41+ val cursor = if (bindParams == null ) {
42+ database.rawQuery(sql, null )
43+ } else {
44+ // Use rawQueryWithFactory to bind parameters with proper types
45+ // This allows us to bind parameters with their actual types (Int, Long, Double, etc.)
46+ // instead of converting everything to String like rawQuery does
47+ val cursorFactory = SQLiteDatabase .CursorFactory { _, masterQuery, editTable, query ->
48+ bindTypedParameters(query, bindParams)
49+ SQLiteCursor (masterQuery, editTable, query)
50+ }
51+ // Pass emptyArray() for selectionArgs since we bind parameters via the factory
52+ // Use empty string for editTable since it's only needed for updateable cursors
53+ database.rawQueryWithFactory(cursorFactory, sql, null , " " )
54+ }
55+ return AndroidCursor (cursor)
56+ }
57+
58+ /* *
59+ * Binds parameters to SQLiteQuery with proper type handling.
60+ *
61+ * Unlike rawQuery which only accepts String[], this method binds parameters
62+ * with their actual types (Long, Double, ByteArray, etc.) to ensure correct
63+ * SQLite type affinity and comparisons.
64+ */
65+ private fun bindTypedParameters (query : SQLiteQuery , bindParams : Array <out Any ?>) {
66+ bindParams.forEachIndexed { index, param ->
67+ val position = index + 1 // SQLite bind positions are 1-based
68+ when (param) {
69+ null -> query.bindNull(position)
70+ is ByteArray -> query.bindBlob(position, param)
71+ is Double -> query.bindDouble(position, param)
72+ is Float -> query.bindDouble(position, param.toDouble())
73+ is Long -> query.bindLong(position, param)
74+ is Int -> query.bindLong(position, param.toLong())
75+ is Short -> query.bindLong(position, param.toLong())
76+ is Byte -> query.bindLong(position, param.toLong())
77+ is Boolean -> query.bindLong(position, if (param) 1L else 0L )
78+ is ULong -> query.bindLong(position, param.toLong())
79+ is UInt -> query.bindLong(position, param.toLong())
80+ is UShort -> query.bindLong(position, param.toLong())
81+ is UByte -> query.bindLong(position, param.toLong())
82+ else -> query.bindString(position, param.toString())
83+ }
84+ }
85+ }
3986
4087 override fun beginTransaction () = database.beginTransaction()
4188 override fun endTransaction () = database.endTransaction()
0 commit comments