Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 99 additions & 1 deletion extensions/ql-vscode/src/databases/config/db-config-store.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
import { pathExists, outputJSON, readJSON, readJSONSync } from "fs-extra";
import { join } from "path";
import { cloneDbConfig, DbConfig, SelectedDbItem } from "./db-config";
import {
cloneDbConfig,
DbConfig,
renameLocalDb,
renameLocalList,
renameRemoteList,
SelectedDbItem,
} from "./db-config";
import * as chokidar from "chokidar";
import { DisposableObject, DisposeHandler } from "../../pure/disposable-object";
import { DbConfigValidator } from "./db-config-validator";
Expand All @@ -11,6 +18,11 @@ import {
DbConfigValidationErrorKind,
} from "../db-validation-errors";
import { ValueResult } from "../../common/value-result";
import {
LocalDatabaseDbItem,
LocalListDbItem,
RemoteUserDefinedListDbItem,
} from "../db-item";

export class DbConfigStore extends DisposableObject {
public readonly onDidChangeConfig: AppEvent<void>;
Expand Down Expand Up @@ -161,6 +173,65 @@ export class DbConfigStore extends DisposableObject {
await this.writeConfig(config);
}

public async renameLocalList(
currentDbItem: LocalListDbItem,
newName: string,
) {
if (!this.config) {
throw Error("Cannot rename local list if config is not loaded");
}

this.validateLocalListName(newName);

const updatedConfig = renameLocalList(
this.config,
currentDbItem.listName,
newName,
);

await this.writeConfig(updatedConfig);
}

public async renameRemoteList(
currentDbItem: RemoteUserDefinedListDbItem,
newName: string,
) {
if (!this.config) {
throw Error("Cannot rename remote list if config is not loaded");
}

this.validateRemoteListName(newName);

const updatedConfig = renameRemoteList(
this.config,
currentDbItem.listName,
newName,
);

await this.writeConfig(updatedConfig);
}

public async renameLocalDb(
currentDbItem: LocalDatabaseDbItem,
newName: string,
parentListName?: string,
): Promise<void> {
if (!this.config) {
throw Error("Cannot rename local db if config is not loaded");
}

this.validateLocalDbName(newName);

const updatedConfig = renameLocalDb(
this.config,
currentDbItem.databaseName,
newName,
parentListName,
);

await this.writeConfig(updatedConfig);
}

public doesRemoteListExist(listName: string): boolean {
if (!this.config) {
throw Error("Cannot check remote list existence if config is not loaded");
Expand All @@ -179,6 +250,23 @@ export class DbConfigStore extends DisposableObject {
return this.config.databases.local.lists.some((l) => l.name === listName);
}

public doesLocalDbExist(dbName: string, listName?: string): boolean {
if (!this.config) {
throw Error(
"Cannot check remote database existence if config is not loaded",
);
}

if (listName) {
return this.config.databases.local.lists.some(
(l) =>
l.name === listName && l.databases.some((d) => d.name === dbName),
);
}

return this.config.databases.local.databases.some((d) => d.name === dbName);
}

public doesRemoteDbExist(dbName: string, listName?: string): boolean {
if (!this.config) {
throw Error(
Expand Down Expand Up @@ -344,4 +432,14 @@ export class DbConfigStore extends DisposableObject {
throw Error(`A remote list with the name '${listName}' already exists`);
}
}

private validateLocalDbName(dbName: string): void {
if (dbName === "") {
throw Error("Database name cannot be empty");
}

if (this.doesLocalDbExist(dbName)) {
throw Error(`A local database with the name '${dbName}' already exists`);
}
}
}
96 changes: 96 additions & 0 deletions extensions/ql-vscode/src/databases/config/db-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,102 @@ export function cloneDbConfig(config: DbConfig): DbConfig {
};
}

export function renameLocalList(
originalConfig: DbConfig,
currentListName: string,
newListName: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);

const list = config.databases.local.lists.find(
(l) => l.name === currentListName,
);
if (!list) {
throw Error(`Cannot find list '${currentListName}' to rename`);
}
list.name = newListName;

if (
config.selected?.kind === SelectedDbItemKind.LocalUserDefinedList ||
config.selected?.kind === SelectedDbItemKind.LocalDatabase
) {
if (config.selected.listName === currentListName) {
config.selected.listName = newListName;
}
}
Comment thread
charisk marked this conversation as resolved.

return config;
}

export function renameRemoteList(
originalConfig: DbConfig,
currentListName: string,
newListName: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);

const list = config.databases.remote.repositoryLists.find(
(l) => l.name === currentListName,
);
if (!list) {
throw Error(`Cannot find list '${currentListName}' to rename`);
}
list.name = newListName;

if (
config.selected?.kind === SelectedDbItemKind.RemoteUserDefinedList ||
config.selected?.kind === SelectedDbItemKind.RemoteRepository
) {
if (config.selected.listName === currentListName) {
config.selected.listName = newListName;
}
}

return config;
}

export function renameLocalDb(
originalConfig: DbConfig,
currentDbName: string,
newDbName: string,
parentListName?: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);

if (parentListName) {
const list = config.databases.local.lists.find(
(l) => l.name === parentListName,
);
if (!list) {
throw Error(`Cannot find parent list '${parentListName}'`);
}
const dbIndex = list.databases.findIndex((db) => db.name === currentDbName);
if (dbIndex === -1) {
throw Error(
`Cannot find database '${currentDbName}' in list '${parentListName}'`,
);
}
list.databases[dbIndex].name = newDbName;
} else {
const dbIndex = config.databases.local.databases.findIndex(
(db) => db.name === currentDbName,
);
if (dbIndex === -1) {
throw Error(`Cannot find database '${currentDbName}' in local databases`);
}
config.databases.local.databases[dbIndex].name = newDbName;
}

if (
config.selected?.kind === SelectedDbItemKind.LocalDatabase &&
config.selected.databaseName === currentDbName
) {
config.selected.databaseName = newDbName;
}

return config;
}

function cloneDbConfigSelectedItem(selected: SelectedDbItem): SelectedDbItem {
switch (selected.kind) {
case SelectedDbItemKind.LocalUserDefinedList:
Expand Down
Loading