Functions/GenXdev.Data.KeyValueStore/Sync-KeyValueStore.ps1
################################################################################ <# .SYNOPSIS Synchronizes local and OneDrive shadow databases. .DESCRIPTION Performs two-way sync between local and shadow databases, with last-modified winning strategy. .PARAMETER SynchronizationKey Optional key to identify sync scope, defaults to "Local". .EXAMPLE Sync-KeyValueStore #> function Sync-KeyValueStore { [CmdletBinding()] param( ####################################################################### [Parameter( Mandatory = $false, Position = 0, HelpMessage = "Key to identify synchronization scope" )] [string]$SynchronizationKey = "Local" ####################################################################### ) # skip sync for local-only records if ($SynchronizationKey -eq "Local") { return } # get database paths $localDb = Expand-Path "$PSScriptRoot\..\..\..\..\GenXdev.Local\KeyValueStores.sqllite.db" $shadowDb = Expand-Path "~\OneDrive\GenXdev.PowerShell.SyncObjects\KeyValueStores.sqllite.db" # ensure both databases exist if (-not ([System.IO.File]::Exists($localDb) -and [System.IO.File]::Exists($shadowDb))) { Initialize-KeyValueStores } # sync query to merge changes based on last modified timestamp $syncQuery = @" ATTACH DATABASE @shadowDb AS shadow; -- sync from shadow to local INSERT OR REPLACE INTO main.KeyValueStore SELECT * FROM shadow.KeyValueStore s WHERE s.synchronizationKey = @syncKey AND ( NOT EXISTS ( SELECT 1 FROM main.KeyValueStore m WHERE m.synchronizationKey = s.synchronizationKey AND m.storeName = s.storeName AND m.keyName = s.keyName AND m.lastModified >= s.lastModified ) ); -- sync from local to shadow INSERT OR REPLACE INTO shadow.KeyValueStore SELECT * FROM main.KeyValueStore m WHERE m.synchronizationKey = @syncKey AND ( NOT EXISTS ( SELECT 1 FROM shadow.KeyValueStore s WHERE s.synchronizationKey = m.synchronizationKey AND s.storeName = m.storeName AND s.keyName = m.keyName AND s.lastModified > m.lastModified ) ); "@ $params = @{ 'shadowDb' = $shadowDb 'syncKey' = $SynchronizationKey } Invoke-SqlLiteQuery -DatabaseFilePath $localDb -Queries $syncQuery -SqlParameters $params } |