Refactor logic to remove db or list from config (#1946)

This commit is contained in:
Charis Kyriakou
2023-01-11 08:41:58 +00:00
committed by GitHub
parent 9cf508837e
commit 0b6f2c248b
4 changed files with 586 additions and 133 deletions

View File

@@ -3,11 +3,15 @@ import { join } from "path";
import {
cloneDbConfig,
DbConfig,
removeLocalDb,
removeLocalList,
removeRemoteList,
removeRemoteOwner,
removeRemoteRepo,
renameLocalDb,
renameLocalList,
renameRemoteList,
SelectedDbItem,
SelectedDbItemKind,
} from "./db-config";
import * as chokidar from "chokidar";
import { DisposableObject, DisposeHandler } from "../../pure/disposable-object";
@@ -26,10 +30,6 @@ import {
DbItem,
DbItemKind,
} from "../db-item";
import {
compareSelectedKindIsEqual,
mapDbItemToSelectedDbItem,
} from "../db-item-selection";
export class DbConfigStore extends DisposableObject {
public readonly onDidChangeConfig: AppEvent<void>;
@@ -87,7 +87,7 @@ export class DbConfigStore extends DisposableObject {
throw Error("Cannot select database item if config is not loaded");
}
const config: DbConfig = {
const config = {
...this.config,
selected: dbItem,
};
@@ -100,88 +100,37 @@ export class DbConfigStore extends DisposableObject {
throw Error("Cannot remove item if config is not loaded");
}
const config = cloneDbConfig(this.config);
const selectedItem: SelectedDbItem | undefined = config.selected;
let config: DbConfig;
// Remove item from databases
switch (dbItem.kind) {
case DbItemKind.LocalList:
config.databases.local.lists = config.databases.local.lists.filter(
(list) => list.name !== dbItem.listName,
);
config = removeLocalList(this.config, dbItem.listName);
break;
case DbItemKind.RemoteUserDefinedList:
config.databases.remote.repositoryLists =
config.databases.remote.repositoryLists.filter(
(list) => list.name !== dbItem.listName,
);
config = removeRemoteList(this.config, dbItem.listName);
break;
case DbItemKind.LocalDatabase:
// When we start using local databases these need to be removed from disk as well.
if (dbItem.parentListName) {
const parent = config.databases.local.lists.find(
(list) => list.name === dbItem.parentListName,
);
if (!parent) {
throw Error(`Cannot find parent list '${dbItem.parentListName}'`);
} else {
parent.databases = parent.databases.filter(
(db) => db.name !== dbItem.databaseName,
);
}
}
config.databases.local.databases =
config.databases.local.databases.filter(
(db) => db.name !== dbItem.databaseName,
);
config = removeLocalDb(
this.config,
dbItem.databaseName,
dbItem.parentListName,
);
break;
case DbItemKind.RemoteRepo:
if (dbItem.parentListName) {
const parent = config.databases.remote.repositoryLists.find(
(list) => list.name === dbItem.parentListName,
);
if (!parent) {
throw Error(`Cannot find parent list '${dbItem.parentListName}'`);
} else {
parent.repositories = parent.repositories.filter(
(repo) => repo !== dbItem.repoFullName,
);
}
}
config.databases.remote.repositories =
config.databases.remote.repositories.filter(
(repo) => repo !== dbItem.repoFullName,
);
config = removeRemoteRepo(
this.config,
dbItem.repoFullName,
dbItem.parentListName,
);
break;
case DbItemKind.RemoteOwner:
config.databases.remote.owners = config.databases.remote.owners.filter(
(owner) => owner !== dbItem.ownerName,
);
config = removeRemoteOwner(this.config, dbItem.ownerName);
break;
default:
throw Error(`Type '${dbItem.kind}' cannot be removed`);
}
// Remove item from selected
const removedItem = mapDbItemToSelectedDbItem(dbItem);
if (selectedItem && removedItem) {
// if removedItem has a parentList, check if parentList is selectedItem
if (
removedItem.kind === SelectedDbItemKind.LocalUserDefinedList ||
removedItem.kind === SelectedDbItemKind.RemoteUserDefinedList
) {
if (
(selectedItem.kind === SelectedDbItemKind.LocalDatabase ||
selectedItem.kind === SelectedDbItemKind.RemoteRepository) &&
removedItem.listName === selectedItem.listName
) {
config.selected = undefined;
}
}
if (compareSelectedKindIsEqual(removedItem, selectedItem)) {
config.selected = undefined;
}
}
await this.writeConfig(config);
}

View File

@@ -121,12 +121,7 @@ export function renameLocalList(
): 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`);
}
const list = getLocalList(config, currentListName);
list.name = newListName;
if (
@@ -148,12 +143,7 @@ export function renameRemoteList(
): 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`);
}
const list = getRemoteList(config, currentListName);
list.name = newListName;
if (
@@ -177,12 +167,7 @@ export function renameLocalDb(
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 list = getLocalList(config, parentListName);
const dbIndex = list.databases.findIndex((db) => db.name === currentDbName);
if (dbIndex === -1) {
throw Error(
@@ -210,6 +195,132 @@ export function renameLocalDb(
return config;
}
export function removeLocalList(
originalConfig: DbConfig,
listName: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
config.databases.local.lists = config.databases.local.lists.filter(
(list) => list.name !== listName,
);
if (config.selected?.kind === SelectedDbItemKind.LocalUserDefinedList) {
config.selected = undefined;
}
if (
config.selected?.kind === SelectedDbItemKind.LocalDatabase &&
config.selected?.listName === listName
) {
config.selected = undefined;
}
return config;
}
export function removeRemoteList(
originalConfig: DbConfig,
listName: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
config.databases.remote.repositoryLists =
config.databases.remote.repositoryLists.filter(
(list) => list.name !== listName,
);
if (config.selected?.kind === SelectedDbItemKind.RemoteUserDefinedList) {
config.selected = undefined;
}
if (
config.selected?.kind === SelectedDbItemKind.RemoteRepository &&
config.selected?.listName === listName
) {
config.selected = undefined;
}
return config;
}
export function removeLocalDb(
originalConfig: DbConfig,
databaseName: string,
parentListName?: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
if (parentListName) {
const parentList = getLocalList(config, parentListName);
parentList.databases = parentList.databases.filter(
(db) => db.name !== databaseName,
);
} else {
config.databases.local.databases = config.databases.local.databases.filter(
(db) => db.name !== databaseName,
);
}
if (
config.selected?.kind === SelectedDbItemKind.LocalDatabase &&
config.selected?.databaseName === databaseName &&
config.selected?.listName === parentListName
) {
config.selected = undefined;
}
return config;
}
export function removeRemoteRepo(
originalConfig: DbConfig,
repoFullName: string,
parentListName?: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
if (parentListName) {
const parentList = getRemoteList(config, parentListName);
parentList.repositories = parentList.repositories.filter(
(r) => r !== repoFullName,
);
} else {
config.databases.remote.repositories =
config.databases.remote.repositories.filter((r) => r !== repoFullName);
}
if (
config.selected?.kind === SelectedDbItemKind.RemoteRepository &&
config.selected?.repositoryName === repoFullName &&
config.selected?.listName === parentListName
) {
config.selected = undefined;
}
return config;
}
export function removeRemoteOwner(
originalConfig: DbConfig,
ownerName: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
config.databases.remote.owners = config.databases.remote.owners.filter(
(o) => o !== ownerName,
);
if (
config.selected?.kind === SelectedDbItemKind.RemoteOwner &&
config.selected?.ownerName === ownerName
) {
config.selected = undefined;
}
return config;
}
function cloneDbConfigSelectedItem(selected: SelectedDbItem): SelectedDbItem {
switch (selected.kind) {
case SelectedDbItemKind.LocalUserDefinedList:
@@ -246,3 +357,28 @@ function cloneDbConfigSelectedItem(selected: SelectedDbItem): SelectedDbItem {
};
}
}
function getLocalList(config: DbConfig, listName: string): LocalList {
const list = config.databases.local.lists.find((l) => l.name === listName);
if (!list) {
throw Error(`Cannot find local list '${listName}'`);
}
return list;
}
function getRemoteList(
config: DbConfig,
listName: string,
): RemoteRepositoryList {
const list = config.databases.remote.repositoryLists.find(
(l) => l.name === listName,
);
if (!list) {
throw Error(`Cannot find remote list '${listName}'`);
}
return list;
}

View File

@@ -1,12 +1,5 @@
import { DbItem, DbItemKind, LocalDbItem, RemoteDbItem } from "./db-item";
import {
SelectedDbItem,
SelectedDbItemKind,
SelectedLocalDatabase,
SelectedLocalUserDefinedList,
SelectedRemoteOwner,
SelectedRemoteRepository,
} from "./config/db-config";
import { SelectedDbItem, SelectedDbItemKind } from "./config/db-config";
export function getSelectedDbItem(dbItems: DbItem[]): DbItem | undefined {
for (const dbItem of dbItems) {
@@ -99,39 +92,3 @@ export function mapDbItemToSelectedDbItem(
};
}
}
export function compareSelectedKindIsEqual(
item1: SelectedDbItem,
item2: SelectedDbItem,
): boolean {
if (item1.kind === item2.kind) {
switch (item1.kind) {
case SelectedDbItemKind.LocalUserDefinedList:
case SelectedDbItemKind.RemoteUserDefinedList:
case SelectedDbItemKind.RemoteSystemDefinedList:
return (
item1.listName === (item2 as SelectedLocalUserDefinedList).listName
);
case SelectedDbItemKind.RemoteOwner:
return item1.ownerName === (item2 as SelectedRemoteOwner).ownerName;
case SelectedDbItemKind.LocalDatabase: {
const selectedItem = item2 as SelectedLocalDatabase;
return (
item1.databaseName === selectedItem.databaseName &&
item1.listName === selectedItem.listName
);
}
case SelectedDbItemKind.RemoteRepository: {
const selectedItem = item2 as SelectedRemoteRepository;
return (
item1.repositoryName === selectedItem.repositoryName &&
item1.listName === selectedItem.listName
);
}
default:
return false;
}
} else {
return false;
}
}

View File

@@ -1,5 +1,11 @@
import {
LocalList,
RemoteRepositoryList,
removeLocalDb,
removeLocalList,
removeRemoteList,
removeRemoteOwner,
removeRemoteRepo,
renameLocalDb,
renameLocalList,
renameRemoteList,
@@ -360,4 +366,409 @@ describe("db config", () => {
expect(updatedLocalDbs.databases[1]).toEqual(db2);
});
});
describe("removeLocalList", () => {
it("should remove a local list", () => {
const originalConfig = createDbConfig({
localLists: [
{
name: "list1",
databases: [],
},
{
name: "list2",
databases: [],
},
],
});
const updatedConfig = removeLocalList(originalConfig, "list1");
expect(updatedConfig.databases.local.lists).toEqual([
{
name: "list2",
databases: [],
},
]);
});
it("should remove a selected local list", () => {
const originalConfig = createDbConfig({
localLists: [
{
name: "list1",
databases: [],
},
{
name: "list2",
databases: [],
},
],
selected: {
kind: SelectedDbItemKind.LocalUserDefinedList,
listName: "list1",
},
});
const updatedConfig = removeLocalList(originalConfig, "list1");
expect(updatedConfig.databases.local.lists).toEqual([
{
name: "list2",
databases: [],
},
]);
expect(updatedConfig.selected).toBeUndefined();
});
it("should remove a local list with a db that is selected", () => {
const selectedLocalDb = createLocalDbConfigItem();
const list1: LocalList = {
name: "list1",
databases: [
createLocalDbConfigItem(),
selectedLocalDb,
createLocalDbConfigItem(),
],
};
const list2: LocalList = {
name: "list2",
databases: [],
};
const originalConfig = createDbConfig({
localLists: [list1, list2],
selected: {
kind: SelectedDbItemKind.LocalDatabase,
databaseName: selectedLocalDb.name,
listName: list1.name,
},
});
const updatedConfig = removeLocalList(originalConfig, list1.name);
expect(updatedConfig.databases.local.lists.length).toEqual(1);
expect(updatedConfig.databases.local.lists[0]).toEqual(list2);
expect(updatedConfig.selected).toBeUndefined();
});
});
describe("removeRemoteList", () => {
it("should remove a remote list", () => {
const originalConfig = createDbConfig({
remoteLists: [
{
name: "list1",
repositories: [],
},
{
name: "list2",
repositories: [],
},
],
});
const updatedConfig = removeRemoteList(originalConfig, "list1");
expect(updatedConfig.databases.remote.repositoryLists).toEqual([
{
name: "list2",
repositories: [],
},
]);
});
it("should remove a selected remote list", () => {
const originalConfig = createDbConfig({
remoteLists: [
{
name: "list1",
repositories: [],
},
{
name: "list2",
repositories: [],
},
],
selected: {
kind: SelectedDbItemKind.RemoteUserDefinedList,
listName: "list1",
},
});
const updatedConfig = removeRemoteList(originalConfig, "list1");
expect(updatedConfig.databases.remote.repositoryLists).toEqual([
{
name: "list2",
repositories: [],
},
]);
expect(updatedConfig.selected).toBeUndefined();
});
it("should remove a remote list with a db that is selected", () => {
const selectedRemoteRepo = "owner/repo2";
const originalConfig = createDbConfig({
remoteLists: [
{
name: "list1",
repositories: ["owner1/repo1", selectedRemoteRepo, "owner1/repo3"],
},
{
name: "list2",
repositories: [],
},
],
selected: {
kind: SelectedDbItemKind.RemoteRepository,
repositoryName: selectedRemoteRepo,
listName: "list1",
},
});
const updatedConfig = removeRemoteList(originalConfig, "list1");
const updatedRepositoryLists =
updatedConfig.databases.remote.repositoryLists;
expect(updatedRepositoryLists.length).toEqual(1);
expect(updatedRepositoryLists[0]).toEqual(
originalConfig.databases.remote.repositoryLists[1],
);
expect(updatedConfig.selected).toBeUndefined();
});
});
describe("removeLocalDb", () => {
it("should remove a local db", () => {
const db1 = createLocalDbConfigItem({ name: "db1" });
const db2 = createLocalDbConfigItem({ name: "db2" });
const originalConfig = createDbConfig({
localLists: [
{
name: "list1",
databases: [
createLocalDbConfigItem({ name: "db1" }),
createLocalDbConfigItem({ name: "db2" }),
],
},
],
localDbs: [db1, db2],
});
const updatedConfig = renameLocalDb(originalConfig, "db1", "dbRenamed");
const updatedLocalDbs = updatedConfig.databases.local;
const originalLocalDbs = originalConfig.databases.local;
expect(updatedLocalDbs.lists).toEqual(originalLocalDbs.lists);
expect(updatedLocalDbs.databases.length).toEqual(2);
expect(updatedLocalDbs.databases[0]).toEqual({
...db1,
name: "dbRenamed",
});
expect(updatedLocalDbs.databases[1]).toEqual(db2);
});
it("should remove a local db inside a list", () => {
const db1List1 = createLocalDbConfigItem({ name: "db1" });
const db2List1 = createLocalDbConfigItem({ name: "db2" });
const originalConfig = createDbConfig({
localLists: [
{
name: "list1",
databases: [db1List1, db2List1],
},
{
name: "list2",
databases: [
createLocalDbConfigItem({ name: "db1" }),
createLocalDbConfigItem({ name: "db2" }),
],
},
],
localDbs: [
createLocalDbConfigItem({ name: "db1" }),
createLocalDbConfigItem({ name: "db2" }),
],
});
const updatedConfig = removeLocalDb(
originalConfig,
db1List1.name,
"list1",
);
const updatedLocalDbs = updatedConfig.databases.local;
const originalLocalDbs = originalConfig.databases.local;
expect(updatedLocalDbs.databases).toEqual(originalLocalDbs.databases);
expect(updatedLocalDbs.lists.length).toEqual(2);
expect(updatedLocalDbs.lists[0].databases.length).toEqual(1);
expect(updatedLocalDbs.lists[0].databases[0]).toEqual(db2List1);
expect(updatedLocalDbs.lists[1]).toEqual(originalLocalDbs.lists[1]);
});
it("should remove a local db that is selected", () => {
const db1 = createLocalDbConfigItem({ name: "db1" });
const db2 = createLocalDbConfigItem({ name: "db2" });
const originalConfig = createDbConfig({
localLists: [
{
name: "list1",
databases: [
createLocalDbConfigItem({ name: "db1" }),
createLocalDbConfigItem({ name: "db2" }),
],
},
],
localDbs: [db1, db2],
selected: {
kind: SelectedDbItemKind.LocalDatabase,
databaseName: "db1",
},
});
const updatedConfig = removeLocalDb(originalConfig, "db1");
const updatedLocalDbs = updatedConfig.databases.local;
const originalLocalDbs = originalConfig.databases.local;
expect(updatedLocalDbs.lists).toEqual(originalLocalDbs.lists);
expect(updatedLocalDbs.databases.length).toEqual(1);
expect(updatedLocalDbs.databases[0]).toEqual(db2);
});
});
describe("removeRemoteRepo", () => {
it("should remove a remote repo", () => {
const repo1 = "owner1/repo1";
const repo2 = "owner1/repo2";
const originalConfig = createDbConfig({
remoteLists: [
{
name: "list1",
repositories: [repo1, repo2],
},
],
remoteRepos: [repo1, repo2],
});
const updatedConfig = removeRemoteRepo(originalConfig, repo1);
const updatedRemoteDbs = updatedConfig.databases.remote;
const originalRemoteDbs = originalConfig.databases.remote;
expect(updatedRemoteDbs.repositories.length).toEqual(1);
expect(updatedRemoteDbs.repositories[0]).toEqual(repo2);
expect(updatedRemoteDbs.repositoryLists).toEqual(
originalRemoteDbs.repositoryLists,
);
});
it("should remove a remote repo inside a list", () => {
const repo1 = "owner1/repo1";
const repo2 = "owner1/repo2";
const list1: RemoteRepositoryList = {
name: "list1",
repositories: [repo1, repo2],
};
const list2: RemoteRepositoryList = {
name: "list2",
repositories: [repo1, repo2],
};
const originalConfig = createDbConfig({
remoteLists: [list1, list2],
remoteRepos: [repo1, repo2],
});
const updatedConfig = removeRemoteRepo(originalConfig, repo1, list1.name);
const updatedRemoteDbs = updatedConfig.databases.remote;
const originalRemoteDbs = originalConfig.databases.remote;
expect(updatedRemoteDbs.repositories).toEqual(
originalRemoteDbs.repositories,
);
expect(updatedRemoteDbs.repositoryLists.length).toEqual(2);
expect(updatedRemoteDbs.repositoryLists[0].repositories.length).toEqual(
1,
);
expect(updatedRemoteDbs.repositoryLists[0].repositories[0]).toEqual(
repo2,
);
expect(updatedRemoteDbs.repositoryLists[1]).toEqual(
originalRemoteDbs.repositoryLists[1],
);
});
it("should remove a remote repo that is selected", () => {
const repo1 = "owner1/repo1";
const repo2 = "owner1/repo2";
const originalConfig = createDbConfig({
remoteLists: [
{
name: "list1",
repositories: [repo1, repo2],
},
],
remoteRepos: [repo1, repo2],
selected: {
kind: SelectedDbItemKind.RemoteRepository,
repositoryName: repo1,
},
});
const updatedConfig = removeRemoteRepo(originalConfig, repo1);
const updatedRemoteDbs = updatedConfig.databases.remote;
const originalRemoteDbs = originalConfig.databases.remote;
expect(updatedRemoteDbs.repositories.length).toEqual(1);
expect(updatedRemoteDbs.repositories[0]).toEqual(repo2);
expect(updatedRemoteDbs.repositoryLists).toEqual(
originalRemoteDbs.repositoryLists,
);
expect(updatedConfig.selected).toBeUndefined();
});
});
describe("removeOwner", () => {
it("should remove a remote owner", () => {
const owner1 = "owner1";
const owner2 = "owner2";
const originalConfig = createDbConfig({
remoteOwners: [owner1, owner2],
});
const updatedConfig = removeRemoteOwner(originalConfig, owner1);
const updatedRemoteDbs = updatedConfig.databases.remote;
expect(updatedRemoteDbs.owners).toEqual([owner2]);
});
it("should remove a remote owner that is selected", () => {
const owner1 = "owner1";
const owner2 = "owner2";
const originalConfig = createDbConfig({
remoteOwners: [owner1, owner2],
selected: {
kind: SelectedDbItemKind.RemoteOwner,
ownerName: owner1,
},
});
const updatedConfig = removeRemoteOwner(originalConfig, owner1);
const updatedRemoteDbs = updatedConfig.databases.remote;
expect(updatedRemoteDbs.owners).toEqual([owner2]);
expect(updatedConfig.selected).toBeUndefined();
});
});
});