Skip to content

Commit

Permalink
Merge pull request #1046 from mittwald/feat/database-list-command
Browse files Browse the repository at this point in the history
feat: add "database list" command for convenience
  • Loading branch information
martin-helmich authored Feb 3, 2025
2 parents 3b4f16d + 122e10b commit 77bd221
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 4 deletions.
32 changes: 32 additions & 0 deletions docs/database.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

Manage databases (like MySQL and Redis) in your projects

* [`mw database list`](#mw-database-list)
* [`mw database mysql charsets`](#mw-database-mysql-charsets)
* [`mw database mysql create`](#mw-database-mysql-create)
* [`mw database mysql delete DATABASE-ID`](#mw-database-mysql-delete-database-id)
Expand All @@ -25,6 +26,37 @@ Manage databases (like MySQL and Redis) in your projects
* [`mw database redis shell DATABASE-ID`](#mw-database-redis-shell-database-id)
* [`mw database redis versions`](#mw-database-redis-versions)

## `mw database list`

List all kinds of databases belonging to a project.

```
USAGE
$ mw database list -o txt|json|yaml|csv|tsv [-x] [--no-header] [--no-truncate] [--no-relative-dates]
[--csv-separator ,|;] [-p <value>]
FLAGS
-o, --output=<option> (required) [default: txt] output in a more machine friendly format
<options: txt|json|yaml|csv|tsv>
-p, --project-id=<value> ID or short ID of a project; this flag is optional if a default project is set in the
context
-x, --extended show extended information
--csv-separator=<option> [default: ,] separator for CSV output (only relevant for CSV output)
<options: ,|;>
--no-header hide table header
--no-relative-dates show dates in absolute format, not relative (only relevant for txt output)
--no-truncate do not truncate output (only relevant for txt output)
DESCRIPTION
List all kinds of databases belonging to a project.
FLAG DESCRIPTIONS
-p, --project-id=<value> ID or short ID of a project; this flag is optional if a default project is set in the context
May contain a short ID or a full ID of a project; you can also use the "mw context set --project-id=<VALUE>" command
to persistently set a default project for all commands that accept this flag.
```

## `mw database mysql charsets`

List available MySQL character sets and collations, optionally filtered by a MySQLVersion.
Expand Down
93 changes: 93 additions & 0 deletions src/commands/database/list.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import { assertStatus } from "@mittwald/api-client-commons";
import { MittwaldAPIV2Client } from "@mittwald/api-client";
import { ListColumns } from "../../rendering/formatter/Table.js";
import { ListBaseCommand } from "../../lib/basecommands/ListBaseCommand.js";
import { projectFlags } from "../../lib/resources/project/flags.js";

type ResponseItem = {
id: string;
kind: "mysql" | "redis";
name: string;
version: string;
description: string;
hostname: string;
isReady: boolean;
createdAt: string;
};
type Response = Awaited<
ReturnType<MittwaldAPIV2Client["database"]["listMysqlDatabases"]>
>;

export class List extends ListBaseCommand<typeof List, ResponseItem, Response> {
static description = "List all kinds of databases belonging to a project.";

static args = {};
static flags = {
...ListBaseCommand.baseFlags,
...projectFlags,
};

public async getData(): Promise<ResponseItem[]> {
const projectId = await this.withProjectId(List);
const databases: ResponseItem[] = [];

const mysqlResponse = await this.apiClient.database.listMysqlDatabases({
projectId,
});
assertStatus(mysqlResponse, 200);

const redisResponse = await this.apiClient.database.listRedisDatabases({
projectId,
});
assertStatus(redisResponse, 200);

databases.push(
...mysqlResponse.data.map((d) => ({ ...d, kind: "mysql" as const })),
...redisResponse.data.map((d) => ({
...d,
kind: "redis" as const,
isReady: true,
})),
);

return databases;
}

protected getColumns(ignoredData: ResponseItem[]): ListColumns<ResponseItem> {
const { id, name, createdAt } = super.getColumns(ignoredData, {
shortIdKey: "name",
});
return {
id,
name,
version: {
header: "Version",
get(row) {
if (row.kind === "mysql") {
return `MySQL ${row.version}`;
} else if (row.kind === "redis") {
return `Redis ${row.version}`;
} else {
return "Unknown";
}
},
},
description: {
header: "Description",
},
hostname: {
header: "Hostname",
},
status: {
header: "Status",
get: (row) => {
if (!row.isReady) {
return "pending";
}
return "ready";
},
},
createdAt,
};
}
}
12 changes: 8 additions & 4 deletions src/lib/basecommands/ListBaseCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,19 @@ export abstract class ListBaseCommand<

public async run(): Promise<void> {
const response = await this.getData();
let data: TItem[];

assertStatus(response, 200);

const data = await this.mapData(response.data);
if (!Array.isArray(response)) {
assertStatus(response, 200);
data = await this.mapData(response.data);
} else {
data = response;
}

this.formatter.log(data, this.getColumns(data), this.flags as ListOptions);
}

protected abstract getData(): Promise<TAPIResponse>;
protected abstract getData(): Promise<TAPIResponse | TItem[]>;

protected mapData(
data: SuccessfulResponse<TAPIResponse, 200>["data"],
Expand Down

0 comments on commit 77bd221

Please sign in to comment.