Skip to content

Commit afc6ce5

Browse files
authored
Merge pull request #1926 from github/charisk/db-config-store-rename
Add db and list rename functionality to db config store
2 parents 3227935 + db9bc5b commit afc6ce5

4 files changed

Lines changed: 757 additions & 2 deletions

File tree

extensions/ql-vscode/src/databases/config/db-config-store.ts

Lines changed: 99 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { pathExists, outputJSON, readJSON, readJSONSync } from "fs-extra";
22
import { join } from "path";
3-
import { cloneDbConfig, DbConfig, SelectedDbItem } from "./db-config";
3+
import {
4+
cloneDbConfig,
5+
DbConfig,
6+
renameLocalDb,
7+
renameLocalList,
8+
renameRemoteList,
9+
SelectedDbItem,
10+
} from "./db-config";
411
import * as chokidar from "chokidar";
512
import { DisposableObject, DisposeHandler } from "../../pure/disposable-object";
613
import { DbConfigValidator } from "./db-config-validator";
@@ -11,6 +18,11 @@ import {
1118
DbConfigValidationErrorKind,
1219
} from "../db-validation-errors";
1320
import { ValueResult } from "../../common/value-result";
21+
import {
22+
LocalDatabaseDbItem,
23+
LocalListDbItem,
24+
RemoteUserDefinedListDbItem,
25+
} from "../db-item";
1426

1527
export class DbConfigStore extends DisposableObject {
1628
public readonly onDidChangeConfig: AppEvent<void>;
@@ -161,6 +173,65 @@ export class DbConfigStore extends DisposableObject {
161173
await this.writeConfig(config);
162174
}
163175

176+
public async renameLocalList(
177+
currentDbItem: LocalListDbItem,
178+
newName: string,
179+
) {
180+
if (!this.config) {
181+
throw Error("Cannot rename local list if config is not loaded");
182+
}
183+
184+
this.validateLocalListName(newName);
185+
186+
const updatedConfig = renameLocalList(
187+
this.config,
188+
currentDbItem.listName,
189+
newName,
190+
);
191+
192+
await this.writeConfig(updatedConfig);
193+
}
194+
195+
public async renameRemoteList(
196+
currentDbItem: RemoteUserDefinedListDbItem,
197+
newName: string,
198+
) {
199+
if (!this.config) {
200+
throw Error("Cannot rename remote list if config is not loaded");
201+
}
202+
203+
this.validateRemoteListName(newName);
204+
205+
const updatedConfig = renameRemoteList(
206+
this.config,
207+
currentDbItem.listName,
208+
newName,
209+
);
210+
211+
await this.writeConfig(updatedConfig);
212+
}
213+
214+
public async renameLocalDb(
215+
currentDbItem: LocalDatabaseDbItem,
216+
newName: string,
217+
parentListName?: string,
218+
): Promise<void> {
219+
if (!this.config) {
220+
throw Error("Cannot rename local db if config is not loaded");
221+
}
222+
223+
this.validateLocalDbName(newName);
224+
225+
const updatedConfig = renameLocalDb(
226+
this.config,
227+
currentDbItem.databaseName,
228+
newName,
229+
parentListName,
230+
);
231+
232+
await this.writeConfig(updatedConfig);
233+
}
234+
164235
public doesRemoteListExist(listName: string): boolean {
165236
if (!this.config) {
166237
throw Error("Cannot check remote list existence if config is not loaded");
@@ -179,6 +250,23 @@ export class DbConfigStore extends DisposableObject {
179250
return this.config.databases.local.lists.some((l) => l.name === listName);
180251
}
181252

253+
public doesLocalDbExist(dbName: string, listName?: string): boolean {
254+
if (!this.config) {
255+
throw Error(
256+
"Cannot check remote database existence if config is not loaded",
257+
);
258+
}
259+
260+
if (listName) {
261+
return this.config.databases.local.lists.some(
262+
(l) =>
263+
l.name === listName && l.databases.some((d) => d.name === dbName),
264+
);
265+
}
266+
267+
return this.config.databases.local.databases.some((d) => d.name === dbName);
268+
}
269+
182270
public doesRemoteDbExist(dbName: string, listName?: string): boolean {
183271
if (!this.config) {
184272
throw Error(
@@ -344,4 +432,14 @@ export class DbConfigStore extends DisposableObject {
344432
throw Error(`A remote list with the name '${listName}' already exists`);
345433
}
346434
}
435+
436+
private validateLocalDbName(dbName: string): void {
437+
if (dbName === "") {
438+
throw Error("Database name cannot be empty");
439+
}
440+
441+
if (this.doesLocalDbExist(dbName)) {
442+
throw Error(`A local database with the name '${dbName}' already exists`);
443+
}
444+
}
347445
}

extensions/ql-vscode/src/databases/config/db-config.ts

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,102 @@ export function cloneDbConfig(config: DbConfig): DbConfig {
114114
};
115115
}
116116

117+
export function renameLocalList(
118+
originalConfig: DbConfig,
119+
currentListName: string,
120+
newListName: string,
121+
): DbConfig {
122+
const config = cloneDbConfig(originalConfig);
123+
124+
const list = config.databases.local.lists.find(
125+
(l) => l.name === currentListName,
126+
);
127+
if (!list) {
128+
throw Error(`Cannot find list '${currentListName}' to rename`);
129+
}
130+
list.name = newListName;
131+
132+
if (
133+
config.selected?.kind === SelectedDbItemKind.LocalUserDefinedList ||
134+
config.selected?.kind === SelectedDbItemKind.LocalDatabase
135+
) {
136+
if (config.selected.listName === currentListName) {
137+
config.selected.listName = newListName;
138+
}
139+
}
140+
141+
return config;
142+
}
143+
144+
export function renameRemoteList(
145+
originalConfig: DbConfig,
146+
currentListName: string,
147+
newListName: string,
148+
): DbConfig {
149+
const config = cloneDbConfig(originalConfig);
150+
151+
const list = config.databases.remote.repositoryLists.find(
152+
(l) => l.name === currentListName,
153+
);
154+
if (!list) {
155+
throw Error(`Cannot find list '${currentListName}' to rename`);
156+
}
157+
list.name = newListName;
158+
159+
if (
160+
config.selected?.kind === SelectedDbItemKind.RemoteUserDefinedList ||
161+
config.selected?.kind === SelectedDbItemKind.RemoteRepository
162+
) {
163+
if (config.selected.listName === currentListName) {
164+
config.selected.listName = newListName;
165+
}
166+
}
167+
168+
return config;
169+
}
170+
171+
export function renameLocalDb(
172+
originalConfig: DbConfig,
173+
currentDbName: string,
174+
newDbName: string,
175+
parentListName?: string,
176+
): DbConfig {
177+
const config = cloneDbConfig(originalConfig);
178+
179+
if (parentListName) {
180+
const list = config.databases.local.lists.find(
181+
(l) => l.name === parentListName,
182+
);
183+
if (!list) {
184+
throw Error(`Cannot find parent list '${parentListName}'`);
185+
}
186+
const dbIndex = list.databases.findIndex((db) => db.name === currentDbName);
187+
if (dbIndex === -1) {
188+
throw Error(
189+
`Cannot find database '${currentDbName}' in list '${parentListName}'`,
190+
);
191+
}
192+
list.databases[dbIndex].name = newDbName;
193+
} else {
194+
const dbIndex = config.databases.local.databases.findIndex(
195+
(db) => db.name === currentDbName,
196+
);
197+
if (dbIndex === -1) {
198+
throw Error(`Cannot find database '${currentDbName}' in local databases`);
199+
}
200+
config.databases.local.databases[dbIndex].name = newDbName;
201+
}
202+
203+
if (
204+
config.selected?.kind === SelectedDbItemKind.LocalDatabase &&
205+
config.selected.databaseName === currentDbName
206+
) {
207+
config.selected.databaseName = newDbName;
208+
}
209+
210+
return config;
211+
}
212+
117213
function cloneDbConfigSelectedItem(selected: SelectedDbItem): SelectedDbItem {
118214
switch (selected.kind) {
119215
case SelectedDbItemKind.LocalUserDefinedList:

0 commit comments

Comments
 (0)