diff --git a/src/localdb.ts b/src/localdb.ts index 385b5fe..a874096 100644 --- a/src/localdb.ts +++ b/src/localdb.ts @@ -113,7 +113,8 @@ const fromSyncMappingsToPrevSyncRecords = ( */ const migrateDBsFrom20220326To20240220 = async ( db: InternalDBs, - vaultRandomID: string + vaultRandomID: string, + profileID: string ) => { const oldVer = 20220326; const newVer = 20240220; @@ -123,7 +124,12 @@ const migrateDBsFrom20220326To20240220 = async ( const syncMappings = await getAllSyncMetaMappingByVault(db, vaultRandomID); const prevSyncRecords = fromSyncMappingsToPrevSyncRecords(syncMappings); for (const prevSyncRecord of prevSyncRecords) { - await upsertPrevSyncRecordByVault(db, vaultRandomID, prevSyncRecord); + await upsertPrevSyncRecordByVaultAndProfile( + db, + vaultRandomID, + profileID, + prevSyncRecord + ); } // // clear not used data @@ -140,7 +146,8 @@ const migrateDBs = async ( db: InternalDBs, oldVer: number, newVer: number, - vaultRandomID: string + vaultRandomID: string, + profileID: string ) => { if (oldVer === newVer) { return; @@ -155,7 +162,7 @@ const migrateDBs = async ( } if (oldVer === 20220326 && newVer === 20240220) { - return await migrateDBsFrom20220326To20240220(db, vaultRandomID); + return await migrateDBsFrom20220326To20240220(db, vaultRandomID, profileID); } if (newVer < oldVer) { @@ -169,7 +176,8 @@ const migrateDBs = async ( export const prepareDBs = async ( vaultBasePath: string, - vaultRandomIDFromOldConfigFile: string + vaultRandomIDFromOldConfigFile: string, + profileID: string ) => { const db = { versionTbl: localforage.createInstance({ @@ -259,7 +267,8 @@ export const prepareDBs = async ( db, originalVersion, DEFAULT_DB_VERSION_NUMBER, - vaultRandomID + vaultRandomID, + profileID ); } @@ -414,16 +423,17 @@ export const clearExpiredSyncPlanRecords = async (db: InternalDBs) => { await Promise.all(ps); }; -export const getAllPrevSyncRecordsByVault = async ( +export const getAllPrevSyncRecordsByVaultAndProfile = async ( db: InternalDBs, - vaultRandomID: string + vaultRandomID: string, + profileID: string ) => { - // console.debug('inside getAllPrevSyncRecordsByVault') + // console.debug('inside getAllPrevSyncRecordsByVaultAndProfile') const keys = await db.prevSyncRecordsTbl.keys(); - // console.debug(`inside getAllPrevSyncRecordsByVault, keys=${keys}`) + // console.debug(`inside getAllPrevSyncRecordsByVaultAndProfile, keys=${keys}`) const res: Entity[] = []; for (const key of keys) { - if (key.startsWith(`${vaultRandomID}\t`)) { + if (key.startsWith(`${vaultRandomID}\t${profileID}\t`)) { const val: Entity | null = await db.prevSyncRecordsTbl.getItem(key); if (val !== null) { res.push(val); @@ -433,23 +443,27 @@ export const getAllPrevSyncRecordsByVault = async ( return res; }; -export const upsertPrevSyncRecordByVault = async ( +export const upsertPrevSyncRecordByVaultAndProfile = async ( db: InternalDBs, vaultRandomID: string, + profileID: string, prevSync: Entity ) => { await db.prevSyncRecordsTbl.setItem( - `${vaultRandomID}\t${prevSync.key}`, + `${vaultRandomID}\t${profileID}\t${prevSync.key}`, prevSync ); }; -export const clearPrevSyncRecordByVault = async ( +export const clearPrevSyncRecordByVaultAndProfile = async ( db: InternalDBs, vaultRandomID: string, + profileID: string, key: string ) => { - await db.prevSyncRecordsTbl.removeItem(`${vaultRandomID}\t${key}`); + await db.prevSyncRecordsTbl.removeItem( + `${vaultRandomID}\t${profileID}\t${key}` + ); }; export const clearAllPrevSyncRecordByVault = async ( diff --git a/src/main.ts b/src/main.ts index 1d1143d..46938ae 100644 --- a/src/main.ts +++ b/src/main.ts @@ -33,7 +33,7 @@ import { clearAllLoggerOutputRecords, upsertLastSuccessSyncTimeByVault, getLastSuccessSyncTimeByVault, - getAllPrevSyncRecordsByVault, + getAllPrevSyncRecordsByVaultAndProfile, } from "./localdb"; import { RemoteClient } from "./remote"; import { @@ -149,6 +149,8 @@ export default class RemotelySavePlugin extends Plugin { return this.i18n.t(x, vars); }; + const profileID = this.getCurrProfileID(); + const getNotice = (x: string, timeout?: number) => { // only show notices in manual mode // no notice in auto mode @@ -278,9 +280,10 @@ export default class RemotelySavePlugin extends Plugin { getNotice(t("syncrun_step5")); } this.syncStatus = "getting_local_prev_sync"; - const prevSyncEntityList = await getAllPrevSyncRecordsByVault( + const prevSyncEntityList = await getAllPrevSyncRecordsByVaultAndProfile( this.db, - this.vaultRandomID + this.vaultRandomID, + profileID ); console.debug("prevSyncEntityList:"); console.debug(prevSyncEntityList); @@ -330,6 +333,7 @@ export default class RemotelySavePlugin extends Plugin { mixedEntityMappings, client, this.vaultRandomID, + profileID, this.app.vault, this.settings.password, this.settings.concurrency ?? 5, @@ -433,6 +437,9 @@ export default class RemotelySavePlugin extends Plugin { await this.loadSettings(); + // MUST after loadSettings and before prepareDB + const profileID: string = this.getCurrProfileID(); + // lang should be load early, but after settings this.i18n = new I18n(this.settings.lang!, async (lang: LangTypeAndAuto) => { this.settings.lang = lang; @@ -458,7 +465,8 @@ export default class RemotelySavePlugin extends Plugin { try { await this.prepareDBAndVaultRandomID( vaultBasePath, - vaultRandomIDFromOldConfigFile + vaultRandomIDFromOldConfigFile, + profileID ); } catch (err: any) { new Notice( @@ -866,6 +874,17 @@ export default class RemotelySavePlugin extends Plugin { await this.saveData(normalConfigToMessy(this.settings)); } + /** + * After 202403 the data should be of profile based. + */ + getCurrProfileID() { + if (this.settings.serviceType !== undefined) { + return `${this.settings.serviceType}-default-1`; + } else { + throw Error("unknown serviceType in the setting!"); + } + } + async checkIfOauthExpires() { let needSave: boolean = false; const current = Date.now(); @@ -975,11 +994,13 @@ export default class RemotelySavePlugin extends Plugin { async prepareDBAndVaultRandomID( vaultBasePath: string, - vaultRandomIDFromOldConfigFile: string + vaultRandomIDFromOldConfigFile: string, + profileID: string ) { const { db, vaultRandomID } = await prepareDBs( vaultBasePath, - vaultRandomIDFromOldConfigFile + vaultRandomIDFromOldConfigFile, + profileID ); this.db = db; this.vaultRandomID = vaultRandomID; diff --git a/src/sync.ts b/src/sync.ts index b1d6980..832daa9 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -34,8 +34,8 @@ import { Vault } from "obsidian"; import AggregateError from "aggregate-error"; import { InternalDBs, - clearPrevSyncRecordByVault, - upsertPrevSyncRecordByVault, + clearPrevSyncRecordByVaultAndProfile, + upsertPrevSyncRecordByVaultAndProfile, } from "./localdb"; export type SyncStatusType = @@ -872,6 +872,7 @@ const splitThreeStepsOnEntityMappings = ( const dispatchOperationToActualV3 = async ( key: string, vaultRandomID: string, + profileID: string, r: MixedEntity, client: RemoteClient, db: InternalDBs, @@ -887,7 +888,7 @@ const dispatchOperationToActualV3 = async ( // )}` // ); if (r.decision === "only_history") { - clearPrevSyncRecordByVault(db, vaultRandomID, key); + clearPrevSyncRecordByVaultAndProfile(db, vaultRandomID, profileID, key); } else if ( r.decision === "equal" || r.decision === "folder_to_skip" || @@ -921,7 +922,12 @@ const dispatchOperationToActualV3 = async ( ); await decryptRemoteEntityInplace(entity, password); await fullfillMTimeOfRemoteEntityInplace(entity, mtimeCli); - await upsertPrevSyncRecordByVault(db, vaultRandomID, entity); + await upsertPrevSyncRecordByVaultAndProfile( + db, + vaultRandomID, + profileID, + entity + ); } } else if ( r.decision === "modified_remote" || @@ -938,15 +944,30 @@ const dispatchOperationToActualV3 = async ( password, r.remote!.keyEnc ); - await upsertPrevSyncRecordByVault(db, vaultRandomID, r.remote!); + await upsertPrevSyncRecordByVaultAndProfile( + db, + vaultRandomID, + profileID, + r.remote! + ); } else if (r.decision === "deleted_local") { // local is deleted, we need to delete remote now await client.deleteFromRemote(r.key, password, r.remote!.keyEnc); - await clearPrevSyncRecordByVault(db, vaultRandomID, r.key); + await clearPrevSyncRecordByVaultAndProfile( + db, + vaultRandomID, + profileID, + r.key + ); } else if (r.decision === "deleted_remote") { // remote is deleted, we need to delete local now await localDeleteFunc(r.key); - await clearPrevSyncRecordByVault(db, vaultRandomID, r.key); + await clearPrevSyncRecordByVaultAndProfile( + db, + vaultRandomID, + profileID, + r.key + ); } else if ( r.decision === "conflict_created_keep_both" || r.decision === "conflict_modified_keep_both" @@ -964,11 +985,21 @@ const dispatchOperationToActualV3 = async ( // we need to decrypt the key!!! await decryptRemoteEntityInplace(entity, password); await fullfillMTimeOfRemoteEntityInplace(entity, mtimeCli); - await upsertPrevSyncRecordByVault(db, vaultRandomID, entity); + await upsertPrevSyncRecordByVaultAndProfile( + db, + vaultRandomID, + profileID, + entity + ); } else if (r.decision === "folder_to_be_deleted") { await localDeleteFunc(r.key); await client.deleteFromRemote(r.key, password, r.remote!.keyEnc); - await clearPrevSyncRecordByVault(db, vaultRandomID, r.key); + await clearPrevSyncRecordByVaultAndProfile( + db, + vaultRandomID, + profileID, + r.key + ); } else { throw Error(`don't know how to dispatch decision: ${JSON.stringify(r)}`); } @@ -978,6 +1009,7 @@ export const doActualSync = async ( mixedEntityMappings: Record, client: RemoteClient, vaultRandomID: string, + profileID: string, vault: Vault, password: string, concurrency: number, @@ -1043,6 +1075,7 @@ export const doActualSync = async ( await dispatchOperationToActualV3( key, vaultRandomID, + profileID, val, client, db,