From 8d1511e38ff4c4f2513b9c3fe2aeac1ea533f210 Mon Sep 17 00:00:00 2001 From: Trent Larson Date: Tue, 27 May 2025 21:07:24 -0600 Subject: [PATCH] convert all remaining DB writes & reads to SQL (with successful registration & claim) --- doc/secure-storage-implementation.md | 153 ++++++++++++++++- src/App.vue | 13 +- src/components/FeedFilters.vue | 6 +- src/components/GiftedDialog.vue | 5 +- src/components/ImageMethodDialog.vue | 12 +- src/components/MembersList.vue | 5 +- src/components/OfferDialog.vue | 8 +- src/components/OnboardingDialog.vue | 19 ++- src/components/PhotoDialog.vue | 14 +- src/components/PushNotificationPermission.vue | 12 +- src/components/TopMessage.vue | 8 +- .../World/components/objects/landmarks.js | 7 +- src/db/databaseUtil.ts | 26 ++- src/db/index.ts | 6 + src/db/tables/accounts.ts | 1 + src/libs/endorserServer.ts | 4 +- src/libs/util.ts | 159 +++++++++++++----- src/main.capacitor.ts | 2 +- src/main.web.ts | 5 +- src/registerServiceWorker.ts | 21 ++- src/services/deepLinks.ts | 2 +- src/test/index.ts | 8 +- src/utils/logger.ts | 2 +- src/views/AccountViewView.vue | 7 +- src/views/ClaimAddRawView.vue | 11 +- src/views/ClaimCertificateView.vue | 5 +- src/views/ClaimReportCertificateView.vue | 5 +- src/views/ClaimView.vue | 18 +- src/views/ConfirmGiftView.vue | 5 +- src/views/ContactAmountsView.vue | 5 +- src/views/ContactGiftingView.vue | 5 +- src/views/ContactImportView.vue | 5 +- src/views/ContactQRScanFullView.vue | 5 +- src/views/ContactQRScanShowView.vue | 5 +- src/views/ContactsView.vue | 30 +++- src/views/DIDView.vue | 49 +++++- src/views/DeepLinkErrorView.vue | 2 +- src/views/DiscoverView.vue | 16 +- src/views/GiftedDetailsView.vue | 25 ++- src/views/HelpNotificationsView.vue | 12 +- src/views/HelpView.vue | 16 +- src/views/HomeView.vue | 78 +++++++-- src/views/IdentitySwitcherView.vue | 9 +- src/views/ImportAccountView.vue | 34 ++-- src/views/ImportDerivedAccountView.vue | 87 +++++++--- src/views/InviteOneAcceptView.vue | 10 +- src/views/InviteOneView.vue | 43 ++++- src/views/LogView.vue | 19 ++- src/views/NewActivityView.vue | 68 +++++++- src/views/NewEditAccountView.vue | 15 +- src/views/NewEditProjectView.vue | 12 +- src/views/OfferDetailsView.vue | 24 ++- src/views/OnboardMeetingListView.vue | 10 +- src/views/OnboardMeetingMembersView.vue | 10 +- src/views/OnboardMeetingSetupView.vue | 10 +- src/views/ProjectViewView.vue | 19 ++- src/views/ProjectsView.vue | 21 ++- src/views/QuickActionBvcBeginView.vue | 8 +- src/views/QuickActionBvcEndView.vue | 39 ++++- src/views/RecentOffersToUserProjectsView.vue | 21 ++- src/views/RecentOffersToUserView.vue | 20 ++- src/views/SearchAreaView.vue | 35 +++- src/views/ShareMyContactInfoView.vue | 22 ++- src/views/SharedPhotoView.vue | 35 +++- src/views/StartView.vue | 8 +- src/views/TestView.vue | 60 ++++++- src/views/UserProfileView.vue | 25 ++- 67 files changed, 1200 insertions(+), 266 deletions(-) diff --git a/doc/secure-storage-implementation.md b/doc/secure-storage-implementation.md index c41f61a6..b8c14c6d 100644 --- a/doc/secure-storage-implementation.md +++ b/doc/secure-storage-implementation.md @@ -131,14 +131,165 @@ async function getAccount(did: string): Promise { ); // Fallback to Dexie if needed - if (USE_DEXIE_DB && !account) { + if (USE_DEXIE_DB) { account = await db.accounts.get(did); } return account; } +``` + +#### A. Modifying Code + +When converting from Dexie.js to SQL-based implementation, follow these patterns: + +1. **Database Access Pattern** + ```typescript + // Before (Dexie) + const result = await db.table.where("field").equals(value).first(); + + // After (SQL) + const platform = PlatformServiceFactory.getInstance(); + let result = await platform.dbQuery( + "SELECT * FROM table WHERE field = ?", + [value] + ); + result = databaseUtil.mapQueryResultToValues(result); + + // Fallback to Dexie if needed + if (USE_DEXIE_DB) { + result = await db.table.where("field").equals(value).first(); + } + ``` + +2. **Update Operations** + ```typescript + // Before (Dexie) + await db.table.where("id").equals(id).modify(changes); + + // After (SQL) + // For settings updates, use the utility methods: + await databaseUtil.updateDefaultSettings(changes); + // OR + await databaseUtil.updateAccountSettings(did, changes); + + // For other tables, use direct SQL: + const platform = PlatformServiceFactory.getInstance(); + await platform.dbExec( + "UPDATE table SET field1 = ?, field2 = ? WHERE id = ?", + [changes.field1, changes.field2, id] + ); + + // Fallback to Dexie if needed + if (USE_DEXIE_DB) { + await db.table.where("id").equals(id).modify(changes); + } + ``` + +3. **Insert Operations** + ```typescript + // Before (Dexie) + await db.table.add(item); + + // After (SQL) + const platform = PlatformServiceFactory.getInstance(); + const columns = Object.keys(item); + const values = Object.values(item); + const placeholders = values.map(() => '?').join(', '); + const sql = `INSERT INTO table (${columns.join(', ')}) VALUES (${placeholders})`; + await platform.dbExec(sql, values); + + // Fallback to Dexie if needed + if (USE_DEXIE_DB) { + await db.table.add(item); + } + ``` + +4. **Delete Operations** + ```typescript + // Before (Dexie) + await db.table.where("id").equals(id).delete(); + + // After (SQL) + const platform = PlatformServiceFactory.getInstance(); + await platform.dbExec("DELETE FROM table WHERE id = ?", [id]); + + // Fallback to Dexie if needed + if (USE_DEXIE_DB) { + await db.table.where("id").equals(id).delete(); + } + ``` + +5. **Result Processing** + ```typescript + // Before (Dexie) + const items = await db.table.toArray(); + + // After (SQL) + const platform = PlatformServiceFactory.getInstance(); + let items = await platform.dbQuery("SELECT * FROM table"); + items = databaseUtil.mapQueryResultToValues(items); + + // Fallback to Dexie if needed + if (USE_DEXIE_DB) { + items = await db.table.toArray(); + } ``` +6. **Using Utility Methods** + +When working with settings or other common operations, use the utility methods in `db/index.ts`: + +```typescript +// Settings operations +await databaseUtil.updateDefaultSettings(settings); +await databaseUtil.updateAccountSettings(did, settings); +const settings = await databaseUtil.retrieveSettingsForDefaultAccount(); +const settings = await databaseUtil.retrieveSettingsForActiveAccount(); + +// Logging operations +await databaseUtil.logToDb(message); +await databaseUtil.logConsoleAndDb(message, showInConsole); +``` + +Key Considerations: +- Always use `databaseUtil.mapQueryResultToValues()` to process SQL query results +- Use utility methods from `db/index.ts` when available instead of direct SQL +- Keep Dexie fallbacks wrapped in `if (USE_DEXIE_DB)` checks +- For queries that return results, use `let` variables to allow Dexie fallback to override +- For updates/inserts/deletes, execute both SQL and Dexie operations when `USE_DEXIE_DB` is true + +Example Migration: +```typescript +// Before (Dexie) +export async function updateSettings(settings: Settings): Promise { + await db.settings.put(settings); +} + +// After (SQL) +export async function updateSettings(settings: Settings): Promise { + const platform = PlatformServiceFactory.getInstance(); + const { sql, params } = generateUpdateStatement( + settings, + "settings", + "id = ?", + [settings.id] + ); + await platform.dbExec(sql, params); +} +``` + +Remember to: +- Create database access code to use the platform service, putting it in front of the Dexie version +- Instead of removing Dexie-specific code, keep it. + + - For creates & updates & deletes, the duplicate code is fine. + + - For queries where we use the results, make the setting from SQL into a 'let' variable, then wrap the Dexie code in a check for USE_DEXIE_DB from app.ts and if +it's true then use that result instead of the SQL code's result. + +- Consider data migration needs, and warn if there are any potential migration problems + ## Success Criteria 1. **Functionality** diff --git a/src/App.vue b/src/App.vue index 5bd5900b..91bce243 100644 --- a/src/App.vue +++ b/src/App.vue @@ -330,8 +330,11 @@