33 * Licensed under the MIT License. See License.txt in the project root for license information.
44 *--------------------------------------------------------------------------------------------*/
55
6- import { Disposable } from 'vs/base/common/lifecycle' ;
6+ import { Disposable , IDisposable , dispose } from 'vs/base/common/lifecycle' ;
77import { Event , Emitter } from 'vs/base/common/event' ;
88import { ILogService } from 'vs/platform/log/common/log' ;
99import { IEnvironmentService } from 'vs/platform/environment/common/environment' ;
1010import { IWorkspaceStorageChangeEvent , IStorageService , StorageScope } from 'vs/platform/storage/common/storage' ;
1111import { Storage , IStorageLoggingOptions } from 'vs/base/node/storage' ;
1212import { IStorageLegacyService , StorageLegacyScope } from 'vs/platform/storage/common/storageLegacyService' ;
13- import { addDisposableListener } from 'vs/base/browser/dom' ;
1413import { startsWith } from 'vs/base/common/strings' ;
1514import { Action } from 'vs/base/common/actions' ;
1615import { IWindowService } from 'vs/platform/windows/common/windows' ;
1716import { localize } from 'vs/nls' ;
1817import { mark , getDuration } from 'vs/base/common/performance' ;
18+ import { IWorkspaceIdentifier } from 'vs/platform/workspaces/common/workspaces' ;
19+ import { join , basename } from 'path' ;
20+ import { mkdirp , copy } from 'vs/base/node/pfs' ;
1921
2022export class StorageService extends Disposable implements IStorageService {
2123 _serviceBrand : any ;
@@ -46,16 +48,21 @@ export class StorageService extends Disposable implements IStorageService {
4648 }
4749
4850 private globalStorage : Storage ;
51+
52+ private workspaceStoragePath : string ;
4953 private workspaceStorage : Storage ;
54+ private workspaceStorageListener : IDisposable ;
55+
56+ private loggingOptions : IStorageLoggingOptions ;
5057
5158 constructor (
52- workspaceDBPath : string ,
59+ workspaceStoragePath : string ,
5360 @ILogService logService : ILogService ,
54- @IEnvironmentService environmentService : IEnvironmentService
61+ @IEnvironmentService private environmentService : IEnvironmentService
5562 ) {
5663 super ( ) ;
5764
58- const loggingOptions : IStorageLoggingOptions = {
65+ this . loggingOptions = {
5966 info : environmentService . verbose || environmentService . logStorage ,
6067 infoLogger : msg => logService . info ( msg ) ,
6168 errorLogger : error => {
@@ -69,15 +76,22 @@ export class StorageService extends Disposable implements IStorageService {
6976 }
7077 } ;
7178
72- this . globalStorage = new Storage ( { path : workspaceDBPath === StorageService . IN_MEMORY_PATH ? StorageService . IN_MEMORY_PATH : StorageService . IN_MEMORY_PATH , logging : loggingOptions } ) ;
73- this . workspaceStorage = new Storage ( { path : workspaceDBPath , logging : loggingOptions } ) ;
79+ this . globalStorage = new Storage ( { path : workspaceStoragePath === StorageService . IN_MEMORY_PATH ? StorageService . IN_MEMORY_PATH : StorageService . IN_MEMORY_PATH , logging : this . loggingOptions } ) ;
80+ this . _register ( this . globalStorage . onDidChangeStorage ( key => this . handleDidChangeStorage ( key , StorageScope . GLOBAL ) ) ) ;
7481
75- this . registerListeners ( ) ;
82+ this . createWorkspaceStorage ( workspaceStoragePath ) ;
7683 }
7784
78- private registerListeners ( ) : void {
79- this . _register ( this . globalStorage . onDidChangeStorage ( key => this . handleDidChangeStorage ( key , StorageScope . GLOBAL ) ) ) ;
80- this . _register ( this . workspaceStorage . onDidChangeStorage ( key => this . handleDidChangeStorage ( key , StorageScope . WORKSPACE ) ) ) ;
85+ private createWorkspaceStorage ( workspaceStoragePath : string ) : void {
86+
87+ // Dispose old (if any)
88+ this . workspaceStorage = dispose ( this . workspaceStorage ) ;
89+ this . workspaceStorageListener = dispose ( this . workspaceStorageListener ) ;
90+
91+ // Create new
92+ this . workspaceStoragePath = workspaceStoragePath ;
93+ this . workspaceStorage = new Storage ( { path : workspaceStoragePath , logging : this . loggingOptions } ) ;
94+ this . workspaceStorageListener = this . workspaceStorage . onDidChangeStorage ( key => this . handleDidChangeStorage ( key , StorageScope . WORKSPACE ) ) ;
8195 }
8296
8397 private handleDidChangeStorage ( key : string , scope : StorageScope ) : void {
@@ -180,6 +194,30 @@ export class StorageService extends Disposable implements IStorageService {
180194 console . log ( workspaceItemsParsed ) ;
181195 } ) ;
182196 }
197+
198+ migrate ( toWorkspace : IWorkspaceIdentifier ) : Promise < void > {
199+ if ( this . workspaceStoragePath === StorageService . IN_MEMORY_PATH ) {
200+ return Promise . resolve ( ) ; // no migration needed if running in memory
201+ }
202+
203+ // Compute new workspace storage path based on workspace identifier
204+ const newWorkspaceStorageHome = join ( this . environmentService . workspaceStorageHome , toWorkspace . id ) ;
205+ const newWorkspaceStoragePath = join ( newWorkspaceStorageHome , basename ( this . workspaceStoragePath ) ) ;
206+ if ( this . workspaceStoragePath === newWorkspaceStoragePath ) {
207+ return Promise . resolve ( ) ; // guard against migrating to same path
208+ }
209+
210+ // Close workspace DB to be able to copy
211+ return this . workspaceStorage . close ( ) . then ( ( ) => {
212+ return mkdirp ( newWorkspaceStorageHome ) . then ( ( ) => {
213+ return copy ( this . workspaceStoragePath , newWorkspaceStoragePath ) . then ( ( ) => {
214+ this . createWorkspaceStorage ( newWorkspaceStoragePath ) ;
215+
216+ return this . workspaceStorage . init ( ) ;
217+ } ) ;
218+ } ) ;
219+ } ) ;
220+ }
183221}
184222
185223export class LogStorageAction extends Action {
@@ -215,9 +253,9 @@ export class DelegatingStorageService extends Disposable implements IStorageServ
215253 private closed : boolean ;
216254
217255 constructor (
218- @ IStorageService private storageService : StorageService ,
219- @ IStorageLegacyService private storageLegacyService : IStorageLegacyService ,
220- @ ILogService private logService : ILogService
256+ private storageService : IStorageService ,
257+ private storageLegacyService : IStorageLegacyService ,
258+ private logService : ILogService
221259 ) {
222260 super ( ) ;
223261
@@ -229,17 +267,18 @@ export class DelegatingStorageService extends Disposable implements IStorageServ
229267 this . _register ( this . storageService . onWillSaveState ( ( ) => this . _onWillSaveState . fire ( ) ) ) ;
230268
231269 const globalKeyMarker = 'storage://global/' ;
232- this . _register ( addDisposableListener ( window , 'storage' , ( e : StorageEvent ) => {
270+
271+ window . addEventListener ( 'storage' , e => {
233272 if ( startsWith ( e . key , globalKeyMarker ) ) {
234273 const key = e . key . substr ( globalKeyMarker . length ) ;
235274
236275 this . _onDidChangeStorage . fire ( { key, scope : StorageScope . GLOBAL } ) ;
237276 }
238- } ) ) ;
277+ } ) ;
239278 }
240279
241280 get storage ( ) : StorageService {
242- return this . storageService ;
281+ return this . storageService as StorageService ;
243282 }
244283
245284 get ( key : string , scope : StorageScope , fallbackValue ?: any ) : string {
@@ -291,7 +330,7 @@ export class DelegatingStorageService extends Disposable implements IStorageServ
291330 }
292331
293332 close ( ) : Promise < void > {
294- const promise = this . storageService . close ( ) ;
333+ const promise = this . storage . close ( ) ;
295334
296335 this . closed = true ;
297336
0 commit comments