提交 3fb99698 编写于 作者: B Benjamin Pasero

storage - only create DB if path does not exist

上级 fd5d3ca5
......@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Database, Statement } from 'vscode-sqlite3';
import { Database, Statement, OPEN_READWRITE, OPEN_CREATE } from 'vscode-sqlite3';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import { Emitter, Event } from 'vs/base/common/event';
import { RunOnceScheduler, Queue } from 'vs/base/common/async';
......@@ -14,6 +14,7 @@ import { mark } from 'vs/base/common/performance';
export interface IStorageOptions {
path: string;
createPath: boolean;
logging?: IStorageLoggingOptions;
}
......@@ -363,18 +364,18 @@ export class SQLiteStorageImpl {
this.logger.info(`[storage ${this.name}] open()`);
return new Promise((resolve, reject) => {
this.doOpen(this.options.path).then(resolve, error => {
this.doOpen(this.options.path, this.options.createPath).then(resolve, error => {
this.logger.error(`[storage ${this.name}] open(): Error (open DB): ${error}`);
this.logger.error(`[storage ${this.name}] open(): Falling back to in-memory DB`);
// In case of any error to open the DB, use an in-memory
// DB so that we always have a valid DB to talk to.
this.doOpen(':memory:').then(resolve, reject);
this.doOpen(':memory:', true).then(resolve, reject);
});
});
}
private doOpen(path: string): Promise<Database> {
private doOpen(path: string, createPath: boolean): Promise<Database> {
return new Promise((resolve, reject) => {
let measureRequireDuration = false;
if (!SQLiteStorageImpl.measuredRequireDuration) {
......@@ -388,12 +389,17 @@ export class SQLiteStorageImpl {
mark('didRequireSQLite');
}
const db = new (this.logger.verbose ? sqlite3.verbose().Database : sqlite3.Database)(path, error => {
const db = new (this.logger.verbose ? sqlite3.verbose().Database : sqlite3.Database)(path, createPath ? OPEN_READWRITE | OPEN_CREATE : OPEN_READWRITE, error => {
if (error) {
return reject(error);
}
// Setup schema
// Return early if we did not create the DB
if (!createPath) {
return resolve(db);
}
// Otherwise: Setup schema
mark('willSetupSQLiteSchema');
this.exec(db, [
'PRAGMA user_version = 1;',
......
......@@ -23,7 +23,7 @@ suite('Storage Library', () => {
const storageDir = uniqueStorageDir();
await mkdirp(storageDir);
const storage = new Storage({ path: join(storageDir, 'storage.db') });
const storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: true });
await storage.init();
......@@ -97,7 +97,7 @@ suite('Storage Library', () => {
const storageDir = uniqueStorageDir();
await mkdirp(storageDir);
let storage = new Storage({ path: join(storageDir, 'storage.db') });
let storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: true });
await storage.init();
const set1Promise = storage.set('foo', 'bar');
......@@ -113,7 +113,7 @@ suite('Storage Library', () => {
equal(setPromiseResolved, true);
storage = new Storage({ path: join(storageDir, 'storage.db') });
storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: false });
await storage.init();
equal(storage.get('foo'), 'bar');
......@@ -121,7 +121,7 @@ suite('Storage Library', () => {
await storage.close();
storage = new Storage({ path: join(storageDir, 'storage.db') });
storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: false });
await storage.init();
const delete1Promise = storage.delete('foo');
......@@ -137,7 +137,7 @@ suite('Storage Library', () => {
equal(deletePromiseResolved, true);
storage = new Storage({ path: join(storageDir, 'storage.db') });
storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: false });
await storage.init();
ok(!storage.get('foo'));
......@@ -151,7 +151,7 @@ suite('Storage Library', () => {
const storageDir = uniqueStorageDir();
await mkdirp(storageDir);
let storage = new Storage({ path: join(storageDir, 'storage.db') });
let storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: true });
await storage.init();
let changes = new Set<string>();
......@@ -206,7 +206,7 @@ suite('SQLite Storage Library', () => {
}
async function testDBBasics(path, errorLogger?: (error) => void) {
const options: IStorageOptions = { path };
const options: IStorageOptions = { path, createPath: true };
if (errorLogger) {
options.logging = {
errorLogger
......@@ -305,7 +305,8 @@ suite('SQLite Storage Library', () => {
await mkdirp(storageDir);
let storage = new SQLiteStorageImpl({
path: join(storageDir, 'storage.db')
path: join(storageDir, 'storage.db'),
createPath: true
});
const items1 = new Map<string, string>();
......@@ -381,7 +382,8 @@ suite('SQLite Storage Library', () => {
await storage.close();
storage = new SQLiteStorageImpl({
path: join(storageDir, 'storage.db')
path: join(storageDir, 'storage.db'),
createPath: true
});
storedItems = await storage.getItems();
......@@ -398,7 +400,8 @@ suite('SQLite Storage Library', () => {
await mkdirp(storageDir);
let storage = new SQLiteStorageImpl({
path: join(storageDir, 'storage.db')
path: join(storageDir, 'storage.db'),
createPath: true
});
const items = new Map<string, string>();
......@@ -451,7 +454,7 @@ suite('SQLite Storage Library', () => {
const storageDir = uniqueStorageDir();
await mkdirp(storageDir);
const storage = new Storage({ path: join(storageDir, 'storage.db') });
const storage = new Storage({ path: join(storageDir, 'storage.db'), createPath: true });
await storage.init();
......
......@@ -61,6 +61,7 @@ export class StorageService extends Disposable implements IStorageService {
constructor(
workspaceStoragePath: string,
workspaceStoragePathExists: boolean,
disableGlobalStorage: boolean,
@ILogService logService: ILogService,
@IEnvironmentService environmentService: IEnvironmentService
......@@ -84,13 +85,13 @@ export class StorageService extends Disposable implements IStorageService {
};
this.globalStorageWorkspacePath = workspaceStoragePath === StorageService.IN_MEMORY_PATH ? StorageService.IN_MEMORY_PATH : StorageService.IN_MEMORY_PATH;
this.globalStorage = disableGlobalStorage ? new NullStorage() : new Storage({ path: this.globalStorageWorkspacePath, logging: this.loggingOptions });
this.globalStorage = disableGlobalStorage ? new NullStorage() : new Storage({ path: this.globalStorageWorkspacePath, createPath: true, logging: this.loggingOptions });
this._register(this.globalStorage.onDidChangeStorage(key => this.handleDidChangeStorage(key, StorageScope.GLOBAL)));
this.createWorkspaceStorage(workspaceStoragePath);
this.createWorkspaceStorage(workspaceStoragePath, workspaceStoragePathExists);
}
private createWorkspaceStorage(workspaceStoragePath: string): void {
private createWorkspaceStorage(workspaceStoragePath: string, workspaceStoragePathExists: boolean): void {
// Dispose old (if any)
this.workspaceStorage = dispose(this.workspaceStorage);
......@@ -98,7 +99,7 @@ export class StorageService extends Disposable implements IStorageService {
// Create new
this.workspaceStoragePath = workspaceStoragePath;
this.workspaceStorage = new Storage({ path: workspaceStoragePath, logging: this.loggingOptions });
this.workspaceStorage = new Storage({ path: workspaceStoragePath, createPath: !workspaceStoragePathExists, logging: this.loggingOptions });
this.workspaceStorageListener = this.workspaceStorage.onDidChangeStorage(key => this.handleDidChangeStorage(key, StorageScope.WORKSPACE));
}
......@@ -233,7 +234,7 @@ export class StorageService extends Disposable implements IStorageService {
// Close workspace DB to be able to copy
return this.workspaceStorage.close().then(() => {
return copy(this.workspaceStoragePath, newWorkspaceStoragePath).then(() => {
this.createWorkspaceStorage(newWorkspaceStoragePath);
this.createWorkspaceStorage(newWorkspaceStoragePath, false);
return this.workspaceStorage.init();
});
......
......@@ -84,7 +84,7 @@ suite('StorageService', () => {
const storageDir = uniqueStorageDir();
await mkdirp(storageDir);
const storage = new StorageService(join(storageDir, 'storage.db'), false, new NullLogService(), TestEnvironmentService);
const storage = new StorageService(join(storageDir, 'storage.db'), false, false, new NullLogService(), TestEnvironmentService);
await storage.init();
storage.store('bar', 'foo', StorageScope.WORKSPACE);
......
......@@ -24,7 +24,7 @@ suite('Telemetry - common properties', function () {
let nestStorage2Service: IStorageService;
setup(() => {
nestStorage2Service = new StorageService(':memory:', false, new NullLogService(), TestEnvironmentService);
nestStorage2Service = new StorageService(':memory:', false, false, new NullLogService(), TestEnvironmentService);
});
teardown(done => {
......
......@@ -284,7 +284,7 @@ function createStorageService(workspaceStorageFolder: string, payload: IWorkspac
// Return early if we are using in-memory storage
const useInMemoryStorage = !!environmentService.extensionTestsPath; /* never keep any state when running extension tests */
if (useInMemoryStorage) {
const storageService = new StorageService(StorageService.IN_MEMORY_PATH, true, logService, environmentService);
const storageService = new StorageService(StorageService.IN_MEMORY_PATH, false, true, logService, environmentService);
return storageService.init().then(() => storageService);
}
......@@ -296,7 +296,7 @@ function createStorageService(workspaceStorageFolder: string, payload: IWorkspac
return exists(workspaceStorageDBPath).then(exists => {
perf.mark('didCheckWorkspaceStorageExists');
const storageService = new StorageService(workspaceStorageDBPath, true, logService, environmentService);
const storageService = new StorageService(workspaceStorageDBPath, exists, true, logService, environmentService);
return storageService.init().then(() => {
if (exists) {
......
......@@ -531,7 +531,7 @@ export class TestPartService implements IPartService {
export class TestStorageService extends StorageService {
constructor() {
super(':memory:', false, new NullLogService(), TestEnvironmentService);
super(':memory:', false, false, new NullLogService(), TestEnvironmentService);
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册