Skip to content

Instantly share code, notes, and snippets.

@aasaandinesh
Created December 9, 2018 15:11
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aasaandinesh/6e4cf206bd1bb56966954cabc42128dd to your computer and use it in GitHub Desktop.
Save aasaandinesh/6e4cf206bd1bb56966954cabc42128dd to your computer and use it in GitHub Desktop.
Helper to generate logs for Room Database library
import android.annotation.SuppressLint
import androidx.room.RoomSQLiteQuery
private const val NULL = 1
private const val LONG = 2
private const val DOUBLE = 3
private const val STRING = 4
private const val BLOB = 5
private const val NULL_QUERY = "NULL"
const val ROOM_LOGGING_TAG = "roomQueryLog"
object RoomLoggingHelper {
@SuppressLint("RestrictedApi")
fun getStringSql(query: RoomSQLiteQuery): String {
val argList = arrayListOf<String>()
val bindingTypes = query.getBindingTypes()
var i = 0
while (i < bindingTypes.size) {
val bindingType = bindingTypes[i]
when (bindingType) {
NULL -> argList.add(NULL_QUERY)
LONG -> argList.add(query.getLongBindings()[i].toString())
DOUBLE -> argList.add(query.getDoubleBindings()[i].toString())
STRING -> argList.add(query.getStringBindings()[i].toString())
}
i++
}
return String.format(query.sql.replace("?", "%s"), *argList.toArray())
}
fun getStringSql(query: String?, args: Array<out Any>?): String? {
return if (query != null && args != null) {
String.format(query.replace("?", "%s"), *args)
} else
""
}
}
private fun RoomSQLiteQuery.getBindingTypes(): IntArray {
return javaClass.getDeclaredField("mBindingTypes").let { field ->
field.isAccessible = true
return@let field.get(this) as IntArray
}
}
private fun RoomSQLiteQuery.getLongBindings(): LongArray {
return javaClass.getDeclaredField("mLongBindings").let { field ->
field.isAccessible = true
return@let field.get(this) as LongArray
}
}
private fun RoomSQLiteQuery.getStringBindings(): Array<String> {
return javaClass.getDeclaredField("mStringBindings").let { field ->
field.isAccessible = true
return@let field.get(this) as Array<String>
}
}
private fun RoomSQLiteQuery.getDoubleBindings(): DoubleArray {
return javaClass.getDeclaredField("mDoubleBindings").let { field ->
field.isAccessible = true
return@let field.get(this) as DoubleArray
}
}
private fun RoomSQLiteQuery.getIntBindings(): IntArray {
return javaClass.getDeclaredField("mBindingTypes").let { field ->
field.isAccessible = true
return@let field.get(this) as IntArray
}
}
@aasaandinesh
Copy link
Author

aasaandinesh commented Dec 9, 2018

Add this file to your Project and call it from your Room Database class as follows. This only work for SELECT queries. Wont work for insert/update/delete

override fun query(query: SupportSQLiteQuery?): Cursor and query(query: String?, args: Array<out Any>?): Cursor

These methods are called whenever a query is being executed. Inside these methods, call getStringSql(query: RoomSQLiteQuery): String and getStringSql(query: String?, args: Array<out Any>?): String? methods to get the actual query in string.

for example:

override fun query(query: SupportSQLiteQuery?): Cursor {
        //This will give you the SQL String
        val queryString = RoomLoggingHelper.getStringSql(query as RoomSQLiteQuery)
        //You can log it in a way you like, I am using Timber
        Timber.d("$ROOM_LOGGING_TAG $queryString")
        return super.query(query)
    }

    override fun query(query: String?, args: Array<out Any>?): Cursor {
        //This will give you the SQL String
        val queryString = RoomLoggingHelper.getStringSql(query, args)
        //You can log it in a way you like, I am using Timber
        Timber.d("$ROOM_LOGGING_TAG $queryString")
        return super.query(query, args)
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment