diff --git a/src/db/databaseUtil.ts b/src/db/databaseUtil.ts index d68926fe..132316a5 100644 --- a/src/db/databaseUtil.ts +++ b/src/db/databaseUtil.ts @@ -117,34 +117,14 @@ export async function retrieveSettingsForActiveAccount(): Promise { return defaultSettings; } - // Map and filter settings + // Map settings const overrideSettings = mapColumnsToValues( result.columns, result.values, )[0] as Settings; - const overrideSettingsFiltered = Object.fromEntries( - Object.entries(overrideSettings).filter(([_, v]) => v !== null), - ); - - // Merge settings - const settings = { ...defaultSettings, ...overrideSettingsFiltered }; - - // Handle searchBoxes parsing - if (settings.searchBoxes) { - try { - // @ts-expect-error - the searchBoxes field is a string in the DB - settings.searchBoxes = JSON.parse(settings.searchBoxes); - } catch (error) { - logConsoleAndDb( - `[databaseUtil] Failed to parse searchBoxes for ${defaultSettings.activeDid}: ${error}`, - true, - ); - // Reset to empty array on parse failure - settings.searchBoxes = []; - } - } - return settings; + // Use the new mergeSettings function for consistency + return mergeSettings(defaultSettings, overrideSettings); } catch (error) { logConsoleAndDb( `[databaseUtil] Failed to retrieve account settings for ${defaultSettings.activeDid}: ${error}`, @@ -312,3 +292,128 @@ export function mapColumnsToValues( return obj; }); } + +/** + * Retrieves settings for a specific account by DID + * @param accountDid - The DID of the account to retrieve settings for + * @returns Promise Combined settings for the specified account + */ +export async function getSettingsForAccount(accountDid: string): Promise { + try { + // Get default settings first + const defaultSettings = await retrieveSettingsForDefaultAccount(); + + // Get account-specific settings + const platform = PlatformServiceFactory.getInstance(); + const result = await platform.dbQuery( + "SELECT * FROM settings WHERE accountDid = ?", + [accountDid], + ); + + if (!result?.values?.length) { + logConsoleAndDb( + `[databaseUtil] No account-specific settings found for ${accountDid}`, + ); + return defaultSettings; + } + + // Map and merge settings + const overrideSettings = mapColumnsToValues( + result.columns, + result.values, + )[0] as Settings; + + return mergeSettings(defaultSettings, overrideSettings); + } catch (error) { + logConsoleAndDb( + `[databaseUtil] Failed to retrieve settings for account ${accountDid}: ${error}`, + true, + ); + // Return default settings on error + return await retrieveSettingsForDefaultAccount(); + } +} + +/** + * Retrieves only account-specific settings for a given DID (without merging with defaults) + * @param accountDid - The DID of the account to retrieve settings for + * @returns Promise Account-specific settings only + */ +export async function getAccountSpecificSettings(accountDid: string): Promise { + try { + const platform = PlatformServiceFactory.getInstance(); + const result = await platform.dbQuery( + "SELECT * FROM settings WHERE accountDid = ?", + [accountDid], + ); + + if (!result?.values?.length) { + logConsoleAndDb( + `[databaseUtil] No account-specific settings found for ${accountDid}`, + ); + return {}; + } + + // Map settings + const settings = mapColumnsToValues( + result.columns, + result.values, + )[0] as Settings; + + // Handle searchBoxes parsing + if (settings.searchBoxes) { + try { + // @ts-expect-error - the searchBoxes field is a string in the DB + settings.searchBoxes = JSON.parse(settings.searchBoxes); + } catch (error) { + logConsoleAndDb( + `[databaseUtil] Failed to parse searchBoxes for ${accountDid}: ${error}`, + true, + ); + // Reset to empty array on parse failure + settings.searchBoxes = []; + } + } + + return settings; + } catch (error) { + logConsoleAndDb( + `[databaseUtil] Failed to retrieve account-specific settings for ${accountDid}: ${error}`, + true, + ); + return {}; + } +} + +/** + * Merges default settings with account-specific settings using consistent logic + * @param defaultSettings - The default/master settings + * @param accountSettings - The account-specific settings to merge + * @returns Settings - Merged settings with account-specific overrides + */ +export function mergeSettings(defaultSettings: Settings, accountSettings: Settings): Settings { + // Filter out null values from account settings + const accountSettingsFiltered = Object.fromEntries( + Object.entries(accountSettings).filter(([_, v]) => v !== null), + ); + + // Perform shallow merge (account settings override defaults) + const mergedSettings = { ...defaultSettings, ...accountSettingsFiltered }; + + // Handle searchBoxes parsing if present + if (mergedSettings.searchBoxes) { + try { + // @ts-expect-error - the searchBoxes field is a string in the DB + mergedSettings.searchBoxes = JSON.parse(mergedSettings.searchBoxes); + } catch (error) { + logConsoleAndDb( + `[databaseUtil] Failed to parse searchBoxes during merge: ${error}`, + true, + ); + // Reset to empty array on parse failure + mergedSettings.searchBoxes = []; + } + } + + return mergedSettings; +} diff --git a/src/db/index.ts b/src/db/index.ts index 0f879fb1..4bba7250 100644 --- a/src/db/index.ts +++ b/src/db/index.ts @@ -265,6 +265,43 @@ export async function retrieveSettingsForActiveAccount(): Promise { } } +/** + * Retrieves settings for a specific account by DID + * @param accountDid - The DID of the account to retrieve settings for + * @returns Promise Combined settings for the specified account + */ +export async function getSettingsForAccount(accountDid: string): Promise { + const defaultSettings = await retrieveSettingsForDefaultAccount(); + const overrideSettings = + (await db.settings + .where("accountDid") + .equals(accountDid) + .first()) || {}; + return R.mergeDeepRight(defaultSettings, overrideSettings); +} + +/** + * Retrieves only account-specific settings for a given DID (without merging with defaults) + * @param accountDid - The DID of the account to retrieve settings for + * @returns Promise Account-specific settings only + */ +export async function getAccountSpecificSettings(accountDid: string): Promise { + return (await db.settings + .where("accountDid") + .equals(accountDid) + .first()) || {}; +} + +/** + * Merges default settings with account-specific settings using consistent logic + * @param defaultSettings - The default/master settings + * @param accountSettings - The account-specific settings to merge + * @returns Settings - Merged settings with account-specific overrides + */ +export function mergeSettings(defaultSettings: Settings, accountSettings: Settings): Settings { + return R.mergeDeepRight(defaultSettings, accountSettings); +} + export async function updateAccountSettings( accountDid: string, settingsChanges: Settings,