@hesed/mysql 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +39 -39
- package/dist/commands/mysql/databases.js +2 -5
- package/dist/commands/mysql/describe-table.js +2 -2
- package/dist/commands/mysql/explain-query.js +1 -1
- package/dist/commands/mysql/indexes.js +2 -2
- package/dist/commands/mysql/query.js +6 -2
- package/dist/commands/mysql/tables.js +2 -5
- package/dist/mysql/database.d.ts +1 -0
- package/dist/mysql/mysql-client.js +1 -1
- package/dist/mysql/mysql-utils.d.ts +2 -1
- package/dist/mysql/mysql-utils.js +29 -24
- package/oclif.manifest.json +12 -6
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ $ npm install -g @hesed/mysql
|
|
|
26
26
|
$ mq COMMAND
|
|
27
27
|
running command...
|
|
28
28
|
$ mq (--version)
|
|
29
|
-
@hesed/mysql/0.
|
|
29
|
+
@hesed/mysql/0.5.0 linux-x64 node-v24.16.0
|
|
30
30
|
$ mq --help [COMMAND]
|
|
31
31
|
USAGE
|
|
32
32
|
$ mq COMMAND
|
|
@@ -80,7 +80,7 @@ EXAMPLES
|
|
|
80
80
|
$ mq mysql auth add -p prod
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
_See code: [src/commands/mysql/auth/add.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
83
|
+
_See code: [src/commands/mysql/auth/add.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/auth/add.ts)_
|
|
84
84
|
|
|
85
85
|
## `mq mysql auth delete`
|
|
86
86
|
|
|
@@ -105,7 +105,7 @@ EXAMPLES
|
|
|
105
105
|
$ mq mysql auth delete -p prod
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
-
_See code: [src/commands/mysql/auth/delete.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
108
|
+
_See code: [src/commands/mysql/auth/delete.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/auth/delete.ts)_
|
|
109
109
|
|
|
110
110
|
## `mq mysql auth list`
|
|
111
111
|
|
|
@@ -125,7 +125,7 @@ EXAMPLES
|
|
|
125
125
|
$ mq mysql auth list
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
-
_See code: [src/commands/mysql/auth/list.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
128
|
+
_See code: [src/commands/mysql/auth/list.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/auth/list.ts)_
|
|
129
129
|
|
|
130
130
|
## `mq mysql auth profile`
|
|
131
131
|
|
|
@@ -150,7 +150,7 @@ EXAMPLES
|
|
|
150
150
|
$ mq mysql auth profile --default test
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
_See code: [src/commands/mysql/auth/profile.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
153
|
+
_See code: [src/commands/mysql/auth/profile.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/auth/profile.ts)_
|
|
154
154
|
|
|
155
155
|
## `mq mysql auth test`
|
|
156
156
|
|
|
@@ -175,7 +175,7 @@ EXAMPLES
|
|
|
175
175
|
$ mq mysql auth test -p prod
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
-
_See code: [src/commands/mysql/auth/test.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
178
|
+
_See code: [src/commands/mysql/auth/test.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/auth/test.ts)_
|
|
179
179
|
|
|
180
180
|
## `mq mysql auth update`
|
|
181
181
|
|
|
@@ -207,7 +207,7 @@ EXAMPLES
|
|
|
207
207
|
$ mq mysql auth update -p test
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
-
_See code: [src/commands/mysql/auth/update.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
210
|
+
_See code: [src/commands/mysql/auth/update.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/auth/update.ts)_
|
|
211
211
|
|
|
212
212
|
## `mq mysql databases`
|
|
213
213
|
|
|
@@ -215,10 +215,10 @@ List all databases accessible on the MySQL server
|
|
|
215
215
|
|
|
216
216
|
```
|
|
217
217
|
USAGE
|
|
218
|
-
$ mq mysql databases [
|
|
218
|
+
$ mq mysql databases [-p <value>]
|
|
219
219
|
|
|
220
220
|
FLAGS
|
|
221
|
-
--profile=<value> Database profile name from config
|
|
221
|
+
-p, --profile=<value> Database profile name from config
|
|
222
222
|
|
|
223
223
|
DESCRIPTION
|
|
224
224
|
List all databases accessible on the MySQL server
|
|
@@ -226,10 +226,10 @@ DESCRIPTION
|
|
|
226
226
|
EXAMPLES
|
|
227
227
|
$ mq mysql databases
|
|
228
228
|
|
|
229
|
-
$ mq mysql databases
|
|
229
|
+
$ mq mysql databases -p staging
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
-
_See code: [src/commands/mysql/databases.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
232
|
+
_See code: [src/commands/mysql/databases.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/databases.ts)_
|
|
233
233
|
|
|
234
234
|
## `mq mysql describe-table TABLE`
|
|
235
235
|
|
|
@@ -237,15 +237,15 @@ Describe the structure of a MySQL table
|
|
|
237
237
|
|
|
238
238
|
```
|
|
239
239
|
USAGE
|
|
240
|
-
$ mq mysql describe-table TABLE [--format table|json|toon] [
|
|
240
|
+
$ mq mysql describe-table TABLE [--format table|json|toon] [-p <value>]
|
|
241
241
|
|
|
242
242
|
ARGUMENTS
|
|
243
243
|
TABLE Table name to describe
|
|
244
244
|
|
|
245
245
|
FLAGS
|
|
246
|
-
--
|
|
247
|
-
|
|
248
|
-
|
|
246
|
+
-p, --profile=<value> Database profile name from config
|
|
247
|
+
--format=<option> [default: table] Output format
|
|
248
|
+
<options: table|json|toon>
|
|
249
249
|
|
|
250
250
|
DESCRIPTION
|
|
251
251
|
Describe the structure of a MySQL table
|
|
@@ -253,10 +253,10 @@ DESCRIPTION
|
|
|
253
253
|
EXAMPLES
|
|
254
254
|
$ mq mysql describe-table users
|
|
255
255
|
|
|
256
|
-
$ mq mysql describe-table orders --format json
|
|
256
|
+
$ mq mysql describe-table orders --format json -p prod
|
|
257
257
|
```
|
|
258
258
|
|
|
259
|
-
_See code: [src/commands/mysql/describe-table.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
259
|
+
_See code: [src/commands/mysql/describe-table.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/describe-table.ts)_
|
|
260
260
|
|
|
261
261
|
## `mq mysql explain-query QUERY`
|
|
262
262
|
|
|
@@ -264,15 +264,15 @@ Show the execution plan for a MySQL query
|
|
|
264
264
|
|
|
265
265
|
```
|
|
266
266
|
USAGE
|
|
267
|
-
$ mq mysql explain-query QUERY [--format table|json|toon] [
|
|
267
|
+
$ mq mysql explain-query QUERY [--format table|json|toon] [-p <value>]
|
|
268
268
|
|
|
269
269
|
ARGUMENTS
|
|
270
270
|
QUERY SQL query to explain
|
|
271
271
|
|
|
272
272
|
FLAGS
|
|
273
|
-
--
|
|
274
|
-
|
|
275
|
-
|
|
273
|
+
-p, --profile=<value> Database profile name from config
|
|
274
|
+
--format=<option> [default: table] Output format
|
|
275
|
+
<options: table|json|toon>
|
|
276
276
|
|
|
277
277
|
DESCRIPTION
|
|
278
278
|
Show the execution plan for a MySQL query
|
|
@@ -283,7 +283,7 @@ EXAMPLES
|
|
|
283
283
|
$ mq mysql explain-query "SELECT * FROM orders JOIN users ON orders.user_id = users.id" --format json
|
|
284
284
|
```
|
|
285
285
|
|
|
286
|
-
_See code: [src/commands/mysql/explain-query.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
286
|
+
_See code: [src/commands/mysql/explain-query.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/explain-query.ts)_
|
|
287
287
|
|
|
288
288
|
## `mq mysql indexes TABLE`
|
|
289
289
|
|
|
@@ -291,15 +291,15 @@ Show indexes for a MySQL table
|
|
|
291
291
|
|
|
292
292
|
```
|
|
293
293
|
USAGE
|
|
294
|
-
$ mq mysql indexes TABLE [--format table|json|toon] [
|
|
294
|
+
$ mq mysql indexes TABLE [--format table|json|toon] [-p <value>]
|
|
295
295
|
|
|
296
296
|
ARGUMENTS
|
|
297
297
|
TABLE Table name to show indexes for
|
|
298
298
|
|
|
299
299
|
FLAGS
|
|
300
|
-
--
|
|
301
|
-
|
|
302
|
-
|
|
300
|
+
-p, --profile=<value> Database profile name from config
|
|
301
|
+
--format=<option> [default: table] Output format
|
|
302
|
+
<options: table|json|toon>
|
|
303
303
|
|
|
304
304
|
DESCRIPTION
|
|
305
305
|
Show indexes for a MySQL table
|
|
@@ -307,10 +307,10 @@ DESCRIPTION
|
|
|
307
307
|
EXAMPLES
|
|
308
308
|
$ mq mysql indexes users
|
|
309
309
|
|
|
310
|
-
$ mq mysql indexes orders --format json
|
|
310
|
+
$ mq mysql indexes orders --format json -p prod
|
|
311
311
|
```
|
|
312
312
|
|
|
313
|
-
_See code: [src/commands/mysql/indexes.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
313
|
+
_See code: [src/commands/mysql/indexes.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/indexes.ts)_
|
|
314
314
|
|
|
315
315
|
## `mq mysql query QUERY`
|
|
316
316
|
|
|
@@ -318,16 +318,16 @@ Execute a SQL query against a MySQL database
|
|
|
318
318
|
|
|
319
319
|
```
|
|
320
320
|
USAGE
|
|
321
|
-
$ mq mysql query QUERY [--format table|json|csv|toon] [
|
|
321
|
+
$ mq mysql query QUERY [--format table|json|csv|toon] [-p <value>] [--skip-confirmation]
|
|
322
322
|
|
|
323
323
|
ARGUMENTS
|
|
324
324
|
QUERY SQL query to execute
|
|
325
325
|
|
|
326
326
|
FLAGS
|
|
327
|
-
--
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
327
|
+
-p, --profile=<value> Database profile name from config
|
|
328
|
+
--format=<option> [default: table] Output format
|
|
329
|
+
<options: table|json|csv|toon>
|
|
330
|
+
--skip-confirmation Skip confirmation prompt for destructive operations
|
|
331
331
|
|
|
332
332
|
DESCRIPTION
|
|
333
333
|
Execute a SQL query against a MySQL database
|
|
@@ -337,10 +337,10 @@ EXAMPLES
|
|
|
337
337
|
|
|
338
338
|
$ mq mysql query "UPDATE users SET email = 'user@email.com' WHERE id = 999" --format json
|
|
339
339
|
|
|
340
|
-
$ mq mysql query "DELETE FROM sessions"
|
|
340
|
+
$ mq mysql query "DELETE FROM sessions" -p prod --skip-confirmation
|
|
341
341
|
```
|
|
342
342
|
|
|
343
|
-
_See code: [src/commands/mysql/query.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
343
|
+
_See code: [src/commands/mysql/query.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/query.ts)_
|
|
344
344
|
|
|
345
345
|
## `mq mysql tables`
|
|
346
346
|
|
|
@@ -348,10 +348,10 @@ List all tables in the current MySQL database
|
|
|
348
348
|
|
|
349
349
|
```
|
|
350
350
|
USAGE
|
|
351
|
-
$ mq mysql tables [
|
|
351
|
+
$ mq mysql tables [-p <value>]
|
|
352
352
|
|
|
353
353
|
FLAGS
|
|
354
|
-
--profile=<value> Database profile name from config
|
|
354
|
+
-p, --profile=<value> Database profile name from config
|
|
355
355
|
|
|
356
356
|
DESCRIPTION
|
|
357
357
|
List all tables in the current MySQL database
|
|
@@ -359,8 +359,8 @@ DESCRIPTION
|
|
|
359
359
|
EXAMPLES
|
|
360
360
|
$ mq mysql tables
|
|
361
361
|
|
|
362
|
-
$ mq mysql tables
|
|
362
|
+
$ mq mysql tables -p local
|
|
363
363
|
```
|
|
364
364
|
|
|
365
|
-
_See code: [src/commands/mysql/tables.ts](https://github.com/hesedcasa/mysql/blob/v0.
|
|
365
|
+
_See code: [src/commands/mysql/tables.ts](https://github.com/hesedcasa/mysql/blob/v0.5.0/src/commands/mysql/tables.ts)_
|
|
366
366
|
<!-- commandsstop -->
|
|
@@ -2,12 +2,9 @@ import { Command, Flags } from '@oclif/core';
|
|
|
2
2
|
import { closeConnections, listDatabases } from '../../mysql/index.js';
|
|
3
3
|
export default class MySQLDatabases extends Command {
|
|
4
4
|
static description = 'List all databases accessible on the MySQL server';
|
|
5
|
-
static examples = [
|
|
6
|
-
'<%= config.bin %> <%= command.id %>',
|
|
7
|
-
'<%= config.bin %> <%= command.id %> --profile staging',
|
|
8
|
-
];
|
|
5
|
+
static examples = ['<%= config.bin %> <%= command.id %>', '<%= config.bin %> <%= command.id %> -p staging'];
|
|
9
6
|
static flags = {
|
|
10
|
-
profile: Flags.string({ description: 'Database profile name from config', required: false }),
|
|
7
|
+
profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
|
|
11
8
|
};
|
|
12
9
|
async run() {
|
|
13
10
|
const { flags } = await this.parse(MySQLDatabases);
|
|
@@ -7,7 +7,7 @@ export default class MySQLDescribeTable extends Command {
|
|
|
7
7
|
static description = 'Describe the structure of a MySQL table';
|
|
8
8
|
static examples = [
|
|
9
9
|
'<%= config.bin %> <%= command.id %> users',
|
|
10
|
-
'<%= config.bin %> <%= command.id %> orders --format json
|
|
10
|
+
'<%= config.bin %> <%= command.id %> orders --format json -p prod',
|
|
11
11
|
];
|
|
12
12
|
static flags = {
|
|
13
13
|
format: Flags.string({
|
|
@@ -15,7 +15,7 @@ export default class MySQLDescribeTable extends Command {
|
|
|
15
15
|
description: 'Output format',
|
|
16
16
|
options: ['table', 'json', 'toon'],
|
|
17
17
|
}),
|
|
18
|
-
profile: Flags.string({ description: 'Database profile name from config', required: false }),
|
|
18
|
+
profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
|
|
19
19
|
};
|
|
20
20
|
async run() {
|
|
21
21
|
const { args, flags } = await this.parse(MySQLDescribeTable);
|
|
@@ -15,7 +15,7 @@ export default class MySQLExplain extends Command {
|
|
|
15
15
|
description: 'Output format',
|
|
16
16
|
options: ['table', 'json', 'toon'],
|
|
17
17
|
}),
|
|
18
|
-
profile: Flags.string({ description: 'Database profile name from config', required: false }),
|
|
18
|
+
profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
|
|
19
19
|
};
|
|
20
20
|
async run() {
|
|
21
21
|
const { args, flags } = await this.parse(MySQLExplain);
|
|
@@ -7,7 +7,7 @@ export default class MySQLIndexes extends Command {
|
|
|
7
7
|
static description = 'Show indexes for a MySQL table';
|
|
8
8
|
static examples = [
|
|
9
9
|
'<%= config.bin %> <%= command.id %> users',
|
|
10
|
-
'<%= config.bin %> <%= command.id %> orders --format json
|
|
10
|
+
'<%= config.bin %> <%= command.id %> orders --format json -p prod',
|
|
11
11
|
];
|
|
12
12
|
static flags = {
|
|
13
13
|
format: Flags.string({
|
|
@@ -15,7 +15,7 @@ export default class MySQLIndexes extends Command {
|
|
|
15
15
|
description: 'Output format',
|
|
16
16
|
options: ['table', 'json', 'toon'],
|
|
17
17
|
}),
|
|
18
|
-
profile: Flags.string({ description: 'Database profile name from config', required: false }),
|
|
18
|
+
profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
|
|
19
19
|
};
|
|
20
20
|
async run() {
|
|
21
21
|
const { args, flags } = await this.parse(MySQLIndexes);
|
|
@@ -8,7 +8,7 @@ export default class MySQLQuery extends Command {
|
|
|
8
8
|
static examples = [
|
|
9
9
|
'<%= config.bin %> <%= command.id %> "SELECT * FROM users LIMIT 10"',
|
|
10
10
|
'<%= config.bin %> <%= command.id %> "UPDATE users SET email = \'user@email.com\' WHERE id = 999" --format json',
|
|
11
|
-
'<%= config.bin %> <%= command.id %> "DELETE FROM sessions"
|
|
11
|
+
'<%= config.bin %> <%= command.id %> "DELETE FROM sessions" -p prod --skip-confirmation',
|
|
12
12
|
];
|
|
13
13
|
static flags = {
|
|
14
14
|
format: Flags.string({
|
|
@@ -16,7 +16,7 @@ export default class MySQLQuery extends Command {
|
|
|
16
16
|
description: 'Output format',
|
|
17
17
|
options: ['table', 'json', 'csv', 'toon'],
|
|
18
18
|
}),
|
|
19
|
-
profile: Flags.string({ description: 'Database profile name from config', required: false }),
|
|
19
|
+
profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
|
|
20
20
|
'skip-confirmation': Flags.boolean({
|
|
21
21
|
default: false,
|
|
22
22
|
description: 'Skip confirmation prompt for destructive operations',
|
|
@@ -27,6 +27,10 @@ export default class MySQLQuery extends Command {
|
|
|
27
27
|
const result = await executeQuery(this.config, args.query, flags.profile, flags.format, flags['skip-confirmation']);
|
|
28
28
|
await closeConnections();
|
|
29
29
|
if (result.success) {
|
|
30
|
+
// Notices (warnings, row counts) go to stderr so machine-readable formats
|
|
31
|
+
// leave stdout as clean, parseable data.
|
|
32
|
+
if (result.notices)
|
|
33
|
+
this.logToStderr(result.notices);
|
|
30
34
|
this.log(result.result ?? '');
|
|
31
35
|
}
|
|
32
36
|
else if (result.requiresConfirmation) {
|
|
@@ -2,12 +2,9 @@ import { Command, Flags } from '@oclif/core';
|
|
|
2
2
|
import { closeConnections, listTables } from '../../mysql/index.js';
|
|
3
3
|
export default class MySQLTables extends Command {
|
|
4
4
|
static description = 'List all tables in the current MySQL database';
|
|
5
|
-
static examples = [
|
|
6
|
-
'<%= config.bin %> <%= command.id %>',
|
|
7
|
-
'<%= config.bin %> <%= command.id %> --profile local',
|
|
8
|
-
];
|
|
5
|
+
static examples = ['<%= config.bin %> <%= command.id %>', '<%= config.bin %> <%= command.id %> -p local'];
|
|
9
6
|
static flags = {
|
|
10
|
-
profile: Flags.string({ description: 'Database profile name from config', required: false }),
|
|
7
|
+
profile: Flags.string({ char: 'p', description: 'Database profile name from config', required: false }),
|
|
11
8
|
};
|
|
12
9
|
async run() {
|
|
13
10
|
const { flags } = await this.parse(MySQLTables);
|
package/dist/mysql/database.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ const DEFAULT_SAFETY_CONFIG = {
|
|
|
10
10
|
async function initMySQL(config) {
|
|
11
11
|
if (mysqlUtil)
|
|
12
12
|
return mysqlUtil;
|
|
13
|
-
const pm = createProfileManager(config);
|
|
13
|
+
const pm = createProfileManager(config, undefined, 'mysql-config.json');
|
|
14
14
|
const profiles = await pm.readProfiles();
|
|
15
15
|
if (!profiles) {
|
|
16
16
|
throw new Error(`No profile found.`);
|
|
@@ -12,7 +12,8 @@ export declare class MySQLUtil implements DatabaseUtil {
|
|
|
12
12
|
listTables(profileName: string): Promise<TableListResult>;
|
|
13
13
|
showIndexes(profileName: string, table: string, format?: 'json' | 'table' | 'toon'): Promise<IndexResult>;
|
|
14
14
|
testConnection(profileName: string): Promise<ConnectionTestResult>;
|
|
15
|
+
private formatReadResult;
|
|
15
16
|
private formatRows;
|
|
16
|
-
private
|
|
17
|
+
private formatWriteResult;
|
|
17
18
|
private getConnection;
|
|
18
19
|
}
|
|
@@ -50,41 +50,36 @@ export class MySQLUtil {
|
|
|
50
50
|
};
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
|
+
// Machine-readable formats must emit only the data payload on stdout, so
|
|
54
|
+
// analysis warnings and status lines are collected as notices instead.
|
|
55
|
+
const machineFormat = format === 'json' || format === 'csv' || format === 'toon';
|
|
56
|
+
const notices = [];
|
|
53
57
|
const warnings = analyzeQuery(query);
|
|
54
|
-
let warningText = '';
|
|
55
58
|
if (warnings.length > 0) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
warnings.map((w) => ` [${w.level.toUpperCase()}] ${w.message}\n → ${w.suggestion}`).join('\n') +
|
|
59
|
-
'\n\n';
|
|
59
|
+
notices.push('Query Analysis:\n' +
|
|
60
|
+
warnings.map((w) => ` [${w.level.toUpperCase()}] ${w.message}\n → ${w.suggestion}`).join('\n'));
|
|
60
61
|
}
|
|
61
62
|
let finalQuery = query;
|
|
62
63
|
const queryType = getQueryType(query);
|
|
63
64
|
if (queryType === 'SELECT') {
|
|
64
65
|
finalQuery = applyDefaultLimit(query, this.config.safety.defaultLimit);
|
|
65
66
|
if (finalQuery !== query) {
|
|
66
|
-
|
|
67
|
+
notices.push(`Applied default LIMIT ${this.config.safety.defaultLimit}`);
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
try {
|
|
70
71
|
const connection = await this.getConnection(profileName);
|
|
71
72
|
const [rows, fields] = await connection.query(finalQuery);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
const insertId = okPacket.insertId ?? null;
|
|
80
|
-
result += `Query executed successfully.\n`;
|
|
81
|
-
result += `Affected rows: ${affectedRows}\n`;
|
|
82
|
-
if (insertId) {
|
|
83
|
-
result += `Insert ID: ${insertId}\n`;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
73
|
+
const isRead = queryType === 'SELECT' || queryType === 'SHOW' || queryType === 'DESCRIBE' || queryType === 'EXPLAIN';
|
|
74
|
+
const data = isRead
|
|
75
|
+
? this.formatReadResult(rows, fields, format, notices)
|
|
76
|
+
: this.formatWriteResult(rows, notices);
|
|
77
|
+
const notice = notices.join('\n\n');
|
|
78
|
+
// For human (table) output everything stays on stdout, exactly as before.
|
|
79
|
+
// For machine formats the data is returned alone and notices go to stderr.
|
|
86
80
|
return {
|
|
87
|
-
|
|
81
|
+
notices: machineFormat ? notice : undefined,
|
|
82
|
+
result: machineFormat ? data : `${notice}\n\n${data}`,
|
|
88
83
|
success: true,
|
|
89
84
|
};
|
|
90
85
|
}
|
|
@@ -192,12 +187,22 @@ export class MySQLUtil {
|
|
|
192
187
|
};
|
|
193
188
|
}
|
|
194
189
|
}
|
|
190
|
+
formatReadResult(rows, fields, format, notices) {
|
|
191
|
+
const rowCount = Array.isArray(rows) ? rows.length : 0;
|
|
192
|
+
notices.push(`Query executed successfully. Rows returned: ${rowCount}`);
|
|
193
|
+
return this.formatRows(rows, fields, format);
|
|
194
|
+
}
|
|
195
195
|
formatRows(rows, fields, format) {
|
|
196
196
|
return FORMATTERS[format](rows, fields);
|
|
197
197
|
}
|
|
198
|
-
|
|
199
|
-
const
|
|
200
|
-
|
|
198
|
+
formatWriteResult(rows, notices) {
|
|
199
|
+
const affectedRows = rows.affectedRows ?? 0;
|
|
200
|
+
const insertId = rows.insertId ?? null;
|
|
201
|
+
notices.push('Query executed successfully.');
|
|
202
|
+
let data = `Affected rows: ${affectedRows}\n`;
|
|
203
|
+
if (insertId)
|
|
204
|
+
data += `Insert ID: ${insertId}\n`;
|
|
205
|
+
return data;
|
|
201
206
|
}
|
|
202
207
|
async getConnection(profileName) {
|
|
203
208
|
const existing = this.connections.get(profileName);
|
package/oclif.manifest.json
CHANGED
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
"description": "List all databases accessible on the MySQL server",
|
|
7
7
|
"examples": [
|
|
8
8
|
"<%= config.bin %> <%= command.id %>",
|
|
9
|
-
"<%= config.bin %> <%= command.id %>
|
|
9
|
+
"<%= config.bin %> <%= command.id %> -p staging"
|
|
10
10
|
],
|
|
11
11
|
"flags": {
|
|
12
12
|
"profile": {
|
|
13
|
+
"char": "p",
|
|
13
14
|
"description": "Database profile name from config",
|
|
14
15
|
"name": "profile",
|
|
15
16
|
"required": false,
|
|
@@ -46,7 +47,7 @@
|
|
|
46
47
|
"description": "Describe the structure of a MySQL table",
|
|
47
48
|
"examples": [
|
|
48
49
|
"<%= config.bin %> <%= command.id %> users",
|
|
49
|
-
"<%= config.bin %> <%= command.id %> orders --format json
|
|
50
|
+
"<%= config.bin %> <%= command.id %> orders --format json -p prod"
|
|
50
51
|
],
|
|
51
52
|
"flags": {
|
|
52
53
|
"format": {
|
|
@@ -63,6 +64,7 @@
|
|
|
63
64
|
"type": "option"
|
|
64
65
|
},
|
|
65
66
|
"profile": {
|
|
67
|
+
"char": "p",
|
|
66
68
|
"description": "Database profile name from config",
|
|
67
69
|
"name": "profile",
|
|
68
70
|
"required": false,
|
|
@@ -116,6 +118,7 @@
|
|
|
116
118
|
"type": "option"
|
|
117
119
|
},
|
|
118
120
|
"profile": {
|
|
121
|
+
"char": "p",
|
|
119
122
|
"description": "Database profile name from config",
|
|
120
123
|
"name": "profile",
|
|
121
124
|
"required": false,
|
|
@@ -152,7 +155,7 @@
|
|
|
152
155
|
"description": "Show indexes for a MySQL table",
|
|
153
156
|
"examples": [
|
|
154
157
|
"<%= config.bin %> <%= command.id %> users",
|
|
155
|
-
"<%= config.bin %> <%= command.id %> orders --format json
|
|
158
|
+
"<%= config.bin %> <%= command.id %> orders --format json -p prod"
|
|
156
159
|
],
|
|
157
160
|
"flags": {
|
|
158
161
|
"format": {
|
|
@@ -169,6 +172,7 @@
|
|
|
169
172
|
"type": "option"
|
|
170
173
|
},
|
|
171
174
|
"profile": {
|
|
175
|
+
"char": "p",
|
|
172
176
|
"description": "Database profile name from config",
|
|
173
177
|
"name": "profile",
|
|
174
178
|
"required": false,
|
|
@@ -206,7 +210,7 @@
|
|
|
206
210
|
"examples": [
|
|
207
211
|
"<%= config.bin %> <%= command.id %> \"SELECT * FROM users LIMIT 10\"",
|
|
208
212
|
"<%= config.bin %> <%= command.id %> \"UPDATE users SET email = 'user@email.com' WHERE id = 999\" --format json",
|
|
209
|
-
"<%= config.bin %> <%= command.id %> \"DELETE FROM sessions\"
|
|
213
|
+
"<%= config.bin %> <%= command.id %> \"DELETE FROM sessions\" -p prod --skip-confirmation"
|
|
210
214
|
],
|
|
211
215
|
"flags": {
|
|
212
216
|
"format": {
|
|
@@ -224,6 +228,7 @@
|
|
|
224
228
|
"type": "option"
|
|
225
229
|
},
|
|
226
230
|
"profile": {
|
|
231
|
+
"char": "p",
|
|
227
232
|
"description": "Database profile name from config",
|
|
228
233
|
"name": "profile",
|
|
229
234
|
"required": false,
|
|
@@ -260,10 +265,11 @@
|
|
|
260
265
|
"description": "List all tables in the current MySQL database",
|
|
261
266
|
"examples": [
|
|
262
267
|
"<%= config.bin %> <%= command.id %>",
|
|
263
|
-
"<%= config.bin %> <%= command.id %>
|
|
268
|
+
"<%= config.bin %> <%= command.id %> -p local"
|
|
264
269
|
],
|
|
265
270
|
"flags": {
|
|
266
271
|
"profile": {
|
|
272
|
+
"char": "p",
|
|
267
273
|
"description": "Database profile name from config",
|
|
268
274
|
"name": "profile",
|
|
269
275
|
"required": false,
|
|
@@ -634,5 +640,5 @@
|
|
|
634
640
|
]
|
|
635
641
|
}
|
|
636
642
|
},
|
|
637
|
-
"version": "0.
|
|
643
|
+
"version": "0.5.0"
|
|
638
644
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hesed/mysql",
|
|
3
3
|
"description": "CLI for MySQL database interaction",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.5.0",
|
|
5
5
|
"author": "Hesed",
|
|
6
6
|
"bin": {
|
|
7
7
|
"mq": "./bin/run.js"
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"@types/chai": "^5",
|
|
23
23
|
"@types/fs-extra": "^11.0.4",
|
|
24
24
|
"@types/mocha": "^10",
|
|
25
|
-
"@types/node": "^
|
|
25
|
+
"@types/node": "^26",
|
|
26
26
|
"@types/sinon": "^21.0.0",
|
|
27
27
|
"c8": "^11.0.0",
|
|
28
28
|
"chai": "^6",
|