# Room and SQLite | Sentry for Android

Supported in Sentry's Android SDK version `4.0.0` and above.

Supported in Sentry Android Gradle Plugin version `3.0.0` and above.

Custom instrumentation is supported in Sentry's Android SDK, version `6.21.0` and above.

## [Auto-Installation With the Sentry Android Gradle Plugin](https://docs.sentry.io/platforms/android/integrations/room-and-sqlite.md#auto-installation-with-the-sentry-android-gradle-plugin)

The [Sentry Android Gradle Plugin](https://docs.sentry.io/platforms/android/configuration/gradle.md) provides Room and AndroidX SQLite support through bytecode manipulation. The source can be found [on GitHub](https://github.com/getsentry/sentry-android-gradle-plugin/tree/main/plugin-build/src/main/kotlin/io/sentry/android/gradle/instrumentation).

On this page, we get you up and running with Sentry's Room and SQLite Integration, so that it will automatically start a span from an active transaction that's bound to the scope of each sqlite/dao query.

### [Install](https://docs.sentry.io/platforms/android/integrations/room-and-sqlite.md#install)

To use the Room and AndroidX SQLite integration, add the Sentry Android Gradle plugin and the Sentry Android SDK (version `4.0.0` or above) in `build.gradle`:

```groovy
plugins {
  id "io.sentry.android.gradle" version "5.8.0"
}

dependencies {
  implementation 'io.sentry:sentry-android:8.16.0'
}
```

Make sure, that [tracing](https://docs.sentry.io/platforms/android/tracing.md#configure-the-sample-rate) is enabled.

### [Configure](https://docs.sentry.io/platforms/android/integrations/room-and-sqlite.md#configure)

In general, no further configuration is required as the auto-instrumentation is enabled by default. If you would like to disable the database instrumentation feature, we expose a configuration option for that:

```groovy
import io.sentry.android.gradle.extensions.InstrumentationFeature

sentry {
  tracingInstrumentation {
    enabled = true
    features = EnumSet.allOf(InstrumentationFeature) - InstrumentationFeature.DATABASE
  }
}
```

## [Manual Installation](https://docs.sentry.io/platforms/android/integrations/room-and-sqlite.md#manual-installation)

Supported in Sentry's Android SDK, version `6.21.0` and above.

### [Install](https://docs.sentry.io/platforms/android/integrations/room-and-sqlite.md#install-1)

Sentry captures data by wrapping a `SupportSQLiteOpenHelper.Factory`. To add the SQLite integration, initialize the [Android SDK](https://docs.sentry.io/platforms/android.md), then add the `sentry-android-sqlite` dependency using Gradle:

```groovy
implementation 'io.sentry:sentry-android:8.16.0'
implementation 'io.sentry:sentry-android-sqlite:8.16.0'
```

### [Configure](https://docs.sentry.io/platforms/android/integrations/room-and-sqlite.md#configure-1)

No configuration is required. Just wrap your `SupportSQLiteOpenHelper` instance in `SentrySupportSQLiteOpenHelper`.

```kotlin
import io.sentry.android.sqlite.SentrySupportSQLiteOpenHelper

private val myOpenHelper = MyOpenHelper()
private val instrumentedOpenHelper = SentrySupportSQLiteOpenHelper.create(myOpenHelper)
```

Room is supported when using the default `FrameworkSQLiteOpenHelperFactory` provided by the `androidx.sqlite` package, but any custom `SupportSQLiteOpenHelper` can be used.

```kotlin
import androidx.room.Room
import io.sentry.android.sqlite.SentrySupportSQLiteOpenHelper

val database = Room.databaseBuilder(context, MyDatabase::class.java, "dbName")
    .openHelperFactory { configuration ->
        SentrySupportSQLiteOpenHelper.create(FrameworkSQLiteOpenHelperFactory().create(configuration))
    }
    .build()
```

## [Verify](https://docs.sentry.io/platforms/android/integrations/room-and-sqlite.md#verify)

Assuming you have the following (reduced) code snippet performing a database query on a Room Dao:

```kotlin
import android.os.Bundle
import android.widget.Button
import androidx.activity.ComponentActivity
import androidx.room.Database
import androidx.room.Dao
import androidx.room.Insert
import androidx.room.OnConflictStrategy
import androidx.room.RoomDatabase
import io.sentry.Sentry
import io.sentry.SpanStatus
import kotlinx.coroutines.withContext

@Dao
abstract class TracksDao {
  @Insert(onConflict = OnConflictStrategy.REPLACE)
  abstract suspend fun insert(track: Track): Long
}

@Database(
  entities = [Track::class],
  version = 1,
  exportSchema = false
)
abstract class TracksDatabase : RoomDatabase() {
    abstract fun tracksDao(): TracksDao
}

class EditActivity : ComponentActivity() {
  private lateinit var database: TracksDatabase

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    database = TODO("initialize database...")

    findViewById<Button>(R.id.editTrack).setOnClickListener {
      val transaction = Sentry.startTransaction(
        name = "Track Interaction",
        operation = "ui.action.edit",
        bindToScope = true
      )

      val newTrack = Track(/* fill in track values */)

      withContext(Dispatchers.IO) {
        database.tracksDao().insert(newTrack)
        transaction.finish(SpanStatus.OK)
      }
    }
  }
}
```

To view the recorded transaction, log into [sentry.io](https://sentry.io) and open your project. Clicking on **Performance** will open a page with transactions, where you can select the just recorded transaction with the name `Track Interaction`. The event will look similar to this:

[![Room and AndroidX SQLite performance instrumentation](https://docs.sentry.io/_next/image/?url=%2Fmdx-images%2Froom-sqlite-instrumentation-O5GJ3MZP.png%231336x852\&w=3840\&q=75)](https://docs.sentry.io/mdx-images/room-sqlite-instrumentation-O5GJ3MZP.png)

The Sentry Android Gradle plugin will report SQL queries for any `SupportSQLiteOpenHelper.Factory`, starting with version `3.11.0`.

Earlier versions will only support standard `androidx.room` usage and won't report SQL queries for any `SupportSQLiteOpenHelper.Factory` other than [androidx.sqlite](https://github.com/androidx/androidx/tree/androidx-main/sqlite).

If you're having trouble with this SDK, we want to hear about it. Create an [issue on GitHub](https://github.com/getsentry/sentry-android-gradle-plugin/issues) and describe your experience.

If you are directly using [SupportSQLiteDatabase#query](https://developer.android.com/reference/androidx/sqlite/db/SupportSQLiteDatabase#query\(java.lang.String\)) or [SupportSQLiteDatabase#execSQL](https://developer.android.com/reference/androidx/sqlite/db/SupportSQLiteDatabase#execSQL\(java.lang.String\)) methods through the Room's SQLiteOpenHelper, consider switching to their alternatives that accept `bindArgs` as a second parameter.

Because Sentry captures SQL queries as Span description, there is a risk of leaking sensitive data when not using an SQL string with placeholders.
