Skip to content

Commit 3fb9969

Browse files
author
Benjamin Pasero
committed
storage - only create DB if path does not exist
1 parent fd5d3ca commit 3fb9969

7 files changed

Lines changed: 37 additions & 27 deletions

File tree

src/vs/base/node/storage.ts

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
* Licensed under the MIT License. See License.txt in the project root for license information.
44
*--------------------------------------------------------------------------------------------*/
55

6-
import { Database, Statement } from 'vscode-sqlite3';
6+
import { Database, Statement, OPEN_READWRITE, OPEN_CREATE } from 'vscode-sqlite3';
77
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
88
import { Emitter, Event } from 'vs/base/common/event';
99
import { RunOnceScheduler, Queue } from 'vs/base/common/async';
@@ -14,6 +14,7 @@ import { mark } from 'vs/base/common/performance';
1414

1515
export interface IStorageOptions {
1616
path: string;
17+
createPath: boolean;
1718

1819
logging?: IStorageLoggingOptions;
1920
}
@@ -363,18 +364,18 @@ export class SQLiteStorageImpl {
363364
this.logger.info(`[storage ${this.name}] open()`);
364365

365366
return new Promise((resolve, reject) => {
366-
this.doOpen(this.options.path).then(resolve, error => {
367+
this.doOpen(this.options.path, this.options.createPath).then(resolve, error => {
367368
this.logger.error(`[storage ${this.name}] open(): Error (open DB): ${error}`);
368369
this.logger.error(`[storage ${this.name}] open(): Falling back to in-memory DB`);
369370

370371
// In case of any error to open the DB, use an in-memory
371372
// DB so that we always have a valid DB to talk to.
372-
this.doOpen(':memory:').then(resolve, reject);
373+
this.doOpen(':memory:', true).then(resolve, reject);
373374
});
374375
});
375376
}
376377

377-
private doOpen(path: string): Promise<Database> {
378+
private doOpen(path: string, createPath: boolean): Promise<Database> {
378379
return new Promise((resolve, reject) => {
379380
let measureRequireDuration = false;
380381
if (!SQLiteStorageImpl.measuredRequireDuration) {
@@ -388,12 +389,17 @@ export class SQLiteStorageImpl {
388389
mark('didRequireSQLite');
389390
}
390391

391-
const db = new (this.logger.verbose ? sqlite3.verbose().Database : sqlite3.Database)(path, error => {
392+
const db = new (this.logger.verbose ? sqlite3.verbose().Database : sqlite3.Database)(path, createPath ? OPEN_READWRITE | OPEN_CREATE : OPEN_READWRITE, error => {
392393
if (error) {
393394
return reject(error);
394395
}
395396

396-
// Setup schema
397+
// Return early if we did not create the DB
398+
if (!createPath) {
399+
return resolve(db);
400+
}
401+
402+
// Otherwise: Setup schema
397403
mark('willSetupSQLiteSchema');
398404
this.exec(db, [
399405
'PRAGMA user_version = 1;',

src/vs/base/test/node/storage/storage.test.ts

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ suite('Storage Library', () => {
2323
const storageDir = uniqueStorageDir();
2424
await mkdirp(storageDir);
2525

26-
const storage = new Storage({ path: join(storageDir, 'storage.db') });
26+
const storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: true });
2727

2828
await storage.init();
2929

@@ -97,7 +97,7 @@ suite('Storage Library', () => {
9797
const storageDir = uniqueStorageDir();
9898
await mkdirp(storageDir);
9999

100-
let storage = new Storage({ path: join(storageDir, 'storage.db') });
100+
let storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: true });
101101
await storage.init();
102102

103103
const set1Promise = storage.set('foo', 'bar');
@@ -113,15 +113,15 @@ suite('Storage Library', () => {
113113

114114
equal(setPromiseResolved, true);
115115

116-
storage = new Storage({ path: join(storageDir, 'storage.db') });
116+
storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: false });
117117
await storage.init();
118118

119119
equal(storage.get('foo'), 'bar');
120120
equal(storage.get('bar'), 'foo');
121121

122122
await storage.close();
123123

124-
storage = new Storage({ path: join(storageDir, 'storage.db') });
124+
storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: false });
125125
await storage.init();
126126

127127
const delete1Promise = storage.delete('foo');
@@ -137,7 +137,7 @@ suite('Storage Library', () => {
137137

138138
equal(deletePromiseResolved, true);
139139

140-
storage = new Storage({ path: join(storageDir, 'storage.db') });
140+
storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: false });
141141
await storage.init();
142142

143143
ok(!storage.get('foo'));
@@ -151,7 +151,7 @@ suite('Storage Library', () => {
151151
const storageDir = uniqueStorageDir();
152152
await mkdirp(storageDir);
153153

154-
let storage = new Storage({ path: join(storageDir, 'storage.db') });
154+
let storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: true });
155155
await storage.init();
156156

157157
let changes = new Set<string>();
@@ -206,7 +206,7 @@ suite('SQLite Storage Library', () => {
206206
}
207207

208208
async function testDBBasics(path, errorLogger?: (error) => void) {
209-
const options: IStorageOptions = { path };
209+
const options: IStorageOptions = { path, createPath: true };
210210
if (errorLogger) {
211211
options.logging = {
212212
errorLogger
@@ -305,7 +305,8 @@ suite('SQLite Storage Library', () => {
305305
await mkdirp(storageDir);
306306

307307
let storage = new SQLiteStorageImpl({
308-
path: join(storageDir, 'storage.db')
308+
path: join(storageDir, 'storage.db'),
309+
createPath: true
309310
});
310311

311312
const items1 = new Map<string, string>();
@@ -381,7 +382,8 @@ suite('SQLite Storage Library', () => {
381382
await storage.close();
382383

383384
storage = new SQLiteStorageImpl({
384-
path: join(storageDir, 'storage.db')
385+
path: join(storageDir, 'storage.db'),
386+
createPath: true
385387
});
386388

387389
storedItems = await storage.getItems();
@@ -398,7 +400,8 @@ suite('SQLite Storage Library', () => {
398400
await mkdirp(storageDir);
399401

400402
let storage = new SQLiteStorageImpl({
401-
path: join(storageDir, 'storage.db')
403+
path: join(storageDir, 'storage.db'),
404+
createPath: true
402405
});
403406

404407
const items = new Map<string, string>();
@@ -451,7 +454,7 @@ suite('SQLite Storage Library', () => {
451454
const storageDir = uniqueStorageDir();
452455
await mkdirp(storageDir);
453456

454-
const storage = new Storage({ path: join(storageDir, 'storage.db') });
457+
const storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: true });
455458

456459
await storage.init();
457460

src/vs/platform/storage/node/storageService.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ export class StorageService extends Disposable implements IStorageService {
6161

6262
constructor(
6363
workspaceStoragePath: string,
64+
workspaceStoragePathExists: boolean,
6465
disableGlobalStorage: boolean,
6566
@ILogService logService: ILogService,
6667
@IEnvironmentService environmentService: IEnvironmentService
@@ -84,21 +85,21 @@ export class StorageService extends Disposable implements IStorageService {
8485
};
8586

8687
this.globalStorageWorkspacePath = workspaceStoragePath === StorageService.IN_MEMORY_PATH ? StorageService.IN_MEMORY_PATH : StorageService.IN_MEMORY_PATH;
87-
this.globalStorage = disableGlobalStorage ? new NullStorage() : new Storage({ path: this.globalStorageWorkspacePath, logging: this.loggingOptions });
88+
this.globalStorage = disableGlobalStorage ? new NullStorage() : new Storage({ path: this.globalStorageWorkspacePath, createPath: true, logging: this.loggingOptions });
8889
this._register(this.globalStorage.onDidChangeStorage(key => this.handleDidChangeStorage(key, StorageScope.GLOBAL)));
8990

90-
this.createWorkspaceStorage(workspaceStoragePath);
91+
this.createWorkspaceStorage(workspaceStoragePath, workspaceStoragePathExists);
9192
}
9293

93-
private createWorkspaceStorage(workspaceStoragePath: string): void {
94+
private createWorkspaceStorage(workspaceStoragePath: string, workspaceStoragePathExists: boolean): void {
9495

9596
// Dispose old (if any)
9697
this.workspaceStorage = dispose(this.workspaceStorage);
9798
this.workspaceStorageListener = dispose(this.workspaceStorageListener);
9899

99100
// Create new
100101
this.workspaceStoragePath = workspaceStoragePath;
101-
this.workspaceStorage = new Storage({ path: workspaceStoragePath, logging: this.loggingOptions });
102+
this.workspaceStorage = new Storage({ path: workspaceStoragePath, createPath: !workspaceStoragePathExists, logging: this.loggingOptions });
102103
this.workspaceStorageListener = this.workspaceStorage.onDidChangeStorage(key => this.handleDidChangeStorage(key, StorageScope.WORKSPACE));
103104
}
104105

@@ -233,7 +234,7 @@ export class StorageService extends Disposable implements IStorageService {
233234
// Close workspace DB to be able to copy
234235
return this.workspaceStorage.close().then(() => {
235236
return copy(this.workspaceStoragePath, newWorkspaceStoragePath).then(() => {
236-
this.createWorkspaceStorage(newWorkspaceStoragePath);
237+
this.createWorkspaceStorage(newWorkspaceStoragePath, false);
237238

238239
return this.workspaceStorage.init();
239240
});

src/vs/platform/storage/test/node/storageService.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ suite('StorageService', () => {
8484
const storageDir = uniqueStorageDir();
8585
await mkdirp(storageDir);
8686

87-
const storage = new StorageService(join(storageDir, 'storage.db'), false, new NullLogService(), TestEnvironmentService);
87+
const storage = new StorageService(join(storageDir, 'storage.db'), false, false, new NullLogService(), TestEnvironmentService);
8888
await storage.init();
8989

9090
storage.store('bar', 'foo', StorageScope.WORKSPACE);

src/vs/platform/telemetry/test/electron-browser/commonProperties.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ suite('Telemetry - common properties', function () {
2424
let nestStorage2Service: IStorageService;
2525

2626
setup(() => {
27-
nestStorage2Service = new StorageService(':memory:', false, new NullLogService(), TestEnvironmentService);
27+
nestStorage2Service = new StorageService(':memory:', false, false, new NullLogService(), TestEnvironmentService);
2828
});
2929

3030
teardown(done => {

src/vs/workbench/electron-browser/main.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ function createStorageService(workspaceStorageFolder: string, payload: IWorkspac
284284
// Return early if we are using in-memory storage
285285
const useInMemoryStorage = !!environmentService.extensionTestsPath; /* never keep any state when running extension tests */
286286
if (useInMemoryStorage) {
287-
const storageService = new StorageService(StorageService.IN_MEMORY_PATH, true, logService, environmentService);
287+
const storageService = new StorageService(StorageService.IN_MEMORY_PATH, false, true, logService, environmentService);
288288

289289
return storageService.init().then(() => storageService);
290290
}
@@ -296,7 +296,7 @@ function createStorageService(workspaceStorageFolder: string, payload: IWorkspac
296296
return exists(workspaceStorageDBPath).then(exists => {
297297
perf.mark('didCheckWorkspaceStorageExists');
298298

299-
const storageService = new StorageService(workspaceStorageDBPath, true, logService, environmentService);
299+
const storageService = new StorageService(workspaceStorageDBPath, exists, true, logService, environmentService);
300300

301301
return storageService.init().then(() => {
302302
if (exists) {

src/vs/workbench/test/workbenchTestServices.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ export class TestPartService implements IPartService {
531531
export class TestStorageService extends StorageService {
532532

533533
constructor() {
534-
super(':memory:', false, new NullLogService(), TestEnvironmentService);
534+
super(':memory:', false, false, new NullLogService(), TestEnvironmentService);
535535
}
536536
}
537537

0 commit comments

Comments
 (0)