@hesed/psql 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/psql/databases.js +2 -5
- package/dist/commands/psql/describe-table.js +2 -2
- package/dist/commands/psql/explain-query.js +1 -1
- package/dist/commands/psql/indexes.js +2 -2
- package/dist/commands/psql/query.js +6 -2
- package/dist/commands/psql/tables.js +2 -5
- package/dist/psql/database.d.ts +1 -0
- package/dist/psql/index.d.ts +0 -1
- package/dist/psql/postgres-client.js +1 -1
- package/dist/psql/postgres-utils.d.ts +2 -1
- package/dist/psql/postgres-utils.js +24 -19
- package/oclif.manifest.json +12 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -26,7 +26,7 @@ $ npm install -g @hesed/psql
|
|
|
26
26
|
$ pg COMMAND
|
|
27
27
|
running command...
|
|
28
28
|
$ pg (--version)
|
|
29
|
-
@hesed/psql/0.
|
|
29
|
+
@hesed/psql/0.5.0 linux-x64 node-v24.16.0
|
|
30
30
|
$ pg --help [COMMAND]
|
|
31
31
|
USAGE
|
|
32
32
|
$ pg COMMAND
|
|
@@ -80,7 +80,7 @@ EXAMPLES
|
|
|
80
80
|
$ pg psql auth add -p prod
|
|
81
81
|
```
|
|
82
82
|
|
|
83
|
-
_See code: [src/commands/psql/auth/add.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
83
|
+
_See code: [src/commands/psql/auth/add.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/auth/add.ts)_
|
|
84
84
|
|
|
85
85
|
## `pg psql auth delete`
|
|
86
86
|
|
|
@@ -105,7 +105,7 @@ EXAMPLES
|
|
|
105
105
|
$ pg psql auth delete -p prod
|
|
106
106
|
```
|
|
107
107
|
|
|
108
|
-
_See code: [src/commands/psql/auth/delete.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
108
|
+
_See code: [src/commands/psql/auth/delete.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/auth/delete.ts)_
|
|
109
109
|
|
|
110
110
|
## `pg psql auth list`
|
|
111
111
|
|
|
@@ -125,7 +125,7 @@ EXAMPLES
|
|
|
125
125
|
$ pg psql auth list
|
|
126
126
|
```
|
|
127
127
|
|
|
128
|
-
_See code: [src/commands/psql/auth/list.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
128
|
+
_See code: [src/commands/psql/auth/list.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/auth/list.ts)_
|
|
129
129
|
|
|
130
130
|
## `pg psql auth profile`
|
|
131
131
|
|
|
@@ -150,7 +150,7 @@ EXAMPLES
|
|
|
150
150
|
$ pg psql auth profile --default test
|
|
151
151
|
```
|
|
152
152
|
|
|
153
|
-
_See code: [src/commands/psql/auth/profile.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
153
|
+
_See code: [src/commands/psql/auth/profile.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/auth/profile.ts)_
|
|
154
154
|
|
|
155
155
|
## `pg psql auth test`
|
|
156
156
|
|
|
@@ -175,7 +175,7 @@ EXAMPLES
|
|
|
175
175
|
$ pg psql auth test -p prod
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
-
_See code: [src/commands/psql/auth/test.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
178
|
+
_See code: [src/commands/psql/auth/test.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/auth/test.ts)_
|
|
179
179
|
|
|
180
180
|
## `pg psql auth update`
|
|
181
181
|
|
|
@@ -207,7 +207,7 @@ EXAMPLES
|
|
|
207
207
|
$ pg psql auth update -p test
|
|
208
208
|
```
|
|
209
209
|
|
|
210
|
-
_See code: [src/commands/psql/auth/update.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
210
|
+
_See code: [src/commands/psql/auth/update.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/auth/update.ts)_
|
|
211
211
|
|
|
212
212
|
## `pg psql databases`
|
|
213
213
|
|
|
@@ -215,10 +215,10 @@ List all databases accessible on the PostgreSQL server
|
|
|
215
215
|
|
|
216
216
|
```
|
|
217
217
|
USAGE
|
|
218
|
-
$ pg psql databases [
|
|
218
|
+
$ pg psql 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 PostgreSQL server
|
|
@@ -226,10 +226,10 @@ DESCRIPTION
|
|
|
226
226
|
EXAMPLES
|
|
227
227
|
$ pg psql databases
|
|
228
228
|
|
|
229
|
-
$ pg psql databases
|
|
229
|
+
$ pg psql databases -p staging
|
|
230
230
|
```
|
|
231
231
|
|
|
232
|
-
_See code: [src/commands/psql/databases.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
232
|
+
_See code: [src/commands/psql/databases.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/databases.ts)_
|
|
233
233
|
|
|
234
234
|
## `pg psql describe-table TABLE`
|
|
235
235
|
|
|
@@ -237,15 +237,15 @@ Describe the structure of a PostgreSQL table
|
|
|
237
237
|
|
|
238
238
|
```
|
|
239
239
|
USAGE
|
|
240
|
-
$ pg psql describe-table TABLE [--format table|json|toon] [
|
|
240
|
+
$ pg psql 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 PostgreSQL table
|
|
@@ -253,10 +253,10 @@ DESCRIPTION
|
|
|
253
253
|
EXAMPLES
|
|
254
254
|
$ pg psql describe-table users
|
|
255
255
|
|
|
256
|
-
$ pg psql describe-table orders --format json
|
|
256
|
+
$ pg psql describe-table orders --format json -p prod
|
|
257
257
|
```
|
|
258
258
|
|
|
259
|
-
_See code: [src/commands/psql/describe-table.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
259
|
+
_See code: [src/commands/psql/describe-table.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/describe-table.ts)_
|
|
260
260
|
|
|
261
261
|
## `pg psql explain-query QUERY`
|
|
262
262
|
|
|
@@ -264,15 +264,15 @@ Show the execution plan for a PostgreSQL query
|
|
|
264
264
|
|
|
265
265
|
```
|
|
266
266
|
USAGE
|
|
267
|
-
$ pg psql explain-query QUERY [--format table|json|toon] [
|
|
267
|
+
$ pg psql 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 PostgreSQL query
|
|
@@ -283,7 +283,7 @@ EXAMPLES
|
|
|
283
283
|
$ pg psql explain-query "SELECT * FROM orders JOIN users ON orders.user_id = users.id" --format json
|
|
284
284
|
```
|
|
285
285
|
|
|
286
|
-
_See code: [src/commands/psql/explain-query.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
286
|
+
_See code: [src/commands/psql/explain-query.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/explain-query.ts)_
|
|
287
287
|
|
|
288
288
|
## `pg psql indexes TABLE`
|
|
289
289
|
|
|
@@ -291,15 +291,15 @@ Show indexes for a PostgreSQL table
|
|
|
291
291
|
|
|
292
292
|
```
|
|
293
293
|
USAGE
|
|
294
|
-
$ pg psql indexes TABLE [--format table|json|toon] [
|
|
294
|
+
$ pg psql 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 PostgreSQL table
|
|
@@ -307,10 +307,10 @@ DESCRIPTION
|
|
|
307
307
|
EXAMPLES
|
|
308
308
|
$ pg psql indexes users
|
|
309
309
|
|
|
310
|
-
$ pg psql indexes orders --format json
|
|
310
|
+
$ pg psql indexes orders --format json -p prod
|
|
311
311
|
```
|
|
312
312
|
|
|
313
|
-
_See code: [src/commands/psql/indexes.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
313
|
+
_See code: [src/commands/psql/indexes.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/indexes.ts)_
|
|
314
314
|
|
|
315
315
|
## `pg psql query QUERY`
|
|
316
316
|
|
|
@@ -318,16 +318,16 @@ Execute a SQL query against a PostgreSQL database
|
|
|
318
318
|
|
|
319
319
|
```
|
|
320
320
|
USAGE
|
|
321
|
-
$ pg psql query QUERY [--format table|json|csv|toon] [
|
|
321
|
+
$ pg psql 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 PostgreSQL database
|
|
@@ -337,10 +337,10 @@ EXAMPLES
|
|
|
337
337
|
|
|
338
338
|
$ pg psql query "UPDATE users SET email = 'user@email.com' WHERE id = 999" --format json
|
|
339
339
|
|
|
340
|
-
$ pg psql query "DELETE FROM sessions"
|
|
340
|
+
$ pg psql query "DELETE FROM sessions" -p prod --skip-confirmation
|
|
341
341
|
```
|
|
342
342
|
|
|
343
|
-
_See code: [src/commands/psql/query.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
343
|
+
_See code: [src/commands/psql/query.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/query.ts)_
|
|
344
344
|
|
|
345
345
|
## `pg psql tables`
|
|
346
346
|
|
|
@@ -348,10 +348,10 @@ List all tables in the current PostgreSQL database
|
|
|
348
348
|
|
|
349
349
|
```
|
|
350
350
|
USAGE
|
|
351
|
-
$ pg psql tables [
|
|
351
|
+
$ pg psql 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 PostgreSQL database
|
|
@@ -359,8 +359,8 @@ DESCRIPTION
|
|
|
359
359
|
EXAMPLES
|
|
360
360
|
$ pg psql tables
|
|
361
361
|
|
|
362
|
-
$ pg psql tables
|
|
362
|
+
$ pg psql tables -p local
|
|
363
363
|
```
|
|
364
364
|
|
|
365
|
-
_See code: [src/commands/psql/tables.ts](https://github.com/hesedcasa/psql/blob/v0.
|
|
365
|
+
_See code: [src/commands/psql/tables.ts](https://github.com/hesedcasa/psql/blob/v0.5.0/src/commands/psql/tables.ts)_
|
|
366
366
|
<!-- commandsstop -->
|
|
@@ -2,12 +2,9 @@ import { Command, Flags } from '@oclif/core';
|
|
|
2
2
|
import { closeConnections, listDatabases } from '../../psql/index.js';
|
|
3
3
|
export default class PostgresDatabases extends Command {
|
|
4
4
|
static description = 'List all databases accessible on the PostgreSQL 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(PostgresDatabases);
|
|
@@ -7,7 +7,7 @@ export default class PostgresDescribeTable extends Command {
|
|
|
7
7
|
static description = 'Describe the structure of a PostgreSQL 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 PostgresDescribeTable 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(PostgresDescribeTable);
|
|
@@ -15,7 +15,7 @@ export default class PostgresExplain 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(PostgresExplain);
|
|
@@ -7,7 +7,7 @@ export default class PostgresIndexes extends Command {
|
|
|
7
7
|
static description = 'Show indexes for a PostgreSQL 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 PostgresIndexes 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(PostgresIndexes);
|
|
@@ -8,7 +8,7 @@ export default class PostgresQuery 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 PostgresQuery 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 PostgresQuery 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 '../../psql/index.js';
|
|
3
3
|
export default class PostgresTables extends Command {
|
|
4
4
|
static description = 'List all tables in the current PostgreSQL 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(PostgresTables);
|
package/dist/psql/database.d.ts
CHANGED
package/dist/psql/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ const DEFAULT_SAFETY_CONFIG = {
|
|
|
10
10
|
async function initPg(config) {
|
|
11
11
|
if (pgUtil)
|
|
12
12
|
return pgUtil;
|
|
13
|
-
const pm = createProfileManager(config);
|
|
13
|
+
const pm = createProfileManager(config, undefined, 'pg-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 PostgreSQLUtil 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,36 +50,36 @@ export class PostgreSQLUtil {
|
|
|
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 client = await this.getConnection(profileName);
|
|
71
72
|
const result = await client.query(finalQuery);
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
output += `Affected rows: ${affectedRows}\n`;
|
|
80
|
-
}
|
|
73
|
+
const isRead = result.rows.length > 0 || result.command === 'SELECT' || result.command === 'EXPLAIN';
|
|
74
|
+
const data = isRead
|
|
75
|
+
? this.formatReadResult(result.rows, result.fields, format, notices)
|
|
76
|
+
: this.formatWriteResult(result.rowCount ?? 0, 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.
|
|
81
80
|
return {
|
|
82
|
-
|
|
81
|
+
notices: machineFormat ? notice : undefined,
|
|
82
|
+
result: machineFormat ? data : `${notice}\n\n${data}`,
|
|
83
83
|
success: true,
|
|
84
84
|
};
|
|
85
85
|
}
|
|
@@ -185,12 +185,17 @@ export class PostgreSQLUtil {
|
|
|
185
185
|
};
|
|
186
186
|
}
|
|
187
187
|
}
|
|
188
|
+
formatReadResult(rows, fields, format, notices) {
|
|
189
|
+
const rowCount = Array.isArray(rows) ? rows.length : 0;
|
|
190
|
+
notices.push(`Query executed successfully. Rows returned: ${rowCount}`);
|
|
191
|
+
return this.formatRows(rows, fields, format);
|
|
192
|
+
}
|
|
188
193
|
formatRows(rows, fields, format) {
|
|
189
194
|
return FORMATTERS[format](rows, fields);
|
|
190
195
|
}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
return `
|
|
196
|
+
formatWriteResult(affectedRows, notices) {
|
|
197
|
+
notices.push('Query executed successfully.');
|
|
198
|
+
return `Affected rows: ${affectedRows}\n`;
|
|
194
199
|
}
|
|
195
200
|
async getConnection(profileName) {
|
|
196
201
|
const existing = this.connections.get(profileName);
|
package/oclif.manifest.json
CHANGED
|
@@ -6,10 +6,11 @@
|
|
|
6
6
|
"description": "List all databases accessible on the PostgreSQL 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 PostgreSQL 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 PostgreSQL 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 PostgreSQL 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
|
}
|