@blogic-cz/agent-tools 0.14.45 → 0.14.46
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/package.json
CHANGED
package/src/db-tool/index.ts
CHANGED
|
@@ -64,16 +64,21 @@ const sqlCommand = Command.make(
|
|
|
64
64
|
),
|
|
65
65
|
),
|
|
66
66
|
sql: Flag.string("sql").pipe(Flag.withDescription("SQL query to execute")),
|
|
67
|
+
limit: Flag.optional(Flag.integer("limit")).pipe(
|
|
68
|
+
Flag.withDescription(
|
|
69
|
+
"Max rows to return (default 50). Use 0 for no cap. Prefer a SQL LIMIT for large tables.",
|
|
70
|
+
),
|
|
71
|
+
),
|
|
67
72
|
format: formatOption,
|
|
68
73
|
profile: Flag.optional(Flag.string("profile")).pipe(
|
|
69
74
|
Flag.withDescription("Database profile name from agent-tools.json5 (if multiple configured)"),
|
|
70
75
|
),
|
|
71
76
|
},
|
|
72
|
-
({ env, sql, format }) =>
|
|
77
|
+
({ env, sql, limit, format }) =>
|
|
73
78
|
Effect.gen(function* () {
|
|
74
79
|
const resolvedEnv = yield* resolveEnv(env);
|
|
75
80
|
const db = yield* DbService;
|
|
76
|
-
const result = yield* db.executeQuery(resolvedEnv, sql);
|
|
81
|
+
const result = yield* db.executeQuery(resolvedEnv, sql, Option.getOrUndefined(limit));
|
|
77
82
|
yield* Console.log(formatOutput(result, format));
|
|
78
83
|
}),
|
|
79
84
|
).pipe(Command.withDescription("Execute a SQL query"));
|
package/src/db-tool/service.ts
CHANGED
|
@@ -59,7 +59,11 @@ export { buildApiProbeArgs } from "#shared/k8s-probe";
|
|
|
59
59
|
export class DbService extends Context.Service<
|
|
60
60
|
DbService,
|
|
61
61
|
{
|
|
62
|
-
readonly executeQuery: (
|
|
62
|
+
readonly executeQuery: (
|
|
63
|
+
env: string,
|
|
64
|
+
sql: string,
|
|
65
|
+
limit?: number,
|
|
66
|
+
) => Effect.Effect<QueryResult, DbError>;
|
|
63
67
|
readonly executeSchemaQuery: (
|
|
64
68
|
env: string,
|
|
65
69
|
mode: SchemaMode,
|
|
@@ -83,7 +87,8 @@ export class DbService extends Context.Service<
|
|
|
83
87
|
environment: env,
|
|
84
88
|
});
|
|
85
89
|
return {
|
|
86
|
-
executeQuery: (env: string, _sql: string) =>
|
|
90
|
+
executeQuery: (env: string, _sql: string, _limit?: number) =>
|
|
91
|
+
Effect.fail(noConfigError(env)),
|
|
87
92
|
executeSchemaQuery: (env: string, _mode: SchemaMode, _table?: string) =>
|
|
88
93
|
Effect.fail(noConfigError(env)),
|
|
89
94
|
};
|
|
@@ -468,6 +473,7 @@ export class DbService extends Context.Service<
|
|
|
468
473
|
password: string,
|
|
469
474
|
startTimeMs: number,
|
|
470
475
|
applyTransform = false,
|
|
476
|
+
limit?: number,
|
|
471
477
|
) {
|
|
472
478
|
const selectSql = sql.trim().replace(/;\s*$/, "");
|
|
473
479
|
const wrappedSql = `SELECT json_agg(t) FROM (${selectSql}) t;`;
|
|
@@ -532,7 +538,7 @@ export class DbService extends Context.Service<
|
|
|
532
538
|
});
|
|
533
539
|
|
|
534
540
|
const transformed = applyTransform
|
|
535
|
-
? transformQueryResult(rawData)
|
|
541
|
+
? transformQueryResult(rawData, limit)
|
|
536
542
|
: {
|
|
537
543
|
data: rawData,
|
|
538
544
|
showing: rawData.length,
|
|
@@ -720,6 +726,7 @@ export class DbService extends Context.Service<
|
|
|
720
726
|
const executeQuery = Effect.fn("DbService.executeQuery")(function* (
|
|
721
727
|
env: string,
|
|
722
728
|
sql: string,
|
|
729
|
+
limit?: number,
|
|
723
730
|
) {
|
|
724
731
|
const config = yield* getConfigForEnv(env);
|
|
725
732
|
const startTimeMs = yield* Clock.currentTimeMillis;
|
|
@@ -753,7 +760,7 @@ export class DbService extends Context.Service<
|
|
|
753
760
|
|
|
754
761
|
const queryEffect = mutation
|
|
755
762
|
? executeMutationQuery(resolvedConfig, sql, password, Number(startTimeMs))
|
|
756
|
-
: executeSelectQuery(resolvedConfig, sql, password, Number(startTimeMs), true);
|
|
763
|
+
: executeSelectQuery(resolvedConfig, sql, password, Number(startTimeMs), true, limit);
|
|
757
764
|
|
|
758
765
|
return yield* runWithVpnPrerequisites(
|
|
759
766
|
resolvedConfig.port,
|
|
@@ -22,12 +22,17 @@ function truncateValue(value: unknown): unknown {
|
|
|
22
22
|
return `${value.slice(0, MAX_VALUE_LENGTH)}...`;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
-
export function transformQueryResult(
|
|
25
|
+
export function transformQueryResult(
|
|
26
|
+
data: Record<string, unknown>[],
|
|
27
|
+
// limit 0 (or negative) means "no row cap".
|
|
28
|
+
limit: number = DEFAULT_ROW_LIMIT,
|
|
29
|
+
): TransformResult {
|
|
26
30
|
const withoutEmptyColumns = stripEmptyColumns(data);
|
|
27
31
|
const truncatedValues = withoutEmptyColumns.map((record) =>
|
|
28
32
|
Object.fromEntries(Object.entries(record).map(([key, value]) => [key, truncateValue(value)])),
|
|
29
33
|
);
|
|
30
|
-
const
|
|
34
|
+
const effectiveLimit = limit > 0 ? limit : Number.POSITIVE_INFINITY;
|
|
35
|
+
const { rows, truncated, total, showing } = truncateRows(truncatedValues, effectiveLimit);
|
|
31
36
|
|
|
32
37
|
return {
|
|
33
38
|
data: rows,
|