Add database configuration store (#1691)

This "config store" creates a `dbconfig.json` file (if it doesn't yet exist),
and reads the file to load the database panel state.

Only the database config store should be able to modify the config
— the config cannot be modified externally.
This commit is contained in:
Shati Patel
2022-11-02 15:07:23 +00:00
committed by GitHub
parent 0965448c02
commit 7296c645b9
6 changed files with 148 additions and 0 deletions

View File

@@ -1,3 +1,4 @@
**/* @github/codeql-vscode-reviewers
**/remote-queries/ @github/code-scanning-secexp-reviewers
**/variant-analysis/ @github/code-scanning-secexp-reviewers
**/databases/ @github/code-scanning-secexp-reviewers

View File

@@ -0,0 +1,3 @@
### Databases
This folder contains code for the new experimental databases panel and new query run experience.

View File

@@ -0,0 +1,46 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import { cloneDbConfig, DbConfig } from './db-config';
export class DbConfigStore {
private readonly configPath: string;
private config: DbConfig;
public constructor(workspaceStoragePath: string) {
this.configPath = path.join(workspaceStoragePath, 'dbconfig.json');
this.config = this.createEmptyConfig();
}
public async initialize(): Promise<void> {
await this.loadConfig();
}
public getConfig(): DbConfig {
// Clone the config so that it's not modified outside of this class.
return cloneDbConfig(this.config);
}
private async loadConfig(): Promise<void> {
if (!await fs.pathExists(this.configPath)) {
await fs.writeJSON(this.configPath, this.createEmptyConfig(), { spaces: 2 });
}
await this.readConfig();
}
private async readConfig(): Promise<void> {
this.config = await fs.readJSON(this.configPath);
}
private createEmptyConfig(): DbConfig {
return {
remote: {
repositoryLists: [],
owners: [],
repositories: [],
}
};
}
}

View File

@@ -0,0 +1,29 @@
// Contains models for the data we want to store in the database config
export interface DbConfig {
remote: RemoteDbConfig;
}
export interface RemoteDbConfig {
repositoryLists: RemoteRepositoryList[];
owners: string[];
repositories: string[];
}
export interface RemoteRepositoryList {
name: string;
repositories: string[];
}
export function cloneDbConfig(config: DbConfig): DbConfig {
return {
remote: {
repositoryLists: config.remote.repositoryLists.map((list) => ({
name: list.name,
repositories: [...list.repositories],
})),
owners: [...config.remote.owners],
repositories: [...config.remote.repositories],
}
};
}

View File

@@ -0,0 +1,12 @@
{
"remote": {
"repositoryLists": [
{
"name": "repoList1",
"repositories": ["foo/bar", "foo/baz"]
}
],
"owners": [],
"repositories": ["owner/repo1", "owner/repo2", "owner/repo3"]
}
}

View File

@@ -0,0 +1,57 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import { DbConfigStore } from '../../../src/databases/db-config-store';
import { expect } from 'chai';
describe('db config store', async () => {
const workspaceStoragePath = path.join(__dirname, 'test-workspace');
const testStoragePath = path.join(__dirname, 'data');
beforeEach(async () => {
await fs.ensureDir(workspaceStoragePath);
});
afterEach(async () => {
await fs.remove(workspaceStoragePath);
});
it('should create a new config if one does not exist', async () => {
const configPath = path.join(workspaceStoragePath, 'dbconfig.json');
const configStore = new DbConfigStore(workspaceStoragePath);
await configStore.initialize();
expect(await fs.pathExists(configPath)).to.be.true;
const config = configStore.getConfig();
expect(config.remote.repositoryLists).to.be.empty;
expect(config.remote.owners).to.be.empty;
expect(config.remote.repositories).to.be.empty;
});
it('should load an existing config', async () => {
const configStore = new DbConfigStore(testStoragePath);
await configStore.initialize();
const config = configStore.getConfig();
expect(config.remote.repositoryLists).to.have.length(1);
expect(config.remote.repositoryLists[0]).to.deep.equal({
'name': 'repoList1',
'repositories': ['foo/bar', 'foo/baz']
});
expect(config.remote.owners).to.be.empty;
expect(config.remote.repositories).to.have.length(3);
expect(config.remote.repositories).to.deep.equal(['owner/repo1', 'owner/repo2', 'owner/repo3']);
});
it('should not allow modification of the config', async () => {
const configStore = new DbConfigStore(testStoragePath);
await configStore.initialize();
const config = configStore.getConfig();
config.remote.repositoryLists = [];
const reRetrievedConfig = configStore.getConfig();
expect(reRetrievedConfig.remote.repositoryLists).to.have.length(1);
});
});