Skip to content

ADFA-3879 resilient LastChange table#1302

Merged
hal-eisen-adfa merged 6 commits into
stagefrom
ADFA-3879-resilient-wholedb-missing-from-LastChange
May 22, 2026
Merged

ADFA-3879 resilient LastChange table#1302
hal-eisen-adfa merged 6 commits into
stagefrom
ADFA-3879-resilient-wholedb-missing-from-LastChange

Conversation

@hal-eisen-adfa
Copy link
Copy Markdown
Collaborator

Handle missing documentation.db LastChange wholedb record by fallback
Never crash regardless of LastChange table

…; never crash regardless of LastChange table
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 6df1b1b7-2fc2-4005-9f00-808b0c0ec4ad

📥 Commits

Reviewing files that changed from the base of the PR and between 634b800 and 18496e9.

📒 Files selected for processing (1)
  • app/src/main/java/com/itsaky/androidide/localWebServer/WebServer.kt

📝 Walkthrough

Release Notes

Resilient Database Version Resolution

  • Added new DatabaseVersionResolver utility that safely queries the LastChange table for database version information
  • Implements fallback logic when the preferred wholedb record is missing: falls back to the most recent LastChange row
  • Returns "Version Unknown" gracefully when the LastChange table is missing, empty, or inaccessible
  • Centralizes database version resolution across the codebase (WebServer, TooltipManager)

Improved Robustness

  • Application will no longer crash due to missing or malformed LastChange table entries
  • Comprehensive error logging when wholedb records are missing or when resolution fails
  • Handles NULL values in the who column correctly

Code Cleanup

  • Removed debug/test artifacts: TooltipScreenshotHostActivity, TooltipDebugDialogScreenshotTest, and debug AndroidManifest entries
  • Replaced inline SQL queries with centralized utility for better maintainability

Test Coverage

  • Added DatabaseVersionResolverTest with comprehensive test scenarios covering:
    • Preference for wholedb row when present
    • Fallback to latest row when wholedb is missing
    • Handling of empty or missing LastChange table
    • Correct formatting with NULL who values

Walkthrough

This PR centralizes database version resolution by introducing DatabaseVersionResolver, a utility that queries the LastChange table for version information. The resolver is tested comprehensively and integrated into TooltipManager and WebServer to replace direct SQL queries.

Changes

Database Version Resolution Centralization

Layer / File(s) Summary
DatabaseVersionResolver implementation
common/src/main/java/com/itsaky/androidide/utils/DatabaseVersionResolver.kt
resolveDatabaseVersion() queries LastChange for wholedb records, falls back to the latest row if missing (with error logging), and uses formatVersion() to construct space-separated version strings from changeTime, optional documentationSet, and optional who fields.
DatabaseVersionResolver test coverage
common/src/androidTest/java/com/itsaky/androidide/utils/DatabaseVersionResolverTest.kt
Tests validate resolver behavior: returns wholedb rows when present, falls back to the latest non-wholedb row, returns VERSION_UNKNOWN for missing or empty tables, and correctly formats output with nullable who columns.
TooltipManager migration
idetooltips/src/main/java/com/itsaky/androidide/idetooltips/ToolTipManager.kt
getTooltip() calls DatabaseVersionResolver.resolveDatabaseVersion() instead of executing the QUERY_LAST_CHANGE SQL constant; resolution errors are caught and logged.
WebServer migration
app/src/main/java/com/itsaky/androidide/localWebServer/WebServer.kt
logDatabaseLastChanged() calls DatabaseVersionResolver.resolveDatabaseVersion() instead of executing cursor-based LastChange queries.

Sequence Diagram

sequenceDiagram
  participant TooltipMgr as TooltipManager
  participant WebServer
  participant Resolver as DatabaseVersionResolver
  participant DB as SQLiteDatabase
  
  TooltipMgr->>Resolver: resolveDatabaseVersion(db)
  Resolver->>DB: query wholedb from LastChange
  alt wholedb found
    DB-->>Resolver: wholedb row (changeTime, who)
    Resolver->>Resolver: formatVersion(changeTime, who)
    Resolver-->>TooltipMgr: formatted version string
  else wholedb missing
    DB-->>Resolver: no wholedb row
    Resolver->>DB: query latest LastChange row
    DB-->>Resolver: latest row (changeTime, who, documentationSet)
    Resolver->>Resolver: formatVersion(changeTime, who, documentationSet)
    Resolver-->>TooltipMgr: formatted version string
  end
  
  WebServer->>Resolver: resolveDatabaseVersion(db)
  Resolver-->>WebServer: version string
  WebServer->>WebServer: log version
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • appdevforall/CodeOnTheGo#843: Updates WebServer.kt's logDatabaseLastChanged() to use the renamed changeTime column; this PR further refactors that method to use centralized DatabaseVersionResolver instead of direct SQL queries.

Poem

🐰 A resolver hops in to tame the queries wild,
No more raw SQL, just logic reconciled!
FromWeb to Tooltip, the version flows so clean,
Tested and ready, the best we've seen! 🎉

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title 'ADFA-3879 resilient LastChange table' clearly summarizes the main change: making the LastChange table handling resilient by adding fallback mechanisms.
Description check ✅ Passed The description directly relates to the changeset, explaining the key improvements: handling missing wholedb records with fallback and ensuring robustness against LastChange table issues.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ADFA-3879-resilient-wholedb-missing-from-LastChange

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
common/src/androidTest/java/com/itsaky/androidide/utils/DatabaseVersionResolverTest.kt (1)

42-52: ⚡ Quick win

Consider adding a test case for multiple wholedb records.

The current test verifies that a single wholedb record is returned correctly. To ensure the query returns the latest record when multiple wholedb entries exist (especially after adding ORDER BY changeTime DESC as suggested), consider adding a test case that inserts multiple wholedb records with different timestamps and verifies the most recent one is returned.

🧪 Example test case
`@Test`
fun returnsLatestWholedbRow_whenMultiplePresent() {
	createTable()
	insertRow("wholedb", "2026-05-01 10:00:00", "alice")
	insertRow("wholedb", "2026-05-09 02:00:20", "hal")
	insertRow("wholedb", "2026-05-03 14:30:00", "bob")

	assertEquals(
		"2026-05-09 02:00:20 hal",
		DatabaseVersionResolver.resolveDatabaseVersion(db),
	)
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@common/src/androidTest/java/com/itsaky/androidide/utils/DatabaseVersionResolverTest.kt`
around lines 42 - 52, Add a new test in DatabaseVersionResolverTest (e.g.,
returnsLatestWholedbRow_whenMultiplePresent) that uses createTable() and
insertRow() to insert multiple "wholedb" rows with different changeTime values,
then assert DatabaseVersionResolver.resolveDatabaseVersion(db) returns the most
recent record (timestamp + author); reference the existing
returnsWholedbRow_whenPresent test for structure and ensure the inserted
timestamps exercise the ORDER BY changeTime DESC behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@app/src/debug/AndroidManifest.xml`:
- Line 7: Remove the android:exported="true" attribute from the debug-only test
activity declaration (the activity launched by ActivityScenario.launch()) so the
activity is not exported to other apps; edit the debug AndroidManifest entry for
that test activity and either delete the android:exported attribute or set it to
false to restrict visibility.

In `@common/src/main/java/com/itsaky/androidide/utils/DatabaseVersionResolver.kt`:
- Around line 12-17: The QUERY_WHOLEDB SQL constant currently selects LIMIT 1
from LastChange without ordering, which can return non-deterministic rows;
update the QUERY_WHOLEDB constant to include an ORDER BY changeTime DESC
(matching QUERY_FALLBACK_LATEST) so the latest wholedb record is
deterministically returned when using LIMIT 1.

---

Nitpick comments:
In
`@common/src/androidTest/java/com/itsaky/androidide/utils/DatabaseVersionResolverTest.kt`:
- Around line 42-52: Add a new test in DatabaseVersionResolverTest (e.g.,
returnsLatestWholedbRow_whenMultiplePresent) that uses createTable() and
insertRow() to insert multiple "wholedb" rows with different changeTime values,
then assert DatabaseVersionResolver.resolveDatabaseVersion(db) returns the most
recent record (timestamp + author); reference the existing
returnsWholedbRow_whenPresent test for structure and ensure the inserted
timestamps exercise the ORDER BY changeTime DESC behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 016fc624-892c-440f-a64b-02ad7f47ea54

📥 Commits

Reviewing files that changed from the base of the PR and between b85bbc2 and 634b800.

📒 Files selected for processing (7)
  • app/src/androidTest/kotlin/com/itsaky/androidide/idetooltips/TooltipDebugDialogScreenshotTest.kt
  • app/src/debug/AndroidManifest.xml
  • app/src/debug/java/com/itsaky/androidide/idetooltips/TooltipScreenshotHostActivity.kt
  • app/src/main/java/com/itsaky/androidide/localWebServer/WebServer.kt
  • common/src/androidTest/java/com/itsaky/androidide/utils/DatabaseVersionResolverTest.kt
  • common/src/main/java/com/itsaky/androidide/utils/DatabaseVersionResolver.kt
  • idetooltips/src/main/java/com/itsaky/androidide/idetooltips/ToolTipManager.kt

Comment thread app/src/debug/AndroidManifest.xml Outdated
@hal-eisen-adfa hal-eisen-adfa requested a review from a team May 13, 2026 23:37
@hal-eisen-adfa hal-eisen-adfa merged commit b640821 into stage May 22, 2026
2 checks passed
@hal-eisen-adfa hal-eisen-adfa deleted the ADFA-3879-resilient-wholedb-missing-from-LastChange branch May 22, 2026 00:10
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.

2 participants