taurusdb-core 0.1.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 +21 -0
- package/dist/auth/secret-resolver.d.ts +16 -0
- package/dist/auth/secret-resolver.js +64 -0
- package/dist/auth/sql-profile-loader/env-source.d.ts +3 -0
- package/dist/auth/sql-profile-loader/env-source.js +94 -0
- package/dist/auth/sql-profile-loader/file-source.d.ts +6 -0
- package/dist/auth/sql-profile-loader/file-source.js +40 -0
- package/dist/auth/sql-profile-loader/loader.d.ts +16 -0
- package/dist/auth/sql-profile-loader/loader.js +81 -0
- package/dist/auth/sql-profile-loader/parsing.d.ts +14 -0
- package/dist/auth/sql-profile-loader/parsing.js +216 -0
- package/dist/auth/sql-profile-loader/runtime-override.d.ts +14 -0
- package/dist/auth/sql-profile-loader/runtime-override.js +52 -0
- package/dist/auth/sql-profile-loader/types.d.ts +64 -0
- package/dist/auth/sql-profile-loader/types.js +1 -0
- package/dist/auth/sql-profile-loader.d.ts +4 -0
- package/dist/auth/sql-profile-loader.js +3 -0
- package/dist/capability/feature-matrix.d.ts +5 -0
- package/dist/capability/feature-matrix.js +237 -0
- package/dist/capability/probe.d.ts +19 -0
- package/dist/capability/probe.js +139 -0
- package/dist/capability/types.d.ts +49 -0
- package/dist/capability/types.js +16 -0
- package/dist/capability/version.d.ts +3 -0
- package/dist/capability/version.js +47 -0
- package/dist/cloud/auth.d.ts +26 -0
- package/dist/cloud/auth.js +198 -0
- package/dist/cloud/instances.d.ts +46 -0
- package/dist/cloud/instances.js +224 -0
- package/dist/config/env.d.ts +1 -0
- package/dist/config/env.js +194 -0
- package/dist/config/index.d.ts +6 -0
- package/dist/config/index.js +21 -0
- package/dist/config/redaction.d.ts +2 -0
- package/dist/config/redaction.js +19 -0
- package/dist/config/schema.d.ts +417 -0
- package/dist/config/schema.js +100 -0
- package/dist/context/datasource-resolver.d.ts +19 -0
- package/dist/context/datasource-resolver.js +71 -0
- package/dist/context/session-context.d.ts +26 -0
- package/dist/context/session-context.js +1 -0
- package/dist/diagnostics/metrics-source.d.ts +65 -0
- package/dist/diagnostics/metrics-source.js +280 -0
- package/dist/diagnostics/slow-sql-source/das-source.d.ts +43 -0
- package/dist/diagnostics/slow-sql-source/das-source.js +170 -0
- package/dist/diagnostics/slow-sql-source/factory.d.ts +5 -0
- package/dist/diagnostics/slow-sql-source/factory.js +87 -0
- package/dist/diagnostics/slow-sql-source/parsers.d.ts +7 -0
- package/dist/diagnostics/slow-sql-source/parsers.js +125 -0
- package/dist/diagnostics/slow-sql-source/taurus-api-source.d.ts +42 -0
- package/dist/diagnostics/slow-sql-source/taurus-api-source.js +149 -0
- package/dist/diagnostics/slow-sql-source/types.d.ts +40 -0
- package/dist/diagnostics/slow-sql-source/types.js +1 -0
- package/dist/diagnostics/slow-sql-source/utils.d.ts +20 -0
- package/dist/diagnostics/slow-sql-source/utils.js +170 -0
- package/dist/diagnostics/slow-sql-source.d.ts +4 -0
- package/dist/diagnostics/slow-sql-source.js +3 -0
- package/dist/diagnostics/types.d.ts +189 -0
- package/dist/diagnostics/types.js +39 -0
- package/dist/engine/data-access/locks.d.ts +8 -0
- package/dist/engine/data-access/locks.js +146 -0
- package/dist/engine/data-access/processlist.d.ts +4 -0
- package/dist/engine/data-access/processlist.js +56 -0
- package/dist/engine/data-access/statements.d.ts +10 -0
- package/dist/engine/data-access/statements.js +203 -0
- package/dist/engine/data-access/storage.d.ts +6 -0
- package/dist/engine/data-access/storage.js +96 -0
- package/dist/engine/data-access.d.ts +4 -0
- package/dist/engine/data-access.js +4 -0
- package/dist/engine/diagnostics.d.ts +7 -0
- package/dist/engine/diagnostics.js +7 -0
- package/dist/engine/helper-modules/diagnostics.d.ts +57 -0
- package/dist/engine/helper-modules/diagnostics.js +322 -0
- package/dist/engine/helper-modules/parsers.d.ts +13 -0
- package/dist/engine/helper-modules/parsers.js +283 -0
- package/dist/engine/helper-modules/sql.d.ts +12 -0
- package/dist/engine/helper-modules/sql.js +119 -0
- package/dist/engine/helper-modules/types.d.ts +103 -0
- package/dist/engine/helper-modules/types.js +1 -0
- package/dist/engine/helpers.d.ts +4 -0
- package/dist/engine/helpers.js +4 -0
- package/dist/engine/runtime.d.ts +20 -0
- package/dist/engine/runtime.js +385 -0
- package/dist/engine/types.d.ts +125 -0
- package/dist/engine/types.js +1 -0
- package/dist/engine/workflows/connection-spike.d.ts +4 -0
- package/dist/engine/workflows/connection-spike.js +316 -0
- package/dist/engine/workflows/db-hotspot.d.ts +4 -0
- package/dist/engine/workflows/db-hotspot.js +182 -0
- package/dist/engine/workflows/lock-contention-helpers/entities.d.ts +9 -0
- package/dist/engine/workflows/lock-contention-helpers/entities.js +58 -0
- package/dist/engine/workflows/lock-contention-helpers/no-match.d.ts +3 -0
- package/dist/engine/workflows/lock-contention-helpers/no-match.js +65 -0
- package/dist/engine/workflows/lock-contention-helpers/report.d.ts +21 -0
- package/dist/engine/workflows/lock-contention-helpers/report.js +104 -0
- package/dist/engine/workflows/lock-contention-helpers/root-cause.d.ts +4 -0
- package/dist/engine/workflows/lock-contention-helpers/root-cause.js +79 -0
- package/dist/engine/workflows/lock-contention-helpers/signals.d.ts +22 -0
- package/dist/engine/workflows/lock-contention-helpers/signals.js +34 -0
- package/dist/engine/workflows/lock-contention-helpers.d.ts +5 -0
- package/dist/engine/workflows/lock-contention-helpers.js +5 -0
- package/dist/engine/workflows/lock-contention.d.ts +4 -0
- package/dist/engine/workflows/lock-contention.js +67 -0
- package/dist/engine/workflows/service-latency.d.ts +4 -0
- package/dist/engine/workflows/service-latency.js +262 -0
- package/dist/engine/workflows/slow-query-helpers.d.ts +41 -0
- package/dist/engine/workflows/slow-query-helpers.js +253 -0
- package/dist/engine/workflows/slow-query.d.ts +4 -0
- package/dist/engine/workflows/slow-query.js +156 -0
- package/dist/engine/workflows/storage-pressure-helpers.d.ts +12 -0
- package/dist/engine/workflows/storage-pressure-helpers.js +281 -0
- package/dist/engine/workflows/storage-pressure.d.ts +4 -0
- package/dist/engine/workflows/storage-pressure.js +27 -0
- package/dist/engine/workflows/top-slow-sql.d.ts +4 -0
- package/dist/engine/workflows/top-slow-sql.js +222 -0
- package/dist/engine.d.ts +77 -0
- package/dist/engine.js +240 -0
- package/dist/executor/adapters/mysql.d.ts +2 -0
- package/dist/executor/adapters/mysql.js +114 -0
- package/dist/executor/connection-pool.d.ts +105 -0
- package/dist/executor/connection-pool.js +236 -0
- package/dist/executor/explain.d.ts +5 -0
- package/dist/executor/explain.js +119 -0
- package/dist/executor/query-tracker.d.ts +45 -0
- package/dist/executor/query-tracker.js +83 -0
- package/dist/executor/result-normalizer.d.ts +6 -0
- package/dist/executor/result-normalizer.js +47 -0
- package/dist/executor/sql-executor.d.ts +32 -0
- package/dist/executor/sql-executor.js +250 -0
- package/dist/executor/types.d.ts +70 -0
- package/dist/executor/types.js +1 -0
- package/dist/index.d.ts +40 -0
- package/dist/index.js +21 -0
- package/dist/safety/confirmation-store.d.ts +44 -0
- package/dist/safety/confirmation-store.js +130 -0
- package/dist/safety/guardrail.d.ts +39 -0
- package/dist/safety/guardrail.js +99 -0
- package/dist/safety/parser/adapter.d.ts +10 -0
- package/dist/safety/parser/adapter.js +72 -0
- package/dist/safety/parser/ast-utils.d.ts +10 -0
- package/dist/safety/parser/ast-utils.js +167 -0
- package/dist/safety/parser/features.d.ts +12 -0
- package/dist/safety/parser/features.js +113 -0
- package/dist/safety/parser/index.d.ts +2 -0
- package/dist/safety/parser/index.js +1 -0
- package/dist/safety/parser/types.d.ts +76 -0
- package/dist/safety/parser/types.js +1 -0
- package/dist/safety/redaction.d.ts +34 -0
- package/dist/safety/redaction.js +186 -0
- package/dist/safety/sql-classifier.d.ts +19 -0
- package/dist/safety/sql-classifier.js +43 -0
- package/dist/safety/sql-validator.d.ts +19 -0
- package/dist/safety/sql-validator.js +143 -0
- package/dist/schema/adapters/mysql.d.ts +16 -0
- package/dist/schema/adapters/mysql.js +287 -0
- package/dist/schema/introspector.d.ts +70 -0
- package/dist/schema/introspector.js +40 -0
- package/dist/taurus/flashback.d.ts +36 -0
- package/dist/taurus/flashback.js +149 -0
- package/dist/taurus/recycle-bin.d.ts +14 -0
- package/dist/taurus/recycle-bin.js +61 -0
- package/dist/utils/formatter.d.ts +70 -0
- package/dist/utils/formatter.js +60 -0
- package/dist/utils/hash.d.ts +2 -0
- package/dist/utils/hash.js +247 -0
- package/dist/utils/id.d.ts +2 -0
- package/dist/utils/id.js +11 -0
- package/dist/utils/logger.d.ts +9 -0
- package/dist/utils/logger.js +39 -0
- package/package.json +46 -0
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
export function parseProcesslistRows(result) {
|
|
2
|
+
const columns = result.columns.map((column) => column.name);
|
|
3
|
+
return result.rows.map((row) => {
|
|
4
|
+
const mapped = Object.fromEntries(columns.map((name, index) => [name, row[index]]));
|
|
5
|
+
const timeValue = mapped.time_seconds;
|
|
6
|
+
return {
|
|
7
|
+
sessionId: mapped.session_id === undefined ? undefined : String(mapped.session_id),
|
|
8
|
+
user: typeof mapped.user === "string" ? mapped.user : undefined,
|
|
9
|
+
host: typeof mapped.host === "string" ? mapped.host : undefined,
|
|
10
|
+
databaseName: typeof mapped.database_name === "string"
|
|
11
|
+
? mapped.database_name
|
|
12
|
+
: undefined,
|
|
13
|
+
command: typeof mapped.command === "string" ? mapped.command : undefined,
|
|
14
|
+
timeSeconds: typeof timeValue === "number"
|
|
15
|
+
? timeValue
|
|
16
|
+
: typeof timeValue === "string" && timeValue.trim().length > 0
|
|
17
|
+
? Number.parseInt(timeValue, 10)
|
|
18
|
+
: undefined,
|
|
19
|
+
state: typeof mapped.state === "string" ? mapped.state : undefined,
|
|
20
|
+
infoPreview: typeof mapped.info_preview === "string"
|
|
21
|
+
? mapped.info_preview
|
|
22
|
+
: undefined,
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export function parseOptionalInteger(value) {
|
|
27
|
+
return typeof value === "number"
|
|
28
|
+
? value
|
|
29
|
+
: typeof value === "string" && value.trim().length > 0
|
|
30
|
+
? Number.parseInt(value, 10)
|
|
31
|
+
: undefined;
|
|
32
|
+
}
|
|
33
|
+
export function parseLockWaitRows(result) {
|
|
34
|
+
const columns = result.columns.map((column) => column.name);
|
|
35
|
+
return result.rows.map((row) => {
|
|
36
|
+
const mapped = Object.fromEntries(columns.map((name, index) => [name, row[index]]));
|
|
37
|
+
return {
|
|
38
|
+
waitingSessionId: mapped.waiting_session_id === undefined
|
|
39
|
+
? undefined
|
|
40
|
+
: String(mapped.waiting_session_id),
|
|
41
|
+
waitingUser: typeof mapped.waiting_user === "string"
|
|
42
|
+
? mapped.waiting_user
|
|
43
|
+
: undefined,
|
|
44
|
+
waitingState: typeof mapped.waiting_state === "string"
|
|
45
|
+
? mapped.waiting_state
|
|
46
|
+
: undefined,
|
|
47
|
+
waitingTrxState: typeof mapped.waiting_trx_state === "string"
|
|
48
|
+
? mapped.waiting_trx_state
|
|
49
|
+
: undefined,
|
|
50
|
+
waitAgeSeconds: parseOptionalInteger(mapped.wait_age_seconds),
|
|
51
|
+
blockingSessionId: mapped.blocking_session_id === undefined
|
|
52
|
+
? undefined
|
|
53
|
+
: String(mapped.blocking_session_id),
|
|
54
|
+
blockingUser: typeof mapped.blocking_user === "string"
|
|
55
|
+
? mapped.blocking_user
|
|
56
|
+
: undefined,
|
|
57
|
+
blockingState: typeof mapped.blocking_state === "string"
|
|
58
|
+
? mapped.blocking_state
|
|
59
|
+
: undefined,
|
|
60
|
+
blockingTrxState: typeof mapped.blocking_trx_state === "string"
|
|
61
|
+
? mapped.blocking_trx_state
|
|
62
|
+
: undefined,
|
|
63
|
+
blockingTrxAgeSeconds: parseOptionalInteger(mapped.blocking_trx_age_seconds),
|
|
64
|
+
lockedSchema: typeof mapped.locked_schema === "string"
|
|
65
|
+
? mapped.locked_schema
|
|
66
|
+
: undefined,
|
|
67
|
+
lockedTable: typeof mapped.locked_table === "string"
|
|
68
|
+
? mapped.locked_table
|
|
69
|
+
: undefined,
|
|
70
|
+
lockedIndex: typeof mapped.locked_index === "string"
|
|
71
|
+
? mapped.locked_index
|
|
72
|
+
: undefined,
|
|
73
|
+
waitingLockType: typeof mapped.waiting_lock_type === "string"
|
|
74
|
+
? mapped.waiting_lock_type
|
|
75
|
+
: undefined,
|
|
76
|
+
waitingLockMode: typeof mapped.waiting_lock_mode === "string"
|
|
77
|
+
? mapped.waiting_lock_mode
|
|
78
|
+
: undefined,
|
|
79
|
+
blockingLockType: typeof mapped.blocking_lock_type === "string"
|
|
80
|
+
? mapped.blocking_lock_type
|
|
81
|
+
: undefined,
|
|
82
|
+
blockingLockMode: typeof mapped.blocking_lock_mode === "string"
|
|
83
|
+
? mapped.blocking_lock_mode
|
|
84
|
+
: undefined,
|
|
85
|
+
waitingQuery: typeof mapped.waiting_query === "string"
|
|
86
|
+
? mapped.waiting_query
|
|
87
|
+
: undefined,
|
|
88
|
+
blockingQuery: typeof mapped.blocking_query === "string"
|
|
89
|
+
? mapped.blocking_query
|
|
90
|
+
: undefined,
|
|
91
|
+
};
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
export function isIdleTransactionBlocker(row) {
|
|
95
|
+
return (row.blockingSessionId !== undefined &&
|
|
96
|
+
row.blockingTrxState !== undefined &&
|
|
97
|
+
(row.blockingState === undefined || row.blockingState === "Sleep"));
|
|
98
|
+
}
|
|
99
|
+
export function parseOptionalNumber(value) {
|
|
100
|
+
return typeof value === "number"
|
|
101
|
+
? value
|
|
102
|
+
: typeof value === "string" && value.trim().length > 0
|
|
103
|
+
? Number.parseFloat(value)
|
|
104
|
+
: undefined;
|
|
105
|
+
}
|
|
106
|
+
export function parseMetadataLockRows(result) {
|
|
107
|
+
const columns = result.columns.map((column) => column.name);
|
|
108
|
+
return result.rows.map((row) => {
|
|
109
|
+
const mapped = Object.fromEntries(columns.map((name, index) => [name, row[index]]));
|
|
110
|
+
return {
|
|
111
|
+
waitingSessionId: mapped.waiting_session_id === undefined
|
|
112
|
+
? undefined
|
|
113
|
+
: String(mapped.waiting_session_id),
|
|
114
|
+
waitingUser: typeof mapped.waiting_user === "string"
|
|
115
|
+
? mapped.waiting_user
|
|
116
|
+
: undefined,
|
|
117
|
+
waitingState: typeof mapped.waiting_state === "string"
|
|
118
|
+
? mapped.waiting_state
|
|
119
|
+
: undefined,
|
|
120
|
+
blockingSessionId: mapped.blocking_session_id === undefined
|
|
121
|
+
? undefined
|
|
122
|
+
: String(mapped.blocking_session_id),
|
|
123
|
+
blockingUser: typeof mapped.blocking_user === "string"
|
|
124
|
+
? mapped.blocking_user
|
|
125
|
+
: undefined,
|
|
126
|
+
blockingState: typeof mapped.blocking_state === "string"
|
|
127
|
+
? mapped.blocking_state
|
|
128
|
+
: undefined,
|
|
129
|
+
objectType: typeof mapped.object_type === "string" ? mapped.object_type : undefined,
|
|
130
|
+
objectSchema: typeof mapped.object_schema === "string"
|
|
131
|
+
? mapped.object_schema
|
|
132
|
+
: undefined,
|
|
133
|
+
objectName: typeof mapped.object_name === "string" ? mapped.object_name : undefined,
|
|
134
|
+
waitingLockType: typeof mapped.waiting_lock_type === "string"
|
|
135
|
+
? mapped.waiting_lock_type
|
|
136
|
+
: undefined,
|
|
137
|
+
waitingLockDuration: typeof mapped.waiting_lock_duration === "string"
|
|
138
|
+
? mapped.waiting_lock_duration
|
|
139
|
+
: undefined,
|
|
140
|
+
blockingLockType: typeof mapped.blocking_lock_type === "string"
|
|
141
|
+
? mapped.blocking_lock_type
|
|
142
|
+
: undefined,
|
|
143
|
+
blockingLockDuration: typeof mapped.blocking_lock_duration === "string"
|
|
144
|
+
? mapped.blocking_lock_duration
|
|
145
|
+
: undefined,
|
|
146
|
+
};
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
export function parseDeadlockSummary(result) {
|
|
150
|
+
const statusColumnIndex = result.columns.findIndex((column) => column.name.toLowerCase() === "status");
|
|
151
|
+
if (statusColumnIndex < 0 || result.rows.length === 0) {
|
|
152
|
+
return undefined;
|
|
153
|
+
}
|
|
154
|
+
const statusValue = result.rows[0]?.[statusColumnIndex];
|
|
155
|
+
if (typeof statusValue !== "string" || !statusValue.includes("DEADLOCK")) {
|
|
156
|
+
return undefined;
|
|
157
|
+
}
|
|
158
|
+
const startIndex = statusValue.indexOf("LATEST DETECTED DEADLOCK");
|
|
159
|
+
if (startIndex < 0) {
|
|
160
|
+
return undefined;
|
|
161
|
+
}
|
|
162
|
+
const deadlockText = statusValue.slice(startIndex);
|
|
163
|
+
const lines = deadlockText
|
|
164
|
+
.split(/\r?\n/)
|
|
165
|
+
.map((line) => line.trim())
|
|
166
|
+
.filter((line) => line.length > 0 && !/^[-*]{3,}$/.test(line));
|
|
167
|
+
const detectedAt = lines.find((line) => /^\d{4}-\d{2}-\d{2}/.test(line));
|
|
168
|
+
const transactionIds = Array.from(new Set([...deadlockText.matchAll(/TRANSACTION\s+(\d+)/g)].map((match) => match[1])));
|
|
169
|
+
const tableRefs = Array.from(new Set([...deadlockText.matchAll(/table\s+`([^`]+)`\.`([^`]+)`/gi)].map((match) => `${match[1]}.${match[2]}`)));
|
|
170
|
+
const summaryLines = lines
|
|
171
|
+
.filter((line) => !line.startsWith("LATEST DETECTED DEADLOCK") &&
|
|
172
|
+
!/^\d{4}-\d{2}-\d{2}/.test(line))
|
|
173
|
+
.slice(0, 3);
|
|
174
|
+
return {
|
|
175
|
+
detectedAt,
|
|
176
|
+
summary: summaryLines.join(" ").slice(0, 400) ||
|
|
177
|
+
"InnoDB reported a recent deadlock in SHOW ENGINE INNODB STATUS.",
|
|
178
|
+
waitingTables: tableRefs,
|
|
179
|
+
blockingTables: tableRefs,
|
|
180
|
+
transactionIds,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
export function parseStatementDigestRows(result) {
|
|
184
|
+
const columns = result.columns.map((column) => column.name);
|
|
185
|
+
return result.rows.map((row) => {
|
|
186
|
+
const mapped = Object.fromEntries(columns.map((name, index) => [name, row[index]]));
|
|
187
|
+
return {
|
|
188
|
+
schemaName: typeof mapped.schema_name === "string" ? mapped.schema_name : undefined,
|
|
189
|
+
digest: typeof mapped.digest === "string" ? mapped.digest : undefined,
|
|
190
|
+
digestText: typeof mapped.digest_text === "string" ? mapped.digest_text : undefined,
|
|
191
|
+
querySampleText: typeof mapped.query_sample_text === "string"
|
|
192
|
+
? mapped.query_sample_text
|
|
193
|
+
: undefined,
|
|
194
|
+
execCount: parseOptionalInteger(mapped.exec_count),
|
|
195
|
+
avgLatencyMs: parseOptionalNumber(mapped.avg_latency_ms),
|
|
196
|
+
totalLatencyMs: parseOptionalNumber(mapped.total_latency_ms),
|
|
197
|
+
maxLatencyMs: parseOptionalNumber(mapped.max_latency_ms),
|
|
198
|
+
avgLockTimeMs: parseOptionalNumber(mapped.avg_lock_time_ms),
|
|
199
|
+
avgRowsExamined: parseOptionalNumber(mapped.avg_rows_examined),
|
|
200
|
+
avgSortRows: parseOptionalNumber(mapped.avg_sort_rows),
|
|
201
|
+
avgTmpTables: parseOptionalNumber(mapped.avg_tmp_tables),
|
|
202
|
+
avgTmpDiskTables: parseOptionalNumber(mapped.avg_tmp_disk_tables),
|
|
203
|
+
selectScanCount: parseOptionalInteger(mapped.select_scan_count),
|
|
204
|
+
noIndexUsedCount: parseOptionalInteger(mapped.no_index_used_count),
|
|
205
|
+
};
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
export function parseStatementWaitEventRows(result) {
|
|
209
|
+
const columns = result.columns.map((column) => column.name);
|
|
210
|
+
return result.rows.map((row) => {
|
|
211
|
+
const mapped = Object.fromEntries(columns.map((name, index) => [name, row[index]]));
|
|
212
|
+
return {
|
|
213
|
+
eventName: typeof mapped.event_name === "string" ? mapped.event_name : undefined,
|
|
214
|
+
sampleCount: parseOptionalInteger(mapped.sample_count),
|
|
215
|
+
statementCount: parseOptionalInteger(mapped.statement_count),
|
|
216
|
+
totalWaitMs: parseOptionalNumber(mapped.total_wait_ms),
|
|
217
|
+
avgWaitMs: parseOptionalNumber(mapped.avg_wait_ms),
|
|
218
|
+
};
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
export function parseTableStorageRows(result) {
|
|
222
|
+
const columns = result.columns.map((column) => column.name);
|
|
223
|
+
return result.rows.map((row) => {
|
|
224
|
+
const mapped = Object.fromEntries(columns.map((name, index) => [name, row[index]]));
|
|
225
|
+
return {
|
|
226
|
+
schemaName: typeof mapped.schema_name === "string" ? mapped.schema_name : undefined,
|
|
227
|
+
tableName: typeof mapped.table_name === "string" ? mapped.table_name : undefined,
|
|
228
|
+
engine: typeof mapped.engine === "string" ? mapped.engine : undefined,
|
|
229
|
+
rowCountEstimate: parseOptionalInteger(mapped.row_count_estimate),
|
|
230
|
+
totalMb: parseOptionalNumber(mapped.total_mb),
|
|
231
|
+
dataMb: parseOptionalNumber(mapped.data_mb),
|
|
232
|
+
indexMb: parseOptionalNumber(mapped.index_mb),
|
|
233
|
+
dataFreeMb: parseOptionalNumber(mapped.data_free_mb),
|
|
234
|
+
};
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
export function parseReplicationStatusRows(result) {
|
|
238
|
+
const columns = result.columns.map((column) => column.name);
|
|
239
|
+
return result.rows
|
|
240
|
+
.map((row) => {
|
|
241
|
+
const mapped = Object.fromEntries(columns.map((name, index) => [name, row[index]]));
|
|
242
|
+
const parsed = {
|
|
243
|
+
channelName: typeof mapped.Channel_Name === "string"
|
|
244
|
+
? mapped.Channel_Name
|
|
245
|
+
: typeof mapped.channel_name === "string"
|
|
246
|
+
? mapped.channel_name
|
|
247
|
+
: undefined,
|
|
248
|
+
replicaIoRunning: typeof mapped.Replica_IO_Running === "string"
|
|
249
|
+
? mapped.Replica_IO_Running
|
|
250
|
+
: typeof mapped.Slave_IO_Running === "string"
|
|
251
|
+
? mapped.Slave_IO_Running
|
|
252
|
+
: undefined,
|
|
253
|
+
replicaSqlRunning: typeof mapped.Replica_SQL_Running === "string"
|
|
254
|
+
? mapped.Replica_SQL_Running
|
|
255
|
+
: typeof mapped.Slave_SQL_Running === "string"
|
|
256
|
+
? mapped.Slave_SQL_Running
|
|
257
|
+
: undefined,
|
|
258
|
+
secondsBehindSource: parseOptionalNumber(mapped.Seconds_Behind_Source) ??
|
|
259
|
+
parseOptionalNumber(mapped.Seconds_Behind_Master),
|
|
260
|
+
retrievedGtidSet: typeof mapped.Retrieved_Gtid_Set === "string"
|
|
261
|
+
? mapped.Retrieved_Gtid_Set
|
|
262
|
+
: undefined,
|
|
263
|
+
executedGtidSet: typeof mapped.Executed_Gtid_Set === "string"
|
|
264
|
+
? mapped.Executed_Gtid_Set
|
|
265
|
+
: undefined,
|
|
266
|
+
lastIoError: typeof mapped.Last_IO_Error === "string" &&
|
|
267
|
+
mapped.Last_IO_Error.length > 0
|
|
268
|
+
? mapped.Last_IO_Error
|
|
269
|
+
: undefined,
|
|
270
|
+
lastSqlError: typeof mapped.Last_SQL_Error === "string" &&
|
|
271
|
+
mapped.Last_SQL_Error.length > 0
|
|
272
|
+
? mapped.Last_SQL_Error
|
|
273
|
+
: undefined,
|
|
274
|
+
};
|
|
275
|
+
return parsed;
|
|
276
|
+
})
|
|
277
|
+
.filter((row) => row.channelName !== undefined ||
|
|
278
|
+
row.replicaIoRunning !== undefined ||
|
|
279
|
+
row.replicaSqlRunning !== undefined ||
|
|
280
|
+
row.secondsBehindSource !== undefined ||
|
|
281
|
+
row.lastIoError !== undefined ||
|
|
282
|
+
row.lastSqlError !== undefined);
|
|
283
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { FindTopSlowSqlInput } from "../../diagnostics/types.js";
|
|
2
|
+
import type { ExplainResult } from "../../executor/sql-executor.js";
|
|
3
|
+
import type { StatementDigestRow } from "./types.js";
|
|
4
|
+
export declare function withDatasourceSummary(prefix: string, datasource: string): string;
|
|
5
|
+
export declare function quoteLiteral(value: string): string;
|
|
6
|
+
export declare function escapeLikePrefix(value: string): string;
|
|
7
|
+
export declare function clampInteger(value: number | undefined, fallback: number, min: number, max: number): number;
|
|
8
|
+
export declare function topSlowSqlOrderBy(sortBy: FindTopSlowSqlInput["sortBy"]): string;
|
|
9
|
+
export declare function normalizeSqlForDigestMatch(sql: string): string;
|
|
10
|
+
export declare function digestMatchScore(sql: string, candidate: StatementDigestRow): number;
|
|
11
|
+
export declare function extractPlanTableNames(plan: ExplainResult["plan"]): string[];
|
|
12
|
+
export declare function extractSqlTableNameHints(sql: string): string[];
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { normalizeSql, sqlHash } from "../../utils/hash.js";
|
|
2
|
+
export function withDatasourceSummary(prefix, datasource) {
|
|
3
|
+
return `${prefix} on datasource ${datasource}.`;
|
|
4
|
+
}
|
|
5
|
+
export function quoteLiteral(value) {
|
|
6
|
+
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "''")}'`;
|
|
7
|
+
}
|
|
8
|
+
export function escapeLikePrefix(value) {
|
|
9
|
+
return value.replace(/\\/g, "\\\\").replace(/[%_]/g, "\\$&");
|
|
10
|
+
}
|
|
11
|
+
export function clampInteger(value, fallback, min, max) {
|
|
12
|
+
if (value === undefined || !Number.isInteger(value)) {
|
|
13
|
+
return fallback;
|
|
14
|
+
}
|
|
15
|
+
return Math.min(Math.max(value, min), max);
|
|
16
|
+
}
|
|
17
|
+
export function topSlowSqlOrderBy(sortBy) {
|
|
18
|
+
switch (sortBy) {
|
|
19
|
+
case "avg_latency":
|
|
20
|
+
return "AVG_TIMER_WAIT DESC, SUM_TIMER_WAIT DESC, COUNT_STAR DESC";
|
|
21
|
+
case "exec_count":
|
|
22
|
+
return "COUNT_STAR DESC, SUM_TIMER_WAIT DESC, AVG_TIMER_WAIT DESC";
|
|
23
|
+
case "lock_time":
|
|
24
|
+
return "SUM_LOCK_TIME DESC, SUM_TIMER_WAIT DESC, COUNT_STAR DESC";
|
|
25
|
+
case "total_latency":
|
|
26
|
+
default:
|
|
27
|
+
return "SUM_TIMER_WAIT DESC, AVG_TIMER_WAIT DESC, COUNT_STAR DESC";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
export function normalizeSqlForDigestMatch(sql) {
|
|
31
|
+
const normalized = normalizeSql(sql).replace(/`([^`]+)`/g, "$1");
|
|
32
|
+
let result = "";
|
|
33
|
+
let index = 0;
|
|
34
|
+
let quoteState = "none";
|
|
35
|
+
while (index < normalized.length) {
|
|
36
|
+
const char = normalized[index];
|
|
37
|
+
if (quoteState === "none") {
|
|
38
|
+
if (char === "'" || char === '"') {
|
|
39
|
+
quoteState = char;
|
|
40
|
+
result += "?";
|
|
41
|
+
index += 1;
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (/[0-9]/.test(char) &&
|
|
45
|
+
(index === 0 || !/[A-Za-z0-9_$]/.test(normalized[index - 1] ?? ""))) {
|
|
46
|
+
result += "?";
|
|
47
|
+
index += 1;
|
|
48
|
+
while (index < normalized.length &&
|
|
49
|
+
/[A-Za-z0-9_.+-]/.test(normalized[index])) {
|
|
50
|
+
index += 1;
|
|
51
|
+
}
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
result += char;
|
|
55
|
+
index += 1;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (char === quoteState) {
|
|
59
|
+
if (normalized[index + 1] === quoteState) {
|
|
60
|
+
index += 2;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
quoteState = "none";
|
|
64
|
+
}
|
|
65
|
+
index += 1;
|
|
66
|
+
}
|
|
67
|
+
return result
|
|
68
|
+
.replace(/\bNULL\b/gi, "?")
|
|
69
|
+
.replace(/\b(TRUE|FALSE)\b/gi, "?")
|
|
70
|
+
.replace(/\s*([=<>!+\-*/%,()])\s*/g, "$1")
|
|
71
|
+
.replace(/\s+/g, " ")
|
|
72
|
+
.trim()
|
|
73
|
+
.toUpperCase();
|
|
74
|
+
}
|
|
75
|
+
export function digestMatchScore(sql, candidate) {
|
|
76
|
+
const normalizedSql = normalizeSql(sql);
|
|
77
|
+
const normalizedSqlHash = sqlHash(normalizedSql);
|
|
78
|
+
const sqlShape = normalizeSqlForDigestMatch(sql);
|
|
79
|
+
if (candidate.querySampleText &&
|
|
80
|
+
sqlHash(normalizeSql(candidate.querySampleText)) === normalizedSqlHash) {
|
|
81
|
+
return 100;
|
|
82
|
+
}
|
|
83
|
+
if (candidate.querySampleText &&
|
|
84
|
+
normalizeSqlForDigestMatch(candidate.querySampleText) === sqlShape) {
|
|
85
|
+
return 80;
|
|
86
|
+
}
|
|
87
|
+
if (candidate.digestText &&
|
|
88
|
+
normalizeSqlForDigestMatch(candidate.digestText) === sqlShape) {
|
|
89
|
+
return 70;
|
|
90
|
+
}
|
|
91
|
+
return 0;
|
|
92
|
+
}
|
|
93
|
+
export function extractPlanTableNames(plan) {
|
|
94
|
+
const names = plan
|
|
95
|
+
.map((row) => {
|
|
96
|
+
if (!row || typeof row !== "object") {
|
|
97
|
+
return undefined;
|
|
98
|
+
}
|
|
99
|
+
const candidate = row.table ??
|
|
100
|
+
row.table_name ??
|
|
101
|
+
row.TABLE;
|
|
102
|
+
return typeof candidate === "string" ? candidate.trim() : undefined;
|
|
103
|
+
})
|
|
104
|
+
.filter((value) => typeof value === "string" &&
|
|
105
|
+
value.length > 0 &&
|
|
106
|
+
value.toUpperCase() !== "NULL" &&
|
|
107
|
+
!value.startsWith("<"));
|
|
108
|
+
return [...new Set(names)];
|
|
109
|
+
}
|
|
110
|
+
export function extractSqlTableNameHints(sql) {
|
|
111
|
+
const hints = new Set();
|
|
112
|
+
const pattern = /\b(?:FROM|JOIN|UPDATE|INTO)\s+`?([A-Za-z0-9_$]+)`?(?:\s*\.\s*`?([A-Za-z0-9_$]+)`?)?/gi;
|
|
113
|
+
let match = pattern.exec(sql);
|
|
114
|
+
while (match) {
|
|
115
|
+
hints.add(match[2] ?? match[1]);
|
|
116
|
+
match = pattern.exec(sql);
|
|
117
|
+
}
|
|
118
|
+
return [...hints];
|
|
119
|
+
}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
export type ProcesslistRow = {
|
|
2
|
+
sessionId?: string;
|
|
3
|
+
user?: string;
|
|
4
|
+
host?: string;
|
|
5
|
+
databaseName?: string;
|
|
6
|
+
command?: string;
|
|
7
|
+
timeSeconds?: number;
|
|
8
|
+
state?: string;
|
|
9
|
+
infoPreview?: string;
|
|
10
|
+
};
|
|
11
|
+
export type LockWaitRow = {
|
|
12
|
+
waitingSessionId?: string;
|
|
13
|
+
waitingUser?: string;
|
|
14
|
+
waitingState?: string;
|
|
15
|
+
waitingTrxState?: string;
|
|
16
|
+
waitAgeSeconds?: number;
|
|
17
|
+
blockingSessionId?: string;
|
|
18
|
+
blockingUser?: string;
|
|
19
|
+
blockingState?: string;
|
|
20
|
+
blockingTrxState?: string;
|
|
21
|
+
blockingTrxAgeSeconds?: number;
|
|
22
|
+
lockedSchema?: string;
|
|
23
|
+
lockedTable?: string;
|
|
24
|
+
lockedIndex?: string;
|
|
25
|
+
waitingLockType?: string;
|
|
26
|
+
waitingLockMode?: string;
|
|
27
|
+
blockingLockType?: string;
|
|
28
|
+
blockingLockMode?: string;
|
|
29
|
+
waitingQuery?: string;
|
|
30
|
+
blockingQuery?: string;
|
|
31
|
+
};
|
|
32
|
+
export type MetadataLockRow = {
|
|
33
|
+
waitingSessionId?: string;
|
|
34
|
+
waitingUser?: string;
|
|
35
|
+
waitingState?: string;
|
|
36
|
+
blockingSessionId?: string;
|
|
37
|
+
blockingUser?: string;
|
|
38
|
+
blockingState?: string;
|
|
39
|
+
objectType?: string;
|
|
40
|
+
objectSchema?: string;
|
|
41
|
+
objectName?: string;
|
|
42
|
+
waitingLockType?: string;
|
|
43
|
+
waitingLockDuration?: string;
|
|
44
|
+
blockingLockType?: string;
|
|
45
|
+
blockingLockDuration?: string;
|
|
46
|
+
};
|
|
47
|
+
export type DeadlockSummary = {
|
|
48
|
+
detectedAt?: string;
|
|
49
|
+
summary: string;
|
|
50
|
+
waitingTables: string[];
|
|
51
|
+
blockingTables: string[];
|
|
52
|
+
transactionIds: string[];
|
|
53
|
+
};
|
|
54
|
+
export type StatementDigestRow = {
|
|
55
|
+
schemaName?: string;
|
|
56
|
+
digest?: string;
|
|
57
|
+
digestText?: string;
|
|
58
|
+
querySampleText?: string;
|
|
59
|
+
execCount?: number;
|
|
60
|
+
avgLatencyMs?: number;
|
|
61
|
+
totalLatencyMs?: number;
|
|
62
|
+
maxLatencyMs?: number;
|
|
63
|
+
avgLockTimeMs?: number;
|
|
64
|
+
avgRowsExamined?: number;
|
|
65
|
+
avgSortRows?: number;
|
|
66
|
+
avgTmpTables?: number;
|
|
67
|
+
avgTmpDiskTables?: number;
|
|
68
|
+
selectScanCount?: number;
|
|
69
|
+
noIndexUsedCount?: number;
|
|
70
|
+
};
|
|
71
|
+
export type StatementWaitEventRow = {
|
|
72
|
+
eventName?: string;
|
|
73
|
+
sampleCount?: number;
|
|
74
|
+
statementCount?: number;
|
|
75
|
+
totalWaitMs?: number;
|
|
76
|
+
avgWaitMs?: number;
|
|
77
|
+
};
|
|
78
|
+
export type PlanTableStats = {
|
|
79
|
+
table: string;
|
|
80
|
+
rowCountEstimate?: number;
|
|
81
|
+
indexCount: number;
|
|
82
|
+
primaryKey?: string[];
|
|
83
|
+
};
|
|
84
|
+
export type TableStorageRow = {
|
|
85
|
+
schemaName?: string;
|
|
86
|
+
tableName?: string;
|
|
87
|
+
engine?: string;
|
|
88
|
+
rowCountEstimate?: number;
|
|
89
|
+
totalMb?: number;
|
|
90
|
+
dataMb?: number;
|
|
91
|
+
indexMb?: number;
|
|
92
|
+
dataFreeMb?: number;
|
|
93
|
+
};
|
|
94
|
+
export type ReplicationStatusRow = {
|
|
95
|
+
channelName?: string;
|
|
96
|
+
replicaIoRunning?: string;
|
|
97
|
+
replicaSqlRunning?: string;
|
|
98
|
+
secondsBehindSource?: number;
|
|
99
|
+
retrievedGtidSet?: string;
|
|
100
|
+
executedGtidSet?: string;
|
|
101
|
+
lastIoError?: string;
|
|
102
|
+
lastSqlError?: string;
|
|
103
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { SessionContext } from "../context/session-context.js";
|
|
2
|
+
import type { CancelResult, ExplainResult, MutationOptions, MutationResult, QueryResult, QueryStatus, ReadonlyOptions } from "../executor/sql-executor.js";
|
|
3
|
+
import type { ConfirmationToken, ConfirmationValidationResult } from "../safety/confirmation-store.js";
|
|
4
|
+
import type { GuardrailDecision } from "../safety/guardrail.js";
|
|
5
|
+
import { type FlashbackInput } from "../taurus/flashback.js";
|
|
6
|
+
import { type RestoreRecycleBinTableInput } from "../taurus/recycle-bin.js";
|
|
7
|
+
import type { ConfirmationOutcome, EnhancedExplainResult, IssueConfirmationInput, TaurusDBEngine } from "../engine.js";
|
|
8
|
+
export declare function explain(engine: TaurusDBEngine, sql: string, ctx: SessionContext): Promise<ExplainResult>;
|
|
9
|
+
export declare function explainEnhanced(engine: TaurusDBEngine, sql: string, ctx: SessionContext): Promise<EnhancedExplainResult>;
|
|
10
|
+
export declare function executeReadonly(engine: TaurusDBEngine, sql: string, ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
11
|
+
export declare function executeMutation(engine: TaurusDBEngine, sql: string, ctx: SessionContext, opts?: MutationOptions): Promise<MutationResult>;
|
|
12
|
+
export declare function flashbackQuery(engine: TaurusDBEngine, input: FlashbackInput, ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
13
|
+
export declare function listRecycleBin(engine: TaurusDBEngine, ctx: SessionContext, opts?: ReadonlyOptions): Promise<QueryResult>;
|
|
14
|
+
export declare function restoreRecycleBinTable(engine: TaurusDBEngine, input: RestoreRecycleBinTableInput, ctx: SessionContext, opts?: MutationOptions): Promise<MutationResult>;
|
|
15
|
+
export declare function getQueryStatus(engine: TaurusDBEngine, queryId: string): Promise<QueryStatus>;
|
|
16
|
+
export declare function cancelQuery(engine: TaurusDBEngine, queryId: string): Promise<CancelResult>;
|
|
17
|
+
export declare function issueConfirmation(engine: TaurusDBEngine, input: IssueConfirmationInput): Promise<ConfirmationToken>;
|
|
18
|
+
export declare function validateConfirmation(engine: TaurusDBEngine, token: string, sql: string, ctx: SessionContext): Promise<ConfirmationValidationResult>;
|
|
19
|
+
export declare function handleConfirmation(engine: TaurusDBEngine, decision: GuardrailDecision, ctx: SessionContext): Promise<ConfirmationOutcome>;
|
|
20
|
+
export declare function close(engine: TaurusDBEngine): Promise<void>;
|