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.
Files changed (170) hide show
  1. package/README.md +21 -0
  2. package/dist/auth/secret-resolver.d.ts +16 -0
  3. package/dist/auth/secret-resolver.js +64 -0
  4. package/dist/auth/sql-profile-loader/env-source.d.ts +3 -0
  5. package/dist/auth/sql-profile-loader/env-source.js +94 -0
  6. package/dist/auth/sql-profile-loader/file-source.d.ts +6 -0
  7. package/dist/auth/sql-profile-loader/file-source.js +40 -0
  8. package/dist/auth/sql-profile-loader/loader.d.ts +16 -0
  9. package/dist/auth/sql-profile-loader/loader.js +81 -0
  10. package/dist/auth/sql-profile-loader/parsing.d.ts +14 -0
  11. package/dist/auth/sql-profile-loader/parsing.js +216 -0
  12. package/dist/auth/sql-profile-loader/runtime-override.d.ts +14 -0
  13. package/dist/auth/sql-profile-loader/runtime-override.js +52 -0
  14. package/dist/auth/sql-profile-loader/types.d.ts +64 -0
  15. package/dist/auth/sql-profile-loader/types.js +1 -0
  16. package/dist/auth/sql-profile-loader.d.ts +4 -0
  17. package/dist/auth/sql-profile-loader.js +3 -0
  18. package/dist/capability/feature-matrix.d.ts +5 -0
  19. package/dist/capability/feature-matrix.js +237 -0
  20. package/dist/capability/probe.d.ts +19 -0
  21. package/dist/capability/probe.js +139 -0
  22. package/dist/capability/types.d.ts +49 -0
  23. package/dist/capability/types.js +16 -0
  24. package/dist/capability/version.d.ts +3 -0
  25. package/dist/capability/version.js +47 -0
  26. package/dist/cloud/auth.d.ts +26 -0
  27. package/dist/cloud/auth.js +198 -0
  28. package/dist/cloud/instances.d.ts +46 -0
  29. package/dist/cloud/instances.js +224 -0
  30. package/dist/config/env.d.ts +1 -0
  31. package/dist/config/env.js +194 -0
  32. package/dist/config/index.d.ts +6 -0
  33. package/dist/config/index.js +21 -0
  34. package/dist/config/redaction.d.ts +2 -0
  35. package/dist/config/redaction.js +19 -0
  36. package/dist/config/schema.d.ts +417 -0
  37. package/dist/config/schema.js +100 -0
  38. package/dist/context/datasource-resolver.d.ts +19 -0
  39. package/dist/context/datasource-resolver.js +71 -0
  40. package/dist/context/session-context.d.ts +26 -0
  41. package/dist/context/session-context.js +1 -0
  42. package/dist/diagnostics/metrics-source.d.ts +65 -0
  43. package/dist/diagnostics/metrics-source.js +280 -0
  44. package/dist/diagnostics/slow-sql-source/das-source.d.ts +43 -0
  45. package/dist/diagnostics/slow-sql-source/das-source.js +170 -0
  46. package/dist/diagnostics/slow-sql-source/factory.d.ts +5 -0
  47. package/dist/diagnostics/slow-sql-source/factory.js +87 -0
  48. package/dist/diagnostics/slow-sql-source/parsers.d.ts +7 -0
  49. package/dist/diagnostics/slow-sql-source/parsers.js +125 -0
  50. package/dist/diagnostics/slow-sql-source/taurus-api-source.d.ts +42 -0
  51. package/dist/diagnostics/slow-sql-source/taurus-api-source.js +149 -0
  52. package/dist/diagnostics/slow-sql-source/types.d.ts +40 -0
  53. package/dist/diagnostics/slow-sql-source/types.js +1 -0
  54. package/dist/diagnostics/slow-sql-source/utils.d.ts +20 -0
  55. package/dist/diagnostics/slow-sql-source/utils.js +170 -0
  56. package/dist/diagnostics/slow-sql-source.d.ts +4 -0
  57. package/dist/diagnostics/slow-sql-source.js +3 -0
  58. package/dist/diagnostics/types.d.ts +189 -0
  59. package/dist/diagnostics/types.js +39 -0
  60. package/dist/engine/data-access/locks.d.ts +8 -0
  61. package/dist/engine/data-access/locks.js +146 -0
  62. package/dist/engine/data-access/processlist.d.ts +4 -0
  63. package/dist/engine/data-access/processlist.js +56 -0
  64. package/dist/engine/data-access/statements.d.ts +10 -0
  65. package/dist/engine/data-access/statements.js +203 -0
  66. package/dist/engine/data-access/storage.d.ts +6 -0
  67. package/dist/engine/data-access/storage.js +96 -0
  68. package/dist/engine/data-access.d.ts +4 -0
  69. package/dist/engine/data-access.js +4 -0
  70. package/dist/engine/diagnostics.d.ts +7 -0
  71. package/dist/engine/diagnostics.js +7 -0
  72. package/dist/engine/helper-modules/diagnostics.d.ts +57 -0
  73. package/dist/engine/helper-modules/diagnostics.js +322 -0
  74. package/dist/engine/helper-modules/parsers.d.ts +13 -0
  75. package/dist/engine/helper-modules/parsers.js +283 -0
  76. package/dist/engine/helper-modules/sql.d.ts +12 -0
  77. package/dist/engine/helper-modules/sql.js +119 -0
  78. package/dist/engine/helper-modules/types.d.ts +103 -0
  79. package/dist/engine/helper-modules/types.js +1 -0
  80. package/dist/engine/helpers.d.ts +4 -0
  81. package/dist/engine/helpers.js +4 -0
  82. package/dist/engine/runtime.d.ts +20 -0
  83. package/dist/engine/runtime.js +385 -0
  84. package/dist/engine/types.d.ts +125 -0
  85. package/dist/engine/types.js +1 -0
  86. package/dist/engine/workflows/connection-spike.d.ts +4 -0
  87. package/dist/engine/workflows/connection-spike.js +316 -0
  88. package/dist/engine/workflows/db-hotspot.d.ts +4 -0
  89. package/dist/engine/workflows/db-hotspot.js +182 -0
  90. package/dist/engine/workflows/lock-contention-helpers/entities.d.ts +9 -0
  91. package/dist/engine/workflows/lock-contention-helpers/entities.js +58 -0
  92. package/dist/engine/workflows/lock-contention-helpers/no-match.d.ts +3 -0
  93. package/dist/engine/workflows/lock-contention-helpers/no-match.js +65 -0
  94. package/dist/engine/workflows/lock-contention-helpers/report.d.ts +21 -0
  95. package/dist/engine/workflows/lock-contention-helpers/report.js +104 -0
  96. package/dist/engine/workflows/lock-contention-helpers/root-cause.d.ts +4 -0
  97. package/dist/engine/workflows/lock-contention-helpers/root-cause.js +79 -0
  98. package/dist/engine/workflows/lock-contention-helpers/signals.d.ts +22 -0
  99. package/dist/engine/workflows/lock-contention-helpers/signals.js +34 -0
  100. package/dist/engine/workflows/lock-contention-helpers.d.ts +5 -0
  101. package/dist/engine/workflows/lock-contention-helpers.js +5 -0
  102. package/dist/engine/workflows/lock-contention.d.ts +4 -0
  103. package/dist/engine/workflows/lock-contention.js +67 -0
  104. package/dist/engine/workflows/service-latency.d.ts +4 -0
  105. package/dist/engine/workflows/service-latency.js +262 -0
  106. package/dist/engine/workflows/slow-query-helpers.d.ts +41 -0
  107. package/dist/engine/workflows/slow-query-helpers.js +253 -0
  108. package/dist/engine/workflows/slow-query.d.ts +4 -0
  109. package/dist/engine/workflows/slow-query.js +156 -0
  110. package/dist/engine/workflows/storage-pressure-helpers.d.ts +12 -0
  111. package/dist/engine/workflows/storage-pressure-helpers.js +281 -0
  112. package/dist/engine/workflows/storage-pressure.d.ts +4 -0
  113. package/dist/engine/workflows/storage-pressure.js +27 -0
  114. package/dist/engine/workflows/top-slow-sql.d.ts +4 -0
  115. package/dist/engine/workflows/top-slow-sql.js +222 -0
  116. package/dist/engine.d.ts +77 -0
  117. package/dist/engine.js +240 -0
  118. package/dist/executor/adapters/mysql.d.ts +2 -0
  119. package/dist/executor/adapters/mysql.js +114 -0
  120. package/dist/executor/connection-pool.d.ts +105 -0
  121. package/dist/executor/connection-pool.js +236 -0
  122. package/dist/executor/explain.d.ts +5 -0
  123. package/dist/executor/explain.js +119 -0
  124. package/dist/executor/query-tracker.d.ts +45 -0
  125. package/dist/executor/query-tracker.js +83 -0
  126. package/dist/executor/result-normalizer.d.ts +6 -0
  127. package/dist/executor/result-normalizer.js +47 -0
  128. package/dist/executor/sql-executor.d.ts +32 -0
  129. package/dist/executor/sql-executor.js +250 -0
  130. package/dist/executor/types.d.ts +70 -0
  131. package/dist/executor/types.js +1 -0
  132. package/dist/index.d.ts +40 -0
  133. package/dist/index.js +21 -0
  134. package/dist/safety/confirmation-store.d.ts +44 -0
  135. package/dist/safety/confirmation-store.js +130 -0
  136. package/dist/safety/guardrail.d.ts +39 -0
  137. package/dist/safety/guardrail.js +99 -0
  138. package/dist/safety/parser/adapter.d.ts +10 -0
  139. package/dist/safety/parser/adapter.js +72 -0
  140. package/dist/safety/parser/ast-utils.d.ts +10 -0
  141. package/dist/safety/parser/ast-utils.js +167 -0
  142. package/dist/safety/parser/features.d.ts +12 -0
  143. package/dist/safety/parser/features.js +113 -0
  144. package/dist/safety/parser/index.d.ts +2 -0
  145. package/dist/safety/parser/index.js +1 -0
  146. package/dist/safety/parser/types.d.ts +76 -0
  147. package/dist/safety/parser/types.js +1 -0
  148. package/dist/safety/redaction.d.ts +34 -0
  149. package/dist/safety/redaction.js +186 -0
  150. package/dist/safety/sql-classifier.d.ts +19 -0
  151. package/dist/safety/sql-classifier.js +43 -0
  152. package/dist/safety/sql-validator.d.ts +19 -0
  153. package/dist/safety/sql-validator.js +143 -0
  154. package/dist/schema/adapters/mysql.d.ts +16 -0
  155. package/dist/schema/adapters/mysql.js +287 -0
  156. package/dist/schema/introspector.d.ts +70 -0
  157. package/dist/schema/introspector.js +40 -0
  158. package/dist/taurus/flashback.d.ts +36 -0
  159. package/dist/taurus/flashback.js +149 -0
  160. package/dist/taurus/recycle-bin.d.ts +14 -0
  161. package/dist/taurus/recycle-bin.js +61 -0
  162. package/dist/utils/formatter.d.ts +70 -0
  163. package/dist/utils/formatter.js +60 -0
  164. package/dist/utils/hash.d.ts +2 -0
  165. package/dist/utils/hash.js +247 -0
  166. package/dist/utils/id.d.ts +2 -0
  167. package/dist/utils/id.js +11 -0
  168. package/dist/utils/logger.d.ts +9 -0
  169. package/dist/utils/logger.js +39 -0
  170. package/package.json +46 -0
@@ -0,0 +1,64 @@
1
+ import type { Config } from "../../config/index.js";
2
+ export type DatabaseEngine = "mysql" | "postgresql";
3
+ export type CredentialRef = {
4
+ type: "plain";
5
+ value: string;
6
+ } | {
7
+ type: "env";
8
+ key: string;
9
+ } | {
10
+ type: "file";
11
+ path: string;
12
+ } | {
13
+ type: "uri";
14
+ uri: string;
15
+ };
16
+ export interface UserCredential {
17
+ username: string;
18
+ password: CredentialRef;
19
+ }
20
+ export interface TlsOptions {
21
+ enabled?: boolean;
22
+ rejectUnauthorized?: boolean;
23
+ servername?: string;
24
+ ca?: CredentialRef;
25
+ cert?: CredentialRef;
26
+ key?: CredentialRef;
27
+ }
28
+ export interface DataSourceProfile {
29
+ name: string;
30
+ engine: DatabaseEngine;
31
+ host?: string;
32
+ port: number;
33
+ database?: string;
34
+ readonlyUser: UserCredential;
35
+ mutationUser?: UserCredential;
36
+ tls?: TlsOptions;
37
+ poolSize?: number;
38
+ toString(): string;
39
+ }
40
+ export interface ProfileLoader {
41
+ load(): Promise<Map<string, DataSourceProfile>>;
42
+ getDefault(): Promise<string | undefined>;
43
+ get(name: string): Promise<DataSourceProfile | undefined>;
44
+ }
45
+ export interface RuntimeDataSourceTarget {
46
+ host: string;
47
+ port?: number;
48
+ instanceId?: string;
49
+ nodeId?: string;
50
+ }
51
+ export interface RuntimeTargetProfileLoader extends ProfileLoader {
52
+ setRuntimeTarget(name: string, target: RuntimeDataSourceTarget): void;
53
+ clearRuntimeTarget(name: string): void;
54
+ clearAllRuntimeTargets(): void;
55
+ getRuntimeTarget(name: string): RuntimeDataSourceTarget | undefined;
56
+ }
57
+ export type SqlProfileLoaderOptions = {
58
+ config: Config;
59
+ env?: NodeJS.ProcessEnv;
60
+ };
61
+ export type LoadedProfiles = {
62
+ profiles: Map<string, DataSourceProfile>;
63
+ defaultDatasource?: string;
64
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export type { CredentialRef, DataSourceProfile, DatabaseEngine, ProfileLoader, RuntimeDataSourceTarget, RuntimeTargetProfileLoader, SqlProfileLoaderOptions, TlsOptions, UserCredential, } from "./sql-profile-loader/types.js";
2
+ export { redactDataSourceProfile } from "./sql-profile-loader/parsing.js";
3
+ export { SqlProfileLoader, createSqlProfileLoader } from "./sql-profile-loader/loader.js";
4
+ export { RuntimeOverrideProfileLoader } from "./sql-profile-loader/runtime-override.js";
@@ -0,0 +1,3 @@
1
+ export { redactDataSourceProfile } from "./sql-profile-loader/parsing.js";
2
+ export { SqlProfileLoader, createSqlProfileLoader } from "./sql-profile-loader/loader.js";
3
+ export { RuntimeOverrideProfileLoader } from "./sql-profile-loader/runtime-override.js";
@@ -0,0 +1,5 @@
1
+ import type { FeatureMatrix, KernelInfo } from "./types.js";
2
+ type ProbeVariables = Partial<Record<string, string>>;
3
+ export declare function buildUnavailableFeatureMatrix(reason?: string): FeatureMatrix;
4
+ export declare function buildFeatureMatrix(kernelInfo: KernelInfo, variables?: ProbeVariables): FeatureMatrix;
5
+ export {};
@@ -0,0 +1,237 @@
1
+ import { isKernelVersionAtLeast } from "./version.js";
2
+ const FEATURE_MIN_VERSIONS = {
3
+ flashback_query: "2.0.69.250900",
4
+ recycle_bin: "2.0.57.240900",
5
+ statement_outline: "2.0.42.230600",
6
+ column_compression: "2.0.54.240600",
7
+ multi_tenant: "2.0.54.240600",
8
+ partition_mdl: "2.0.57.240900",
9
+ dynamic_masking: "2.0.69.250900",
10
+ nonblocking_ddl: "2.0.54.240600",
11
+ hot_row_update: "2.0.54.240600",
12
+ };
13
+ function normalizeBooleanVariable(value) {
14
+ if (!value) {
15
+ return undefined;
16
+ }
17
+ const normalized = value.trim().toLowerCase();
18
+ if (["on", "1", "true", "yes", "enabled"].includes(normalized)) {
19
+ return true;
20
+ }
21
+ if (["off", "0", "false", "no", "disabled"].includes(normalized)) {
22
+ return false;
23
+ }
24
+ return undefined;
25
+ }
26
+ function makeUnavailable(reason, minVersion) {
27
+ return {
28
+ available: false,
29
+ enabled: false,
30
+ minVersion,
31
+ reason,
32
+ };
33
+ }
34
+ function makeVersionGatedFeature(kernelInfo, feature, reasonWhenUnavailable) {
35
+ const minVersion = FEATURE_MIN_VERSIONS[feature];
36
+ if (!kernelInfo.isTaurusDB) {
37
+ return makeUnavailable("Instance is not TaurusDB.", minVersion);
38
+ }
39
+ if (!minVersion) {
40
+ return {
41
+ available: true,
42
+ minVersion,
43
+ };
44
+ }
45
+ if (!isKernelVersionAtLeast(kernelInfo.kernelVersion, minVersion)) {
46
+ return makeUnavailable(reasonWhenUnavailable ??
47
+ `Requires kernel version >= ${minVersion}, current: ${kernelInfo.kernelVersion ?? "unknown"}.`, minVersion);
48
+ }
49
+ return {
50
+ available: true,
51
+ minVersion,
52
+ };
53
+ }
54
+ function inferOffsetPushdown(optimizerSwitch) {
55
+ if (!optimizerSwitch) {
56
+ return undefined;
57
+ }
58
+ const match = optimizerSwitch.match(/(?:^|,)offset_pushdown=(on|off)(?:,|$)/i);
59
+ if (!match) {
60
+ return undefined;
61
+ }
62
+ return match[1].toLowerCase() === "on";
63
+ }
64
+ export function buildUnavailableFeatureMatrix(reason = "Instance is not TaurusDB.") {
65
+ return {
66
+ flashback_query: makeUnavailable(reason, FEATURE_MIN_VERSIONS.flashback_query),
67
+ parallel_query: makeUnavailable(reason),
68
+ ndp_pushdown: makeUnavailable(reason),
69
+ offset_pushdown: makeUnavailable(reason),
70
+ recycle_bin: makeUnavailable(reason, FEATURE_MIN_VERSIONS.recycle_bin),
71
+ statement_outline: makeUnavailable(reason, FEATURE_MIN_VERSIONS.statement_outline),
72
+ column_compression: makeUnavailable(reason, FEATURE_MIN_VERSIONS.column_compression),
73
+ multi_tenant: makeUnavailable(reason, FEATURE_MIN_VERSIONS.multi_tenant),
74
+ partition_mdl: makeUnavailable(reason, FEATURE_MIN_VERSIONS.partition_mdl),
75
+ dynamic_masking: makeUnavailable(reason, FEATURE_MIN_VERSIONS.dynamic_masking),
76
+ nonblocking_ddl: makeUnavailable(reason, FEATURE_MIN_VERSIONS.nonblocking_ddl),
77
+ hot_row_update: makeUnavailable(reason, FEATURE_MIN_VERSIONS.hot_row_update),
78
+ };
79
+ }
80
+ export function buildFeatureMatrix(kernelInfo, variables = {}) {
81
+ if (!kernelInfo.isTaurusDB) {
82
+ return buildUnavailableFeatureMatrix();
83
+ }
84
+ const flashbackEnabled = normalizeBooleanVariable(variables.innodb_rds_backquery_enable);
85
+ const recycleBinMode = normalizeBooleanVariable(variables.rds_recycle_bin_mode);
86
+ const parallelSetting = variables.force_parallel_execute;
87
+ const parallelEnabled = normalizeBooleanVariable(parallelSetting);
88
+ const offsetPushdownEnabled = inferOffsetPushdown(variables.optimizer_switch);
89
+ const ndpModeRaw = variables.ndp_mode ??
90
+ variables.rds_ndp_mode ??
91
+ variables.taurus_ndp_mode ??
92
+ variables.ndp_pushdown_mode ??
93
+ variables.ndp_pushdown;
94
+ const ndpParamName = variables.ndp_mode !== undefined
95
+ ? "ndp_mode"
96
+ : variables.rds_ndp_mode !== undefined
97
+ ? "rds_ndp_mode"
98
+ : variables.taurus_ndp_mode !== undefined
99
+ ? "taurus_ndp_mode"
100
+ : variables.ndp_pushdown_mode !== undefined
101
+ ? "ndp_pushdown_mode"
102
+ : variables.ndp_pushdown !== undefined
103
+ ? "ndp_pushdown"
104
+ : undefined;
105
+ const ndpMode = ndpModeRaw?.toUpperCase() === "REPLICA_ON" ||
106
+ ndpModeRaw?.toUpperCase() === "ON" ||
107
+ ndpModeRaw?.toUpperCase() === "OFF"
108
+ ? ndpModeRaw.toUpperCase()
109
+ : undefined;
110
+ const multiTenantActive = normalizeBooleanVariable(variables.rds_multi_tenant ?? variables.multi_tenant_mode);
111
+ const multiTenantParamName = variables.multi_tenant_mode !== undefined
112
+ ? "multi_tenant_mode"
113
+ : variables.rds_multi_tenant !== undefined
114
+ ? "rds_multi_tenant"
115
+ : "multi_tenant_mode";
116
+ const statementOutlineEnabled = normalizeBooleanVariable(variables.rds_opt_outline_enabled);
117
+ const partitionMdlEnabled = normalizeBooleanVariable(variables.rds_partition_level_mdl_enabled);
118
+ const dynamicMaskingEnabled = normalizeBooleanVariable(variables.rds_dynamic_masking_enabled);
119
+ const nonblockingDdlEnabled = normalizeBooleanVariable(variables.rds_nonblock_ddl_enable);
120
+ const hotRowUpdateEnabled = normalizeBooleanVariable(variables.rds_hotspot);
121
+ const flashback = makeVersionGatedFeature(kernelInfo, "flashback_query");
122
+ if (flashback.available) {
123
+ flashback.enabled = flashbackEnabled ?? true;
124
+ if (flashbackEnabled === false) {
125
+ flashback.param = "innodb_rds_backquery_enable=OFF";
126
+ }
127
+ else if (flashbackEnabled === true) {
128
+ flashback.param = "innodb_rds_backquery_enable=ON";
129
+ }
130
+ }
131
+ const recycleBin = makeVersionGatedFeature(kernelInfo, "recycle_bin");
132
+ if (recycleBin.available) {
133
+ recycleBin.enabled = recycleBinMode ?? true;
134
+ if (recycleBinMode === false) {
135
+ recycleBin.param = "rds_recycle_bin_mode=OFF";
136
+ }
137
+ else if (recycleBinMode === true) {
138
+ recycleBin.param = "rds_recycle_bin_mode=ON";
139
+ }
140
+ }
141
+ const statementOutline = makeVersionGatedFeature(kernelInfo, "statement_outline");
142
+ if (statementOutline.available) {
143
+ statementOutline.enabled = statementOutlineEnabled;
144
+ if (statementOutlineEnabled === false) {
145
+ statementOutline.param = "rds_opt_outline_enabled=OFF";
146
+ }
147
+ else if (statementOutlineEnabled === true) {
148
+ statementOutline.param = "rds_opt_outline_enabled=ON";
149
+ }
150
+ }
151
+ const columnCompression = makeVersionGatedFeature(kernelInfo, "column_compression");
152
+ const multiTenant = makeVersionGatedFeature(kernelInfo, "multi_tenant");
153
+ if (multiTenant.available) {
154
+ multiTenant.active = multiTenantActive ?? false;
155
+ multiTenant.enabled = multiTenantActive ?? false;
156
+ if (multiTenantActive === false) {
157
+ multiTenant.param = `${multiTenantParamName}=OFF`;
158
+ }
159
+ else if (multiTenantActive === true) {
160
+ multiTenant.param =
161
+ variables[multiTenantParamName] !== undefined
162
+ ? `${multiTenantParamName}=${variables[multiTenantParamName]}`
163
+ : `${multiTenantParamName}=ON`;
164
+ }
165
+ }
166
+ const partitionMdl = makeVersionGatedFeature(kernelInfo, "partition_mdl");
167
+ if (partitionMdl.available) {
168
+ partitionMdl.enabled = partitionMdlEnabled;
169
+ if (partitionMdlEnabled === false) {
170
+ partitionMdl.param = "rds_partition_level_mdl_enabled=OFF";
171
+ }
172
+ else if (partitionMdlEnabled === true) {
173
+ partitionMdl.param = "rds_partition_level_mdl_enabled=ON";
174
+ }
175
+ }
176
+ const dynamicMasking = makeVersionGatedFeature(kernelInfo, "dynamic_masking");
177
+ if (dynamicMasking.available) {
178
+ dynamicMasking.enabled = dynamicMaskingEnabled;
179
+ if (dynamicMaskingEnabled === false) {
180
+ dynamicMasking.param = "rds_dynamic_masking_enabled=OFF";
181
+ }
182
+ else if (dynamicMaskingEnabled === true) {
183
+ dynamicMasking.param = "rds_dynamic_masking_enabled=ON";
184
+ }
185
+ }
186
+ const nonblockingDdl = makeVersionGatedFeature(kernelInfo, "nonblocking_ddl");
187
+ if (nonblockingDdl.available) {
188
+ nonblockingDdl.enabled = nonblockingDdlEnabled;
189
+ if (nonblockingDdlEnabled === false) {
190
+ nonblockingDdl.param = "rds_nonblock_ddl_enable=OFF";
191
+ }
192
+ else if (nonblockingDdlEnabled === true) {
193
+ nonblockingDdl.param = "rds_nonblock_ddl_enable=ON";
194
+ }
195
+ }
196
+ const hotRowUpdate = makeVersionGatedFeature(kernelInfo, "hot_row_update");
197
+ if (hotRowUpdate.available) {
198
+ hotRowUpdate.enabled = hotRowUpdateEnabled;
199
+ if (hotRowUpdateEnabled === false) {
200
+ hotRowUpdate.param = "rds_hotspot=OFF";
201
+ }
202
+ else if (hotRowUpdateEnabled === true) {
203
+ hotRowUpdate.param = "rds_hotspot=ON";
204
+ }
205
+ }
206
+ return {
207
+ flashback_query: flashback,
208
+ parallel_query: {
209
+ available: true,
210
+ enabled: parallelEnabled ?? false,
211
+ param: parallelSetting ? `force_parallel_execute=${parallelSetting}` : undefined,
212
+ },
213
+ ndp_pushdown: {
214
+ available: true,
215
+ enabled: ndpMode ? ndpMode !== "OFF" : true,
216
+ mode: ndpMode,
217
+ param: ndpModeRaw && ndpParamName ? `${ndpParamName}=${ndpModeRaw}` : undefined,
218
+ },
219
+ offset_pushdown: {
220
+ available: true,
221
+ enabled: offsetPushdownEnabled ?? true,
222
+ param: offsetPushdownEnabled === false
223
+ ? "optimizer_switch: offset_pushdown=off"
224
+ : offsetPushdownEnabled === true
225
+ ? "optimizer_switch: offset_pushdown=on"
226
+ : undefined,
227
+ },
228
+ recycle_bin: recycleBin,
229
+ statement_outline: statementOutline,
230
+ column_compression: columnCompression,
231
+ multi_tenant: multiTenant,
232
+ partition_mdl: partitionMdl,
233
+ dynamic_masking: dynamicMasking,
234
+ nonblocking_ddl: nonblockingDdl,
235
+ hot_row_update: hotRowUpdate,
236
+ };
237
+ }
@@ -0,0 +1,19 @@
1
+ import type { SessionContext } from "../context/session-context.js";
2
+ import type { ConnectionPool } from "../executor/connection-pool.js";
3
+ import type { CapabilitySnapshot, FeatureMatrix, KernelInfo } from "./types.js";
4
+ export interface CapabilityProbe {
5
+ probe(ctx: SessionContext): Promise<CapabilitySnapshot>;
6
+ getKernelInfo(ctx: SessionContext): Promise<KernelInfo>;
7
+ listFeatures(ctx: SessionContext): Promise<FeatureMatrix>;
8
+ }
9
+ export interface CapabilityProbeOptions {
10
+ connectionPool: ConnectionPool;
11
+ }
12
+ export declare class CapabilityProbeImpl implements CapabilityProbe {
13
+ private readonly connectionPool;
14
+ constructor(options: CapabilityProbeOptions);
15
+ probe(ctx: SessionContext): Promise<CapabilitySnapshot>;
16
+ getKernelInfo(ctx: SessionContext): Promise<KernelInfo>;
17
+ listFeatures(ctx: SessionContext): Promise<FeatureMatrix>;
18
+ }
19
+ export declare function createCapabilityProbe(options: CapabilityProbeOptions): CapabilityProbe;
@@ -0,0 +1,139 @@
1
+ import { buildFeatureMatrix } from "./feature-matrix.js";
2
+ import { extractKernelVersion } from "./version.js";
3
+ const TAURUS_VARIABLE_NAMES = [
4
+ "innodb_rds_backquery_enable",
5
+ "rds_recycle_bin_mode",
6
+ "force_parallel_execute",
7
+ "ndp_mode",
8
+ "rds_ndp_mode",
9
+ "taurus_ndp_mode",
10
+ "ndp_pushdown_mode",
11
+ "ndp_pushdown",
12
+ "rds_multi_tenant",
13
+ "multi_tenant_mode",
14
+ "rds_opt_outline_enabled",
15
+ "rds_partition_level_mdl_enabled",
16
+ "rds_dynamic_masking_enabled",
17
+ "rds_nonblock_ddl_enable",
18
+ "rds_hotspot",
19
+ ];
20
+ function mysqlCompatFromVersion(rawVersion) {
21
+ if (/8\.0/i.test(rawVersion)) {
22
+ return "8.0";
23
+ }
24
+ if (/5\.7/i.test(rawVersion)) {
25
+ return "5.7";
26
+ }
27
+ return "unknown";
28
+ }
29
+ function rowValueOf(row) {
30
+ if (!row || typeof row !== "object" || Array.isArray(row)) {
31
+ return undefined;
32
+ }
33
+ const record = row;
34
+ const preferredKeys = ["Value", "value", "VARIABLE_VALUE", "version", "VERSION()"];
35
+ for (const key of preferredKeys) {
36
+ const value = record[key];
37
+ if (typeof value === "string" && value.trim().length > 0) {
38
+ return value.trim();
39
+ }
40
+ }
41
+ for (const value of Object.values(record)) {
42
+ if (typeof value === "string" && value.trim().length > 0) {
43
+ return value.trim();
44
+ }
45
+ }
46
+ return undefined;
47
+ }
48
+ function firstRow(result) {
49
+ return Array.isArray(result.rows) ? result.rows[0] : undefined;
50
+ }
51
+ function inferInstanceSpecHint(variables) {
52
+ const parallelSetting = (variables.force_parallel_execute ?? "").toUpperCase();
53
+ const ndpMode = (variables.ndp_mode ??
54
+ variables.rds_ndp_mode ??
55
+ variables.taurus_ndp_mode ??
56
+ variables.ndp_pushdown_mode ??
57
+ "").toUpperCase();
58
+ if (parallelSetting === "ON" || ndpMode === "REPLICA_ON") {
59
+ return "large";
60
+ }
61
+ if (parallelSetting === "OFF" || ndpMode === "ON") {
62
+ return "medium";
63
+ }
64
+ return undefined;
65
+ }
66
+ async function executeSingleValueQuery(session, sql) {
67
+ try {
68
+ const result = await session.execute(sql);
69
+ return rowValueOf(firstRow(result));
70
+ }
71
+ catch {
72
+ return undefined;
73
+ }
74
+ }
75
+ async function readVariable(session, name) {
76
+ return executeSingleValueQuery(session, `SHOW VARIABLES LIKE '${name}'`);
77
+ }
78
+ async function collectVariables(session) {
79
+ const names = [
80
+ "version_comment",
81
+ ...TAURUS_VARIABLE_NAMES,
82
+ "optimizer_switch",
83
+ ];
84
+ const entries = await Promise.all(names.map(async (name) => [name, await readVariable(session, name)]));
85
+ return Object.fromEntries(entries.filter(([, value]) => value !== undefined));
86
+ }
87
+ function hasTaurusSpecificVariables(variables) {
88
+ return TAURUS_VARIABLE_NAMES.some((name) => Object.prototype.hasOwnProperty.call(variables, name));
89
+ }
90
+ async function detectKernelInfo(session, variables) {
91
+ const rawVersion = (await executeSingleValueQuery(session, "SELECT VERSION() AS version")) ?? "unknown";
92
+ const versionComment = variables.version_comment;
93
+ const combined = [rawVersion, versionComment].filter(Boolean).join(" ");
94
+ const kernelVersion = extractKernelVersion(combined);
95
+ const taurusSignals = [combined, variables.force_parallel_execute, variables.innodb_rds_backquery_enable]
96
+ .filter((value) => typeof value === "string")
97
+ .join(" ");
98
+ const hasTaurusSignals = /taurus|huawei|gaussdb/i.test(taurusSignals) ||
99
+ hasTaurusSpecificVariables(variables);
100
+ return {
101
+ isTaurusDB: hasTaurusSignals,
102
+ kernelVersion,
103
+ mysqlCompat: mysqlCompatFromVersion(rawVersion),
104
+ instanceSpecHint: inferInstanceSpecHint(variables),
105
+ rawVersion,
106
+ };
107
+ }
108
+ export class CapabilityProbeImpl {
109
+ connectionPool;
110
+ constructor(options) {
111
+ this.connectionPool = options.connectionPool;
112
+ }
113
+ async probe(ctx) {
114
+ const session = await this.connectionPool.acquire(ctx.datasource, "ro");
115
+ try {
116
+ const variables = await collectVariables(session);
117
+ const kernelInfo = await detectKernelInfo(session, variables);
118
+ return {
119
+ kernelInfo,
120
+ features: buildFeatureMatrix(kernelInfo, variables),
121
+ checkedAt: Date.now(),
122
+ };
123
+ }
124
+ finally {
125
+ await this.connectionPool.release(session);
126
+ }
127
+ }
128
+ async getKernelInfo(ctx) {
129
+ const snapshot = await this.probe(ctx);
130
+ return snapshot.kernelInfo;
131
+ }
132
+ async listFeatures(ctx) {
133
+ const snapshot = await this.probe(ctx);
134
+ return snapshot.features;
135
+ }
136
+ }
137
+ export function createCapabilityProbe(options) {
138
+ return new CapabilityProbeImpl(options);
139
+ }
@@ -0,0 +1,49 @@
1
+ export interface KernelInfo {
2
+ isTaurusDB: boolean;
3
+ kernelVersion?: string;
4
+ mysqlCompat: "5.7" | "8.0" | "unknown";
5
+ instanceSpecHint?: "small" | "medium" | "large";
6
+ rawVersion: string;
7
+ }
8
+ export type FeatureStatus = {
9
+ available: boolean;
10
+ enabled?: boolean;
11
+ minVersion?: string;
12
+ reason?: string;
13
+ param?: string;
14
+ };
15
+ export interface FeatureMatrix {
16
+ flashback_query: FeatureStatus;
17
+ parallel_query: FeatureStatus;
18
+ ndp_pushdown: FeatureStatus & {
19
+ mode?: "OFF" | "ON" | "REPLICA_ON";
20
+ };
21
+ offset_pushdown: FeatureStatus;
22
+ recycle_bin: FeatureStatus;
23
+ statement_outline: FeatureStatus;
24
+ column_compression: FeatureStatus;
25
+ multi_tenant: FeatureStatus & {
26
+ active?: boolean;
27
+ };
28
+ partition_mdl: FeatureStatus;
29
+ dynamic_masking: FeatureStatus;
30
+ nonblocking_ddl: FeatureStatus;
31
+ hot_row_update: FeatureStatus;
32
+ }
33
+ export type TaurusFeatureName = keyof FeatureMatrix;
34
+ export interface CapabilitySnapshot {
35
+ kernelInfo: KernelInfo;
36
+ features: FeatureMatrix;
37
+ checkedAt: number;
38
+ }
39
+ export declare class UnsupportedFeatureError extends Error {
40
+ readonly code = "UNSUPPORTED_FEATURE";
41
+ readonly feature: TaurusFeatureName;
42
+ readonly requiredVersion?: string;
43
+ readonly currentVersion?: string;
44
+ constructor(feature: TaurusFeatureName, message: string, options?: {
45
+ requiredVersion?: string;
46
+ currentVersion?: string;
47
+ cause?: unknown;
48
+ });
49
+ }
@@ -0,0 +1,16 @@
1
+ export class UnsupportedFeatureError extends Error {
2
+ code = "UNSUPPORTED_FEATURE";
3
+ feature;
4
+ requiredVersion;
5
+ currentVersion;
6
+ constructor(feature, message, options = {}) {
7
+ super(message);
8
+ this.name = "UnsupportedFeatureError";
9
+ this.feature = feature;
10
+ this.requiredVersion = options.requiredVersion;
11
+ this.currentVersion = options.currentVersion;
12
+ if (options.cause !== undefined) {
13
+ this.cause = options.cause;
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,3 @@
1
+ export declare function compareKernelVersions(left: string | undefined, right: string | undefined): number;
2
+ export declare function isKernelVersionAtLeast(currentVersion: string | undefined, minimumVersion: string | undefined): boolean;
3
+ export declare function extractKernelVersion(input: string | undefined): string | undefined;
@@ -0,0 +1,47 @@
1
+ function parseVersion(version) {
2
+ if (!version) {
3
+ return [];
4
+ }
5
+ const match = version.match(/\d+(?:\.\d+)+/);
6
+ if (!match) {
7
+ return [];
8
+ }
9
+ return match[0]
10
+ .split(".")
11
+ .map((segment) => Number.parseInt(segment, 10))
12
+ .filter((segment) => Number.isFinite(segment));
13
+ }
14
+ export function compareKernelVersions(left, right) {
15
+ const leftParts = parseVersion(left);
16
+ const rightParts = parseVersion(right);
17
+ const size = Math.max(leftParts.length, rightParts.length);
18
+ for (let index = 0; index < size; index += 1) {
19
+ const a = leftParts[index] ?? 0;
20
+ const b = rightParts[index] ?? 0;
21
+ if (a === b) {
22
+ continue;
23
+ }
24
+ return a > b ? 1 : -1;
25
+ }
26
+ return 0;
27
+ }
28
+ export function isKernelVersionAtLeast(currentVersion, minimumVersion) {
29
+ if (!minimumVersion) {
30
+ return true;
31
+ }
32
+ if (!currentVersion) {
33
+ return false;
34
+ }
35
+ return compareKernelVersions(currentVersion, minimumVersion) >= 0;
36
+ }
37
+ export function extractKernelVersion(input) {
38
+ if (!input) {
39
+ return undefined;
40
+ }
41
+ const exact = input.match(/\b\d+\.\d+\.\d+\.\d+\b/);
42
+ if (exact) {
43
+ return exact[0];
44
+ }
45
+ const fallback = input.match(/\b\d+\.\d+\.\d+\b/);
46
+ return fallback?.[0];
47
+ }
@@ -0,0 +1,26 @@
1
+ import type { Config } from "../config/index.js";
2
+ export interface HuaweiCloudAuthOptions {
3
+ region?: string;
4
+ projectId?: string;
5
+ authToken?: string;
6
+ accessKeyId?: string;
7
+ secretAccessKey?: string;
8
+ securityToken?: string;
9
+ domainSuffix?: string;
10
+ iamEndpoint?: string;
11
+ language?: "en-us" | "zh-cn";
12
+ }
13
+ export interface FetchHuaweiCloudOptions {
14
+ url: string;
15
+ method?: string;
16
+ headers?: HeadersInit;
17
+ body?: string;
18
+ auth: HuaweiCloudAuthOptions;
19
+ fetchImpl?: typeof fetch;
20
+ }
21
+ export declare function canAuthenticateHuaweiCloudRequests(auth: HuaweiCloudAuthOptions): boolean;
22
+ export declare function fetchHuaweiCloud(options: FetchHuaweiCloudOptions): Promise<Response>;
23
+ export declare function resolveHuaweiCloudProjectId(auth: HuaweiCloudAuthOptions, fetchImpl?: typeof fetch): Promise<string | undefined>;
24
+ export declare function getHuaweiCloudAuthFromConfig(config: Config): HuaweiCloudAuthOptions;
25
+ export declare function hasHuaweiCloudCredentialAuth(config: Config): boolean;
26
+ export declare function inferHuaweiCloudRegionFromEndpoint(endpoint: string | undefined): string | undefined;