Skip to content

chore(android-sqlite): Add SQLite samples to sentry-samples-android#5504

Open
0xadam-brown wants to merge 2 commits into
feat/support-sqlite-driverfrom
feat/add-sqlite-to-android-sample-app
Open

chore(android-sqlite): Add SQLite samples to sentry-samples-android#5504
0xadam-brown wants to merge 2 commits into
feat/support-sqlite-driverfrom
feat/add-sqlite-to-android-sample-app

Conversation

@0xadam-brown
Copy link
Copy Markdown
Member

📜 Description

Adds our SQLite integrations to sentry-android-samples (SentrySQLiteDriver and SentrySupportOpenSQLiteHelper).

The entry point is SQLiteActivity. Example SQL statements are identical across integrations so we can observe similarities / differences in how they handle spans. Users can exercise the integrations directly or via Room or SQLDelight.

💡 Motivation and Context

Follow-on to #5466 so we can vet SentrySQLiteDriver in the wild. Backfills to cover SentrySupportOpenSQLiteHelper.

How do I use it?

./gradlew :sentry-samples:sentry-samples-android:installDebug

Then click "Tracing" > "Open SQLiteActivity"

Screenshots

SQLite sample Sentry UI sample

💚 How did you test it?

Manually.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.

🔮 Next steps

Adds our SQLite integrations to sentry-android-samples (`SentrySQLiteDriver` and `SentrySupportOpenSQLiteHelper`).

The entry point is `SQLiteActivity`. Example SQL statements are identical across integrations so we can observe similarities / differences in how they handle spans. Users can exercise the integrations directly or via Room or SQLDelight.
@sentry
Copy link
Copy Markdown

sentry Bot commented Jun 5, 2026

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.43.1 (1) release

⚙️ sentry-android Build Distribution Settings

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 5, 2026

Performance metrics 🚀

  Plain With Sentry Diff
Startup time 321.26 ms 361.84 ms 40.58 ms
Size 0 B 0 B 0 B

Baseline results on branch: feat/support-sqlite-driver

Startup times

Revision Plain With Sentry Diff
f8d2380 309.09 ms 365.52 ms 56.43 ms
2a55b58 365.41 ms 434.64 ms 69.23 ms
4993a1b 303.45 ms 392.65 ms 89.20 ms
9ed1dfc 310.92 ms 361.74 ms 50.82 ms
703e7ae 350.72 ms 415.76 ms 65.03 ms
8c92b97 310.02 ms 361.44 ms 51.42 ms

App size

Revision Plain With Sentry Diff
f8d2380 0 B 0 B 0 B
2a55b58 0 B 0 B 0 B
4993a1b 0 B 0 B 0 B
9ed1dfc 0 B 0 B 0 B
703e7ae 0 B 0 B 0 B
8c92b97 0 B 0 B 0 B

Previous results on branch: feat/add-sqlite-to-android-sample-app

Startup times

Revision Plain With Sentry Diff
f6e3213 291.28 ms 357.63 ms 66.35 ms

App size

Revision Plain With Sentry Diff
f6e3213 0 B 0 B 0 B

Comment thread gradle/libs.versions.toml
room2 = "2.8.4"
room3 = "3.0.0-alpha06"
sqlite = "2.6.2"
sqliteAlpha = "2.7.0-alpha06" # Required by Room3 3.0.0-alpha*
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've included deps that are only relevant to the sample app b/c that matched prior art. Chime in if you want me to break with that practice and move the new sample app deps to its build.gradle file.

@@ -0,0 +1,106 @@
package io.sentry.samples.android.sqlite
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From here on I've flagged what few items I think are of interest. Your time is probably better spent spinning up the sample app from a local branch and seeing whether you have any feedback.

applicationId = "io.sentry.samples.android"
minSdk = libs.versions.minSdk.get().toInt()
// androidx.sqlite 2.6+ require minSdk 23; the Sentry SDK still supports 21.
minSdk = 23
Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that Room 3 requires us to bump the Android sample app minSDK to 23 and JVM target to 11.

Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0b1a52e. Configure here.

)
val cleared = names.count { appContext.deleteDatabase(it) }
warmUp(appContext)
return cleared
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reset races live SQL work

Medium Severity

SampleDatabases.reset closes cached handles and deletes database files without blocking other SQL demos. Demo buttons and long-press UiLoadActivity launches still call SqlStatements.execute during reset, and a single dbOperationInFlight flag can clear while another demo or reset is still on Dispatchers.IO, so closeAll/deleteDatabase can run against open or freshly reopened connections.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0b1a52e. Configure here.

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

val id = SqlDemo.valueOf(intent.getStringExtra(EXTRA_DEMO_ID).orEmpty())
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The app crashes with an IllegalArgumentException if UiLoadActivity is restored without the EXTRA_DEMO_ID intent extra, as SqlDemo.valueOf("") is called.
Severity: HIGH

Suggested Fix

Wrap the SqlDemo.valueOf() call in a try-catch block to handle the IllegalArgumentException and provide a default value or gracefully finish the activity. Alternatively, use a safer method to find the enum value that returns null for invalid input instead of throwing an exception.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location:
sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/sqlite/UiLoadActivity.kt#L33

Potential issue: In `UiLoadActivity`, the code
`SqlDemo.valueOf(intent.getStringExtra(EXTRA_DEMO_ID).orEmpty())` is called within
`onCreate`. If the activity is restored by the Android system after process death, the
intent extra may be missing. In this scenario, `getStringExtra` returns `null`, which
`.orEmpty()` converts to an empty string `""`. The subsequent call to
`SqlDemo.valueOf("")` throws an `IllegalArgumentException`, causing the application to
crash.

Comment on lines +361 to +371
try {
latestResult =
withContext(Dispatchers.IO) {
runInTransaction(variant.transactionName, variant.op) {
SqlStatements.execute(applicationContext, variant.demo, heavyWork)
}
}
} finally {
dbOperationInFlight = false
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Rapidly tapping a demo button launches multiple coroutines, causing the dbOperationInFlight UI state flag to become incorrect when the first operation finishes.
Severity: LOW

Suggested Fix

Before launching a new coroutine in the onTap function, add a guard to check if dbOperationInFlight is already true. If it is, prevent a new operation from starting. This will ensure only one database operation runs at a time, keeping the UI state consistent.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.

Location:
sentry-samples/sentry-samples-android/src/main/java/io/sentry/samples/android/sqlite/SQLiteActivity.kt#L359-L371

Potential issue: The `onTap` function, triggered by `DemoRowButton` clicks, launches a
database operation in a new coroutine without checking if an operation is already in
progress. Rapid taps can launch multiple concurrent coroutines. When the first coroutine
finishes, it sets `dbOperationInFlight` to `false`, even if other coroutines are still
running. This leads to an inconsistent UI state, as other UI elements like the
`ResetButton` rely on this flag to manage their enabled state.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant