@solidxai/core 0.1.10 → 0.1.11-beta.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/dist/controllers/datasource-introspection.controller.d.ts +234 -0
- package/dist/controllers/datasource-introspection.controller.d.ts.map +1 -0
- package/dist/controllers/datasource-introspection.controller.js +98 -0
- package/dist/controllers/datasource-introspection.controller.js.map +1 -0
- package/dist/controllers/datasource-management.controller.d.ts +18 -0
- package/dist/controllers/datasource-management.controller.d.ts.map +1 -0
- package/dist/controllers/datasource-management.controller.js +55 -0
- package/dist/controllers/datasource-management.controller.js.map +1 -0
- package/dist/dtos/create-datasource-management.dto.d.ts +25 -0
- package/dist/dtos/create-datasource-management.dto.d.ts.map +1 -0
- package/dist/dtos/create-datasource-management.dto.js +169 -0
- package/dist/dtos/create-datasource-management.dto.js.map +1 -0
- package/dist/dtos/datasource-introspection-mapping.dto.d.ts +45 -0
- package/dist/dtos/datasource-introspection-mapping.dto.d.ts.map +1 -0
- package/dist/dtos/datasource-introspection-mapping.dto.js +233 -0
- package/dist/dtos/datasource-introspection-mapping.dto.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces/datasource-introspection-provider.interface.d.ts +26 -0
- package/dist/interfaces/datasource-introspection-provider.interface.d.ts.map +1 -0
- package/dist/interfaces/datasource-introspection-provider.interface.js +3 -0
- package/dist/interfaces/datasource-introspection-provider.interface.js.map +1 -0
- package/dist/seeders/seed-data/solid-core-metadata.json +21 -0
- package/dist/services/authentication.service.js +1 -1
- package/dist/services/authentication.service.js.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.d.ts.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.js +2 -2
- package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.js.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.d.ts.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.js +2 -2
- package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.js.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-provider-utils.d.ts +3 -0
- package/dist/services/dashboard-providers/mq-dashboard-provider-utils.d.ts.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-provider-utils.js +71 -0
- package/dist/services/dashboard-providers/mq-dashboard-provider-utils.js.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.d.ts.map +1 -1
- package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.js +3 -3
- package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.js.map +1 -1
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts +11 -0
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts.map +1 -0
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js +181 -0
- package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js.map +1 -0
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts +11 -0
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.d.ts.map +1 -0
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js +90 -0
- package/dist/services/datasource-introspection/mysql-datasource-introspection-provider.service.js.map +1 -0
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts +11 -0
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.d.ts.map +1 -0
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js +156 -0
- package/dist/services/datasource-introspection/postgres-datasource-introspection-provider.service.js.map +1 -0
- package/dist/services/datasource-introspection.service.d.ts +288 -0
- package/dist/services/datasource-introspection.service.d.ts.map +1 -0
- package/dist/services/datasource-introspection.service.js +1278 -0
- package/dist/services/datasource-introspection.service.js.map +1 -0
- package/dist/services/datasource-management.service.d.ts +60 -0
- package/dist/services/datasource-management.service.d.ts.map +1 -0
- package/dist/services/datasource-management.service.js +461 -0
- package/dist/services/datasource-management.service.js.map +1 -0
- package/dist/services/field-metadata.service.d.ts.map +1 -1
- package/dist/services/field-metadata.service.js +19 -0
- package/dist/services/field-metadata.service.js.map +1 -1
- package/dist/services/model-metadata.service.d.ts +1 -3
- package/dist/services/model-metadata.service.d.ts.map +1 -1
- package/dist/services/model-metadata.service.js +47 -15
- package/dist/services/model-metadata.service.js.map +1 -1
- package/dist/services/role-metadata.service.d.ts +1 -0
- package/dist/services/role-metadata.service.d.ts.map +1 -1
- package/dist/services/role-metadata.service.js +13 -0
- package/dist/services/role-metadata.service.js.map +1 -1
- package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.d.ts.map +1 -1
- package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.js +2 -3
- package/dist/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.js.map +1 -1
- package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.d.ts.map +1 -1
- package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.js +2 -3
- package/dist/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.js.map +1 -1
- package/dist/services/setting.service.d.ts +1 -0
- package/dist/services/setting.service.d.ts.map +1 -1
- package/dist/services/setting.service.js +32 -8
- package/dist/services/setting.service.js.map +1 -1
- package/dist/services/solid-ts-morph.service.d.ts +1 -1
- package/dist/services/solid-ts-morph.service.d.ts.map +1 -1
- package/dist/services/solid-ts-morph.service.js.map +1 -1
- package/dist/solid-core.module.d.ts.map +1 -1
- package/dist/solid-core.module.js +16 -0
- package/dist/solid-core.module.js.map +1 -1
- package/package.json +1 -1
- package/src/controllers/datasource-introspection.controller.ts +58 -0
- package/src/controllers/datasource-management.controller.ts +24 -0
- package/src/dtos/create-datasource-management.dto.ts +139 -0
- package/src/dtos/datasource-introspection-mapping.dto.ts +182 -0
- package/src/index.ts +5 -0
- package/src/interfaces/datasource-introspection-provider.interface.ts +28 -0
- package/src/seeders/seed-data/solid-core-metadata.json +22 -1
- package/src/services/authentication.service.ts +1 -1
- package/src/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.ts +9 -4
- package/src/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.ts +9 -4
- package/src/services/dashboard-providers/mq-dashboard-provider-utils.ts +82 -0
- package/src/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.ts +10 -4
- package/src/services/datasource-introspection/mssql-datasource-introspection-provider.service.ts +185 -0
- package/src/services/datasource-introspection/mysql-datasource-introspection-provider.service.ts +95 -0
- package/src/services/datasource-introspection/postgres-datasource-introspection-provider.service.ts +160 -0
- package/src/services/datasource-introspection.service.ts +1536 -0
- package/src/services/datasource-management.service.ts +566 -0
- package/src/services/field-metadata.service.ts +21 -1
- package/src/services/model-metadata.service.ts +50 -13
- package/src/services/role-metadata.service.ts +14 -0
- package/src/services/selection-providers/mq-dashboard-message-broker-variable-options-provider.service.ts +2 -4
- package/src/services/selection-providers/mq-dashboard-queue-name-variable-options-provider.service.ts +2 -4
- package/src/services/setting.service.ts +43 -12
- package/src/services/solid-ts-morph.service.ts +2 -2
- package/src/solid-core.module.ts +16 -0
package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mq-dashboard-latency-trend-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,4BAA4B,EAAE,mCAAmC,EAAE,oCAAoC,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"mq-dashboard-latency-trend-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,4BAA4B,EAAE,mCAAmC,EAAE,oCAAoC,EAAE,MAAM,gBAAgB,CAAC;AASzI,qBAEa,+BAAgC,YAAW,4BAA4B;IAE5E,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAAnB,mBAAmB,EAAE,mBAAmB;IAG7D,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAIR,OAAO,CACT,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACrC,IAAI,EAAE,mCAAmC,GAC1C,OAAO,CAAC,oCAAoC,CAAC,GAAG,CAAC,CAAC;CAgCxD"}
|
|
@@ -29,14 +29,14 @@ let MqDashboardLatencyTrendProvider = class MqDashboardLatencyTrendProvider {
|
|
|
29
29
|
const qb = await this.mqMessageRepository.createSecurityRuleAwareQueryBuilder("mqMessage");
|
|
30
30
|
(0, mq_dashboard_provider_utils_1.applyMqDashboardFilters)(qb, ctxt.variables ?? {});
|
|
31
31
|
qb.andWhere("mqMessage.elapsedMillis IS NOT NULL");
|
|
32
|
-
const bucketExpr =
|
|
32
|
+
const bucketExpr = (0, mq_dashboard_provider_utils_1.buildMqDashboardBucketExpression)(qb, bucket, "mqMessage.createdAt");
|
|
33
33
|
const rows = await qb
|
|
34
34
|
.select(bucketExpr, "bucket")
|
|
35
35
|
.addSelect("AVG(mqMessage.elapsedMillis)", "value")
|
|
36
36
|
.groupBy(bucketExpr)
|
|
37
37
|
.orderBy("bucket", "ASC")
|
|
38
38
|
.getRawMany();
|
|
39
|
-
const categories = rows.map((r) =>
|
|
39
|
+
const categories = rows.map((r) => (0, mq_dashboard_provider_utils_1.normalizeMqDashboardBucketValue)(r.bucket));
|
|
40
40
|
const values = rows.map((r) => Number((0, mq_dashboard_provider_utils_1.toNumber)(r.value).toFixed(2)));
|
|
41
41
|
return {
|
|
42
42
|
meta: {
|
package/dist/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mq-dashboard-latency-trend-provider.service.js","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,wHAAsG;AACtG,kFAA2E;AAE3E,+
|
|
1
|
+
{"version":3,"file":"mq-dashboard-latency-trend-provider.service.js","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-latency-trend-provider.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,wHAAsG;AACtG,kFAA2E;AAE3E,+EAMsE;AAI/D,IAAM,+BAA+B,GAArC,MAAM,+BAA+B;IACxC,YACqB,mBAAwC;QAAxC,wBAAmB,GAAnB,mBAAmB,CAAqB;IACzD,CAAC;IAEL,IAAI;QACA,OAAO,iCAAiC,CAAC;IAC7C,CAAC;IAED,IAAI;QACA,OAAO,4FAA4F,CAAC;IACxG,CAAC;IAED,KAAK,CAAC,OAAO,CACT,gBAAqC,EACrC,IAAyC;QAEzC,MAAM,MAAM,GAAG,IAAA,6CAAe,EAAC,IAAI,EAAE,eAAe,EAAE,MAAM,CAAC,CAAC;QAE9D,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,mCAAmC,CAAC,WAAW,CAAC,CAAC;QAC3F,IAAA,qDAAuB,EAAC,EAAE,EAAE,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;QAClD,EAAE,CAAC,QAAQ,CAAC,qCAAqC,CAAC,CAAC;QAEnD,MAAM,UAAU,GAAG,IAAA,8DAAgC,EAAC,EAAE,EAAE,MAAM,EAAE,qBAAqB,CAAC,CAAC;QACvF,MAAM,IAAI,GAAG,MAAM,EAAE;aAChB,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC;aAC5B,SAAS,CAAC,8BAA8B,EAAE,OAAO,CAAC;aAClD,OAAO,CAAC,UAAU,CAAC;aACnB,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC;aACxB,UAAU,EAA8C,CAAC;QAE9D,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,6DAA+B,EAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAA,sCAAQ,EAAC,CAAC,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAErE,OAAO;YACH,IAAI,EAAE;gBACF,YAAY,EAAE,IAAI,CAAC,IAAI,EAAE;gBACzB,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;gBACrC,UAAU,EAAE,IAAI,CAAC,UAAU;gBAC3B,UAAU,EAAE,CAAC;aAChB;YACD,IAAI,EAAE;gBACF,UAAU;gBACV,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gBACtD,MAAM;aACT;SACJ,CAAC;IACN,CAAC;CACJ,CAAA;AAhDY,0EAA+B;0CAA/B,+BAA+B;IAF3C,IAAA,sEAA2B,GAAE;IAC7B,IAAA,mBAAU,GAAE;qCAGiC,2CAAmB;GAFpD,+BAA+B,CAgD3C","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { DashboardWidgetDataProvider } from \"src/decorators/dashboard-widget-data-provider.decorator\";\nimport { MqMessageRepository } from \"src/repository/mq-message.repository\";\nimport { IDashboardWidgetDataProvider, IDashboardWidgetDataProviderContext, IDashboardWidgetDataResponseEnvelope } from \"src/interfaces\";\nimport {\n applyMqDashboardFilters,\n buildMqDashboardBucketExpression,\n normalizeBucket,\n normalizeMqDashboardBucketValue,\n toNumber,\n} from \"src/services/dashboard-providers/mq-dashboard-provider-utils\";\n\n@DashboardWidgetDataProvider()\n@Injectable()\nexport class MqDashboardLatencyTrendProvider implements IDashboardWidgetDataProvider {\n constructor(\n private readonly mqMessageRepository: MqMessageRepository,\n ) { }\n\n name(): string {\n return \"MqDashboardLatencyTrendProvider\";\n }\n\n help(): string {\n return \"Returns average elapsed millis trend over time buckets after applying dashboard variables.\";\n }\n\n async getData(\n widgetDefinition: Record<string, any>,\n ctxt: IDashboardWidgetDataProviderContext,\n ): Promise<IDashboardWidgetDataResponseEnvelope<any>> {\n const bucket = normalizeBucket(ctxt?.providerContext?.bucket);\n\n const qb = await this.mqMessageRepository.createSecurityRuleAwareQueryBuilder(\"mqMessage\");\n applyMqDashboardFilters(qb, ctxt.variables ?? {});\n qb.andWhere(\"mqMessage.elapsedMillis IS NOT NULL\");\n\n const bucketExpr = buildMqDashboardBucketExpression(qb, bucket, \"mqMessage.createdAt\");\n const rows = await qb\n .select(bucketExpr, \"bucket\")\n .addSelect(\"AVG(mqMessage.elapsedMillis)\", \"value\")\n .groupBy(bucketExpr)\n .orderBy(\"bucket\", \"ASC\")\n .getRawMany<{ bucket: string; value: string | number }>();\n\n const categories = rows.map((r) => normalizeMqDashboardBucketValue(r.bucket));\n const values = rows.map((r) => Number(toNumber(r.value).toFixed(2)));\n\n return {\n meta: {\n providerName: this.name(),\n generatedAt: new Date().toISOString(),\n widgetName: ctxt.widgetName,\n durationMs: 0,\n },\n data: {\n categories,\n series: [{ name: \"avg_elapsed_millis\", data: values }],\n bucket,\n },\n };\n }\n}\n"]}
|
package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mq-dashboard-messages-over-time-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,4BAA4B,EAAE,mCAAmC,EAAE,oCAAoC,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"mq-dashboard-messages-over-time-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAC3E,OAAO,EAAE,4BAA4B,EAAE,mCAAmC,EAAE,oCAAoC,EAAE,MAAM,gBAAgB,CAAC;AASzI,qBAEa,mCAAoC,YAAW,4BAA4B;IAEhF,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAAnB,mBAAmB,EAAE,mBAAmB;IAG7D,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAIR,OAAO,CACT,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACrC,IAAI,EAAE,mCAAmC,GAC1C,OAAO,CAAC,oCAAoC,CAAC,GAAG,CAAC,CAAC;CAqDxD"}
|
package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.js
CHANGED
|
@@ -31,7 +31,7 @@ let MqDashboardMessagesOverTimeProvider = class MqDashboardMessagesOverTimeProvi
|
|
|
31
31
|
: ["total", "succeeded", "failed", "retrying"];
|
|
32
32
|
const qb = await this.mqMessageRepository.createSecurityRuleAwareQueryBuilder("mqMessage");
|
|
33
33
|
(0, mq_dashboard_provider_utils_1.applyMqDashboardFilters)(qb, ctxt.variables ?? {});
|
|
34
|
-
const bucketExpr =
|
|
34
|
+
const bucketExpr = (0, mq_dashboard_provider_utils_1.buildMqDashboardBucketExpression)(qb, bucket, "mqMessage.createdAt");
|
|
35
35
|
const rows = await qb
|
|
36
36
|
.select(bucketExpr, "bucket")
|
|
37
37
|
.addSelect("mqMessage.stage", "stage")
|
|
@@ -42,7 +42,7 @@ let MqDashboardMessagesOverTimeProvider = class MqDashboardMessagesOverTimeProvi
|
|
|
42
42
|
.getRawMany();
|
|
43
43
|
const bucketToStageMap = new Map();
|
|
44
44
|
for (const row of rows) {
|
|
45
|
-
const key =
|
|
45
|
+
const key = (0, mq_dashboard_provider_utils_1.normalizeMqDashboardBucketValue)(row.bucket);
|
|
46
46
|
const entry = bucketToStageMap.get(key) ?? {};
|
|
47
47
|
entry[row.stage] = (entry[row.stage] ?? 0) + (0, mq_dashboard_provider_utils_1.toNumber)(row.count, 0);
|
|
48
48
|
bucketToStageMap.set(key, entry);
|
package/dist/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mq-dashboard-messages-over-time-provider.service.js","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,wHAAsG;AACtG,kFAA2E;AAE3E,+
|
|
1
|
+
{"version":3,"file":"mq-dashboard-messages-over-time-provider.service.js","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-messages-over-time-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { DashboardWidgetDataProvider } from \"src/decorators/dashboard-widget-data-provider.decorator\";\nimport { MqMessageRepository } from \"src/repository/mq-message.repository\";\nimport { IDashboardWidgetDataProvider, IDashboardWidgetDataProviderContext, IDashboardWidgetDataResponseEnvelope } from \"src/interfaces\";\nimport {\n applyMqDashboardFilters,\n buildMqDashboardBucketExpression,\n normalizeBucket,\n normalizeMqDashboardBucketValue,\n toNumber,\n} from \"src/services/dashboard-providers/mq-dashboard-provider-utils\";\n\n@DashboardWidgetDataProvider()\n@Injectable()\nexport class MqDashboardMessagesOverTimeProvider implements IDashboardWidgetDataProvider {\n constructor(\n private readonly mqMessageRepository: MqMessageRepository,\n ) { }\n\n name(): string {\n return \"MqDashboardMessagesOverTimeProvider\";\n }\n\n help(): string {\n return \"Returns time-series message counts by stage (and total) after applying dashboard variables.\";\n }\n\n async getData(\n widgetDefinition: Record<string, any>,\n ctxt: IDashboardWidgetDataProviderContext,\n ): Promise<IDashboardWidgetDataResponseEnvelope<any>> {\n const bucket = normalizeBucket(ctxt?.providerContext?.bucket);\n const requestedSeries: string[] = Array.isArray(ctxt?.providerContext?.series) && ctxt.providerContext.series.length > 0\n ? ctxt.providerContext.series\n : [\"total\", \"succeeded\", \"failed\", \"retrying\"];\n\n const qb = await this.mqMessageRepository.createSecurityRuleAwareQueryBuilder(\"mqMessage\");\n applyMqDashboardFilters(qb, ctxt.variables ?? {});\n\n const bucketExpr = buildMqDashboardBucketExpression(qb, bucket, \"mqMessage.createdAt\");\n const rows = await qb\n .select(bucketExpr, \"bucket\")\n .addSelect(\"mqMessage.stage\", \"stage\")\n .addSelect(\"COUNT(mqMessage.id)\", \"count\")\n .groupBy(bucketExpr)\n .addGroupBy(\"mqMessage.stage\")\n .orderBy(\"bucket\", \"ASC\")\n .getRawMany<{ bucket: string; stage: string; count: string | number }>();\n\n const bucketToStageMap = new Map<string, Record<string, number>>();\n for (const row of rows) {\n const key = normalizeMqDashboardBucketValue(row.bucket);\n const entry = bucketToStageMap.get(key) ?? {};\n entry[row.stage] = (entry[row.stage] ?? 0) + toNumber(row.count, 0);\n bucketToStageMap.set(key, entry);\n }\n\n const categories = Array.from(bucketToStageMap.keys()).sort();\n const series = requestedSeries.map((seriesName) => {\n const data = categories.map((category) => {\n const stageMap = bucketToStageMap.get(category) ?? {};\n if (seriesName === \"total\") {\n return Object.values(stageMap).reduce((sum, value) => sum + value, 0);\n }\n return stageMap[seriesName] ?? 0;\n });\n return { name: seriesName, data };\n });\n\n return {\n meta: {\n providerName: this.name(),\n generatedAt: new Date().toISOString(),\n widgetName: ctxt.widgetName,\n durationMs: 0,\n },\n data: {\n categories,\n series,\n bucket,\n },\n };\n }\n}\n"]}
|
|
@@ -14,4 +14,7 @@ export interface ApplyMqDashboardFiltersOptions {
|
|
|
14
14
|
export declare function applyMqDashboardFilters(qb: SelectQueryBuilder<MqMessage>, variables?: MqDashboardVariables, options?: ApplyMqDashboardFiltersOptions): SelectQueryBuilder<MqMessage>;
|
|
15
15
|
export declare function normalizeBucket(value: string | undefined): 'hour' | 'day' | 'week' | 'month';
|
|
16
16
|
export declare function toNumber(value: any, fallback?: number): number;
|
|
17
|
+
export declare function buildMqDashboardBucketExpression(qb: SelectQueryBuilder<MqMessage>, bucket: 'hour' | 'day' | 'week' | 'month', columnExpr: string): string;
|
|
18
|
+
export declare function normalizeMqDashboardBucketValue(value: any): string;
|
|
19
|
+
export declare function applyCaseInsensitiveContainsFilter<T>(qb: SelectQueryBuilder<T>, qualifiedColumn: string, query: string | undefined, paramKey: string): void;
|
|
17
20
|
//# sourceMappingURL=mq-dashboard-provider-utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mq-dashboard-provider-utils.d.ts","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-provider-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C,eAAO,MAAM,kBAAkB,UAA2D,CAAC;AAE3F,MAAM,WAAW,oBAAoB;IACjC,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,8BAA8B;IAC3C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,uBAAuB,CACnC,EAAE,EAAE,kBAAkB,CAAC,SAAS,CAAC,EACjC,SAAS,GAAE,oBAAyB,EACpC,OAAO,GAAE,8BAAmC,GAC7C,kBAAkB,CAAC,SAAS,CAAC,CAoB/B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAM5F;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,SAAI,GAAG,MAAM,CAGzD"}
|
|
1
|
+
{"version":3,"file":"mq-dashboard-provider-utils.d.ts","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-provider-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAE7C,eAAO,MAAM,kBAAkB,UAA2D,CAAC;AAE3F,MAAM,WAAW,oBAAoB;IACjC,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,8BAA8B;IAC3C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,wBAAgB,uBAAuB,CACnC,EAAE,EAAE,kBAAkB,CAAC,SAAS,CAAC,EACjC,SAAS,GAAE,oBAAyB,EACpC,OAAO,GAAE,8BAAmC,GAC7C,kBAAkB,CAAC,SAAS,CAAC,CAoB/B;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAM5F;AAED,wBAAgB,QAAQ,CAAC,KAAK,EAAE,GAAG,EAAE,QAAQ,SAAI,GAAG,MAAM,CAGzD;AAED,wBAAgB,gCAAgC,CAC5C,EAAE,EAAE,kBAAkB,CAAC,SAAS,CAAC,EACjC,MAAM,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,EACzC,UAAU,EAAE,MAAM,GACnB,MAAM,CAsCR;AAED,wBAAgB,+BAA+B,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,CAOlE;AAoCD,wBAAgB,kCAAkC,CAAC,CAAC,EAChD,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,EACzB,eAAe,EAAE,MAAM,EACvB,KAAK,EAAE,MAAM,GAAG,SAAS,EACzB,QAAQ,EAAE,MAAM,QAuBnB"}
|
|
@@ -4,6 +4,9 @@ exports.MQ_INFLIGHT_STAGES = void 0;
|
|
|
4
4
|
exports.applyMqDashboardFilters = applyMqDashboardFilters;
|
|
5
5
|
exports.normalizeBucket = normalizeBucket;
|
|
6
6
|
exports.toNumber = toNumber;
|
|
7
|
+
exports.buildMqDashboardBucketExpression = buildMqDashboardBucketExpression;
|
|
8
|
+
exports.normalizeMqDashboardBucketValue = normalizeMqDashboardBucketValue;
|
|
9
|
+
exports.applyCaseInsensitiveContainsFilter = applyCaseInsensitiveContainsFilter;
|
|
7
10
|
exports.MQ_INFLIGHT_STAGES = ['pending', 'scheduled', 'started', 'retry', 'retrying'];
|
|
8
11
|
function applyMqDashboardFilters(qb, variables = {}, options = {}) {
|
|
9
12
|
applyDateFilter(qb, variables.date);
|
|
@@ -31,6 +34,53 @@ function toNumber(value, fallback = 0) {
|
|
|
31
34
|
const n = Number(value);
|
|
32
35
|
return Number.isFinite(n) ? n : fallback;
|
|
33
36
|
}
|
|
37
|
+
function buildMqDashboardBucketExpression(qb, bucket, columnExpr) {
|
|
38
|
+
const driver = `${qb.connection.options.type ?? ''}`.toLowerCase();
|
|
39
|
+
switch (driver) {
|
|
40
|
+
case 'postgres':
|
|
41
|
+
case 'cockroachdb':
|
|
42
|
+
return `DATE_TRUNC('${bucket}', ${columnExpr})`;
|
|
43
|
+
case 'mysql':
|
|
44
|
+
case 'mariadb':
|
|
45
|
+
switch (bucket) {
|
|
46
|
+
case 'hour':
|
|
47
|
+
return `DATE_FORMAT(${columnExpr}, '%Y-%m-%d %H:00:00')`;
|
|
48
|
+
case 'day':
|
|
49
|
+
return `DATE_FORMAT(${columnExpr}, '%Y-%m-%d 00:00:00')`;
|
|
50
|
+
case 'week':
|
|
51
|
+
return `STR_TO_DATE(DATE_FORMAT(${columnExpr}, '%x-%v-1'), '%x-%v-%w')`;
|
|
52
|
+
case 'month':
|
|
53
|
+
return `DATE_FORMAT(${columnExpr}, '%Y-%m-01 00:00:00')`;
|
|
54
|
+
default:
|
|
55
|
+
throw new Error(`Unsupported bucket ${bucket} for driver ${driver}`);
|
|
56
|
+
}
|
|
57
|
+
case 'mssql':
|
|
58
|
+
case 'sqlserver':
|
|
59
|
+
switch (bucket) {
|
|
60
|
+
case 'hour':
|
|
61
|
+
return `DATEADD(hour, DATEDIFF(hour, 0, ${columnExpr}), 0)`;
|
|
62
|
+
case 'day':
|
|
63
|
+
return `DATEADD(day, DATEDIFF(day, 0, ${columnExpr}), 0)`;
|
|
64
|
+
case 'week':
|
|
65
|
+
return `DATEADD(week, DATEDIFF(week, 0, ${columnExpr}), 0)`;
|
|
66
|
+
case 'month':
|
|
67
|
+
return `DATEFROMPARTS(YEAR(${columnExpr}), MONTH(${columnExpr}), 1)`;
|
|
68
|
+
default:
|
|
69
|
+
throw new Error(`Unsupported bucket ${bucket} for driver ${driver}`);
|
|
70
|
+
}
|
|
71
|
+
default:
|
|
72
|
+
throw new Error(`Unsupported driver ${driver} for mq dashboard bucket expressions.`);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
function normalizeMqDashboardBucketValue(value) {
|
|
76
|
+
if (!value)
|
|
77
|
+
return '';
|
|
78
|
+
const parsed = value instanceof Date ? value : new Date(value);
|
|
79
|
+
if (Number.isNaN(parsed.getTime())) {
|
|
80
|
+
return `${value}`;
|
|
81
|
+
}
|
|
82
|
+
return parsed.toISOString();
|
|
83
|
+
}
|
|
34
84
|
function applyDateFilter(qb, dateVariable) {
|
|
35
85
|
const range = resolveDateRange(dateVariable);
|
|
36
86
|
if (range.from) {
|
|
@@ -54,6 +104,27 @@ function applyStringOrArrayFilter(qb, qualifiedColumn, value, paramKey) {
|
|
|
54
104
|
}
|
|
55
105
|
qb.andWhere(`${qualifiedColumn} IN (:...${paramKey})`, { [paramKey]: values });
|
|
56
106
|
}
|
|
107
|
+
function applyCaseInsensitiveContainsFilter(qb, qualifiedColumn, query, paramKey) {
|
|
108
|
+
if (!query) {
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const driver = `${qb.connection.options.type ?? ''}`.toLowerCase();
|
|
112
|
+
const value = `%${query}%`;
|
|
113
|
+
switch (driver) {
|
|
114
|
+
case 'postgres':
|
|
115
|
+
case 'cockroachdb':
|
|
116
|
+
qb.andWhere(`${qualifiedColumn} ILIKE :${paramKey}`, { [paramKey]: value });
|
|
117
|
+
return;
|
|
118
|
+
case 'mysql':
|
|
119
|
+
case 'mariadb':
|
|
120
|
+
case 'mssql':
|
|
121
|
+
case 'sqlserver':
|
|
122
|
+
qb.andWhere(`LOWER(${qualifiedColumn}) LIKE LOWER(:${paramKey})`, { [paramKey]: value });
|
|
123
|
+
return;
|
|
124
|
+
default:
|
|
125
|
+
qb.andWhere(`${qualifiedColumn} LIKE :${paramKey}`, { [paramKey]: value });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
57
128
|
function resolveDateRange(dateVariable) {
|
|
58
129
|
if (!dateVariable)
|
|
59
130
|
return {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mq-dashboard-provider-utils.js","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-provider-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { MqMessage } from \"src/entities/mq-message.entity\";\nimport { SelectQueryBuilder } from \"typeorm\";\n\nexport const MQ_INFLIGHT_STAGES = ['pending', 'scheduled', 'started', 'retry', 'retrying'];\n\nexport interface MqDashboardVariables {\n date?: any;\n queueName?: string | string[];\n stage?: string | string[];\n messageBroker?: string | string[];\n}\n\nexport interface ApplyMqDashboardFiltersOptions {\n ignoreStage?: boolean;\n ensureQueueJoin?: boolean;\n}\n\nexport function applyMqDashboardFilters(\n qb: SelectQueryBuilder<MqMessage>,\n variables: MqDashboardVariables = {},\n options: ApplyMqDashboardFiltersOptions = {},\n): SelectQueryBuilder<MqMessage> {\n applyDateFilter(qb, variables.date);\n applyStringOrArrayFilter(qb, 'mqMessage.messageBroker', variables.messageBroker, 'messageBroker');\n\n if (!options.ignoreStage) {\n applyStringOrArrayFilter(qb, 'mqMessage.stage', variables.stage, 'stage');\n }\n\n if (\n options.ensureQueueJoin ||\n (variables.queueName !== undefined && variables.queueName !== null && variables.queueName !== '')\n ) {\n qb.leftJoin('mqMessage.mqMessageQueue', 'mqMessageQueue');\n }\n\n if (variables.queueName !== undefined && variables.queueName !== null && variables.queueName !== '') {\n applyStringOrArrayFilter(qb, 'mqMessageQueue.name', variables.queueName, 'queueName');\n }\n\n return qb;\n}\n\nexport function normalizeBucket(value: string | undefined): 'hour' | 'day' | 'week' | 'month' {\n const v = `${value ?? ''}`.toLowerCase();\n if (v === 'hour' || v === 'day' || v === 'week' || v === 'month') {\n return v;\n }\n return 'hour';\n}\n\nexport function toNumber(value: any, fallback = 0): number {\n const n = Number(value);\n return Number.isFinite(n) ? n : fallback;\n}\n\n\nfunction applyDateFilter(qb: SelectQueryBuilder<MqMessage>, dateVariable: any): void {\n const range = resolveDateRange(dateVariable);\n if (range.from) {\n qb.andWhere('mqMessage.createdAt >= :dashboardDateFrom', { dashboardDateFrom: range.from.toISOString() });\n }\n if (range.to) {\n qb.andWhere('mqMessage.createdAt <= :dashboardDateTo', { dashboardDateTo: range.to.toISOString() });\n }\n}\n\nfunction applyStringOrArrayFilter(\n qb: SelectQueryBuilder<MqMessage>,\n qualifiedColumn: string,\n value: string | string[] | undefined,\n paramKey: string,\n) {\n if (value === undefined || value === null || value === '') {\n return;\n }\n\n const values = Array.isArray(value) ? value.filter((v) => !!v) : [value];\n if (values.length === 0) {\n return;\n }\n\n if (values.length === 1) {\n qb.andWhere(`${qualifiedColumn} = :${paramKey}`, { [paramKey]: values[0] });\n return;\n }\n\n qb.andWhere(`${qualifiedColumn} IN (:...${paramKey})`, { [paramKey]: values });\n}\n\nfunction resolveDateRange(dateVariable: any): { from?: Date; to?: Date } {\n if (!dateVariable) return {};\n\n if (Array.isArray(dateVariable) && dateVariable.length >= 2) {\n return {\n from: parseDate(dateVariable[0]),\n to: parseDate(dateVariable[1]),\n };\n }\n\n if (typeof dateVariable === 'object') {\n const presetRange = resolvePresetRange(dateVariable.preset);\n const from = parseDate(dateVariable.from ?? dateVariable.start ?? dateVariable.startDate) ?? presetRange.from;\n const to = parseDate(dateVariable.to ?? dateVariable.end ?? dateVariable.endDate) ?? presetRange.to;\n return { from, to };\n }\n\n if (typeof dateVariable === 'string') {\n const presetRange = resolvePresetRange(dateVariable);\n if (presetRange.from || presetRange.to) {\n return presetRange;\n }\n const parsed = parseDate(dateVariable);\n if (!parsed) return {};\n return { from: parsed, to: parsed };\n }\n\n return {};\n}\n\nfunction parseDate(value: any): Date | undefined {\n if (!value) return undefined;\n const d = new Date(value);\n if (Number.isNaN(d.getTime())) return undefined;\n return d;\n}\n\nfunction resolvePresetRange(preset: string | undefined): { from?: Date; to?: Date } {\n if (!preset) return {};\n\n const now = new Date();\n const to = new Date(now);\n switch (preset) {\n case 'today': {\n const from = new Date(now);\n from.setHours(0, 0, 0, 0);\n return { from, to };\n }\n case 'yesterday': {\n const from = new Date(now);\n from.setDate(from.getDate() - 1);\n from.setHours(0, 0, 0, 0);\n const end = new Date(from);\n end.setHours(23, 59, 59, 999);\n return { from, to: end };\n }\n case 'last_24_hours': {\n const from = new Date(now);\n from.setHours(from.getHours() - 24);\n return { from, to };\n }\n case 'last_7_days': {\n const from = new Date(now);\n from.setDate(from.getDate() - 7);\n return { from, to };\n }\n case 'last_30_days': {\n const from = new Date(now);\n from.setDate(from.getDate() - 30);\n return { from, to };\n }\n default:\n return {};\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mq-dashboard-provider-utils.js","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-provider-utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { MqMessage } from \"src/entities/mq-message.entity\";\nimport { SelectQueryBuilder } from \"typeorm\";\n\nexport const MQ_INFLIGHT_STAGES = ['pending', 'scheduled', 'started', 'retry', 'retrying'];\n\nexport interface MqDashboardVariables {\n date?: any;\n queueName?: string | string[];\n stage?: string | string[];\n messageBroker?: string | string[];\n}\n\nexport interface ApplyMqDashboardFiltersOptions {\n ignoreStage?: boolean;\n ensureQueueJoin?: boolean;\n}\n\nexport function applyMqDashboardFilters(\n qb: SelectQueryBuilder<MqMessage>,\n variables: MqDashboardVariables = {},\n options: ApplyMqDashboardFiltersOptions = {},\n): SelectQueryBuilder<MqMessage> {\n applyDateFilter(qb, variables.date);\n applyStringOrArrayFilter(qb, 'mqMessage.messageBroker', variables.messageBroker, 'messageBroker');\n\n if (!options.ignoreStage) {\n applyStringOrArrayFilter(qb, 'mqMessage.stage', variables.stage, 'stage');\n }\n\n if (\n options.ensureQueueJoin ||\n (variables.queueName !== undefined && variables.queueName !== null && variables.queueName !== '')\n ) {\n qb.leftJoin('mqMessage.mqMessageQueue', 'mqMessageQueue');\n }\n\n if (variables.queueName !== undefined && variables.queueName !== null && variables.queueName !== '') {\n applyStringOrArrayFilter(qb, 'mqMessageQueue.name', variables.queueName, 'queueName');\n }\n\n return qb;\n}\n\nexport function normalizeBucket(value: string | undefined): 'hour' | 'day' | 'week' | 'month' {\n const v = `${value ?? ''}`.toLowerCase();\n if (v === 'hour' || v === 'day' || v === 'week' || v === 'month') {\n return v;\n }\n return 'hour';\n}\n\nexport function toNumber(value: any, fallback = 0): number {\n const n = Number(value);\n return Number.isFinite(n) ? n : fallback;\n}\n\nexport function buildMqDashboardBucketExpression(\n qb: SelectQueryBuilder<MqMessage>,\n bucket: 'hour' | 'day' | 'week' | 'month',\n columnExpr: string,\n): string {\n const driver = `${qb.connection.options.type ?? ''}`.toLowerCase();\n\n switch (driver) {\n case 'postgres':\n case 'cockroachdb':\n return `DATE_TRUNC('${bucket}', ${columnExpr})`;\n case 'mysql':\n case 'mariadb':\n switch (bucket) {\n case 'hour':\n return `DATE_FORMAT(${columnExpr}, '%Y-%m-%d %H:00:00')`;\n case 'day':\n return `DATE_FORMAT(${columnExpr}, '%Y-%m-%d 00:00:00')`;\n case 'week':\n return `STR_TO_DATE(DATE_FORMAT(${columnExpr}, '%x-%v-1'), '%x-%v-%w')`;\n case 'month':\n return `DATE_FORMAT(${columnExpr}, '%Y-%m-01 00:00:00')`;\n default:\n throw new Error(`Unsupported bucket ${bucket} for driver ${driver}`);\n }\n case 'mssql':\n case 'sqlserver':\n switch (bucket) {\n case 'hour':\n return `DATEADD(hour, DATEDIFF(hour, 0, ${columnExpr}), 0)`;\n case 'day':\n return `DATEADD(day, DATEDIFF(day, 0, ${columnExpr}), 0)`;\n case 'week':\n return `DATEADD(week, DATEDIFF(week, 0, ${columnExpr}), 0)`;\n case 'month':\n return `DATEFROMPARTS(YEAR(${columnExpr}), MONTH(${columnExpr}), 1)`;\n default:\n throw new Error(`Unsupported bucket ${bucket} for driver ${driver}`);\n }\n default:\n throw new Error(`Unsupported driver ${driver} for mq dashboard bucket expressions.`);\n }\n}\n\nexport function normalizeMqDashboardBucketValue(value: any): string {\n if (!value) return '';\n const parsed = value instanceof Date ? value : new Date(value);\n if (Number.isNaN(parsed.getTime())) {\n return `${value}`;\n }\n return parsed.toISOString();\n}\n\n\nfunction applyDateFilter(qb: SelectQueryBuilder<MqMessage>, dateVariable: any): void {\n const range = resolveDateRange(dateVariable);\n if (range.from) {\n qb.andWhere('mqMessage.createdAt >= :dashboardDateFrom', { dashboardDateFrom: range.from.toISOString() });\n }\n if (range.to) {\n qb.andWhere('mqMessage.createdAt <= :dashboardDateTo', { dashboardDateTo: range.to.toISOString() });\n }\n}\n\nfunction applyStringOrArrayFilter(\n qb: SelectQueryBuilder<MqMessage>,\n qualifiedColumn: string,\n value: string | string[] | undefined,\n paramKey: string,\n) {\n if (value === undefined || value === null || value === '') {\n return;\n }\n\n const values = Array.isArray(value) ? value.filter((v) => !!v) : [value];\n if (values.length === 0) {\n return;\n }\n\n if (values.length === 1) {\n qb.andWhere(`${qualifiedColumn} = :${paramKey}`, { [paramKey]: values[0] });\n return;\n }\n\n qb.andWhere(`${qualifiedColumn} IN (:...${paramKey})`, { [paramKey]: values });\n}\n\nexport function applyCaseInsensitiveContainsFilter<T>(\n qb: SelectQueryBuilder<T>,\n qualifiedColumn: string,\n query: string | undefined,\n paramKey: string,\n) {\n if (!query) {\n return;\n }\n\n const driver = `${qb.connection.options.type ?? ''}`.toLowerCase();\n const value = `%${query}%`;\n\n switch (driver) {\n case 'postgres':\n case 'cockroachdb':\n qb.andWhere(`${qualifiedColumn} ILIKE :${paramKey}`, { [paramKey]: value });\n return;\n case 'mysql':\n case 'mariadb':\n case 'mssql':\n case 'sqlserver':\n qb.andWhere(`LOWER(${qualifiedColumn}) LIKE LOWER(:${paramKey})`, { [paramKey]: value });\n return;\n default:\n qb.andWhere(`${qualifiedColumn} LIKE :${paramKey}`, { [paramKey]: value });\n }\n}\n\nfunction resolveDateRange(dateVariable: any): { from?: Date; to?: Date } {\n if (!dateVariable) return {};\n\n if (Array.isArray(dateVariable) && dateVariable.length >= 2) {\n return {\n from: parseDate(dateVariable[0]),\n to: parseDate(dateVariable[1]),\n };\n }\n\n if (typeof dateVariable === 'object') {\n const presetRange = resolvePresetRange(dateVariable.preset);\n const from = parseDate(dateVariable.from ?? dateVariable.start ?? dateVariable.startDate) ?? presetRange.from;\n const to = parseDate(dateVariable.to ?? dateVariable.end ?? dateVariable.endDate) ?? presetRange.to;\n return { from, to };\n }\n\n if (typeof dateVariable === 'string') {\n const presetRange = resolvePresetRange(dateVariable);\n if (presetRange.from || presetRange.to) {\n return presetRange;\n }\n const parsed = parseDate(dateVariable);\n if (!parsed) return {};\n return { from: parsed, to: parsed };\n }\n\n return {};\n}\n\nfunction parseDate(value: any): Date | undefined {\n if (!value) return undefined;\n const d = new Date(value);\n if (Number.isNaN(d.getTime())) return undefined;\n return d;\n}\n\nfunction resolvePresetRange(preset: string | undefined): { from?: Date; to?: Date } {\n if (!preset) return {};\n\n const now = new Date();\n const to = new Date(now);\n switch (preset) {\n case 'today': {\n const from = new Date(now);\n from.setHours(0, 0, 0, 0);\n return { from, to };\n }\n case 'yesterday': {\n const from = new Date(now);\n from.setDate(from.getDate() - 1);\n from.setHours(0, 0, 0, 0);\n const end = new Date(from);\n end.setHours(23, 59, 59, 999);\n return { from, to: end };\n }\n case 'last_24_hours': {\n const from = new Date(now);\n from.setHours(from.getHours() - 24);\n return { from, to };\n }\n case 'last_7_days': {\n const from = new Date(now);\n from.setDate(from.getDate() - 7);\n return { from, to };\n }\n case 'last_30_days': {\n const from = new Date(now);\n from.setDate(from.getDate() - 30);\n return { from, to };\n }\n default:\n return {};\n }\n}\n"]}
|
package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mq-dashboard-queue-sla-heatmap-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,EAAE,mCAAmC,EAAE,oCAAoC,EAAE,MAAM,gBAAgB,CAAC;AACzI,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;
|
|
1
|
+
{"version":3,"file":"mq-dashboard-queue-sla-heatmap-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,4BAA4B,EAAE,mCAAmC,EAAE,oCAAoC,EAAE,MAAM,gBAAgB,CAAC;AACzI,OAAO,EAAE,mBAAmB,EAAE,MAAM,sCAAsC,CAAC;AAS3E,KAAK,sBAAsB,GAAG;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,KAAK,kBAAkB,GAAG;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;CAC7B,CAAC;AAEF,KAAK,uBAAuB,GAAG;IAC3B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,YAAY,CAAC,EAAE,kBAAkB,EAAE,CAAC;IACpC,gBAAgB,CAAC,EAAE,sBAAsB,EAAE,CAAC;CAC/C,CAAC;AASF,qBAEa,kCAAmC,YAAW,4BAA4B;IAE/E,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAAnB,mBAAmB,EAAE,mBAAmB;IAG7D,IAAI,IAAI,MAAM;IAId,IAAI,IAAI,MAAM;IAIR,OAAO,CACT,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACrC,IAAI,EAAE,mCAAmC,GAC1C,OAAO,CAAC,oCAAoC,CAAC,uBAAuB,CAAC,CAAC;CA8F5E"}
|
package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.js
CHANGED
|
@@ -41,7 +41,7 @@ let MqDashboardQueueSlaHeatmapProvider = class MqDashboardQueueSlaHeatmapProvide
|
|
|
41
41
|
const qb = await this.mqMessageRepository.createSecurityRuleAwareQueryBuilder("mqMessage");
|
|
42
42
|
(0, mq_dashboard_provider_utils_1.applyMqDashboardFilters)(qb, ctxt.variables ?? {}, { ensureQueueJoin: true });
|
|
43
43
|
qb.andWhere("mqMessage.elapsedMillis IS NOT NULL");
|
|
44
|
-
const bucketExpr =
|
|
44
|
+
const bucketExpr = (0, mq_dashboard_provider_utils_1.buildMqDashboardBucketExpression)(qb, bucket, "mqMessage.createdAt");
|
|
45
45
|
const rows = await qb
|
|
46
46
|
.select(bucketExpr, "bucket")
|
|
47
47
|
.addSelect("mqMessageQueue.name", "queueName")
|
|
@@ -54,7 +54,7 @@ let MqDashboardQueueSlaHeatmapProvider = class MqDashboardQueueSlaHeatmapProvide
|
|
|
54
54
|
.addOrderBy("mqMessageQueue.name", "ASC")
|
|
55
55
|
.getRawMany();
|
|
56
56
|
const xCategories = Array.from(new Set(rows
|
|
57
|
-
.map((row) =>
|
|
57
|
+
.map((row) => (0, mq_dashboard_provider_utils_1.normalizeMqDashboardBucketValue)(row?.bucket))
|
|
58
58
|
.filter((bucketValue) => !!bucketValue))).sort();
|
|
59
59
|
const yCategories = Array.from(new Set(rows.map((row) => `${row?.queueName ?? ""}`.trim()).filter((queueName) => !!queueName))).sort((left, right) => left.localeCompare(right));
|
|
60
60
|
const xIndexMap = new Map(xCategories.map((value, index) => [value, index]));
|
|
@@ -62,7 +62,7 @@ let MqDashboardQueueSlaHeatmapProvider = class MqDashboardQueueSlaHeatmapProvide
|
|
|
62
62
|
const points = [];
|
|
63
63
|
const pointDetails = [];
|
|
64
64
|
for (const row of rows) {
|
|
65
|
-
const bucketValue =
|
|
65
|
+
const bucketValue = (0, mq_dashboard_provider_utils_1.normalizeMqDashboardBucketValue)(row?.bucket);
|
|
66
66
|
const queueName = `${row?.queueName ?? ""}`.trim();
|
|
67
67
|
const xIndex = xIndexMap.get(bucketValue);
|
|
68
68
|
const yIndex = yIndexMap.get(queueName);
|
package/dist/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mq-dashboard-queue-sla-heatmap-provider.service.js","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { DashboardWidgetDataProvider } from \"src/decorators/dashboard-widget-data-provider.decorator\";\nimport { IDashboardWidgetDataProvider, IDashboardWidgetDataProviderContext, IDashboardWidgetDataResponseEnvelope } from \"src/interfaces\";\nimport { MqMessageRepository } from \"src/repository/mq-message.repository\";\nimport { applyMqDashboardFilters, normalizeBucket, toNumber } from \"src/services/dashboard-providers/mq-dashboard-provider-utils\";\n\ntype HeatmapLegendThreshold = {\n label: string;\n color: string;\n lte?: number;\n gte?: number;\n gt?: number;\n};\n\ntype HeatmapPointDetail = {\n xIndex: number;\n yIndex: number;\n bucket: string;\n queueName: string;\n avgElapsedMillis: number;\n messageCount: number;\n peakElapsedMillis: number;\n};\n\ntype QueueSlaHeatmapResponse = {\n xCategories: string[];\n yCategories: string[];\n points: [number, number, number][];\n metric: string;\n bucket: string;\n tooltipFields?: string[];\n pointDetails?: HeatmapPointDetail[];\n legendThresholds?: HeatmapLegendThreshold[];\n};\n\nconst DEFAULT_LEGEND_THRESHOLDS: HeatmapLegendThreshold[] = [\n { label: \"0-5s\", color: \"#22c55e\", lte: 5000 },\n { label: \"5-15s\", color: \"#f59e0b\", gt: 5000, lte: 15000 },\n { label: \"15-30s\", color: \"#f97316\", gt: 15000, lte: 30000 },\n { label: \"30s+\", color: \"#ef4444\", gt: 30000 },\n];\n\n@DashboardWidgetDataProvider()\n@Injectable()\nexport class MqDashboardQueueSlaHeatmapProvider implements IDashboardWidgetDataProvider {\n constructor(\n private readonly mqMessageRepository: MqMessageRepository,\n ) { }\n\n name(): string {\n return \"MqDashboardQueueSlaHeatmapProvider\";\n }\n\n help(): string {\n return \"Returns queue-wise SLA heatmap data using average elapsed millis across time buckets.\";\n }\n\n async getData(\n widgetDefinition: Record<string, any>,\n ctxt: IDashboardWidgetDataProviderContext,\n ): Promise<IDashboardWidgetDataResponseEnvelope<QueueSlaHeatmapResponse>> {\n const bucket = normalizeBucket(ctxt?.providerContext?.bucket);\n const legendThresholds = Array.isArray(ctxt?.providerContext?.legendThresholds) && ctxt.providerContext.legendThresholds.length > 0\n ? ctxt.providerContext.legendThresholds\n : DEFAULT_LEGEND_THRESHOLDS;\n const tooltipFields = Array.isArray(ctxt?.providerContext?.tooltipFields) && ctxt.providerContext.tooltipFields.length > 0\n ? ctxt.providerContext.tooltipFields\n : [\"avgElapsedMillis\", \"messageCount\", \"peakElapsedMillis\"];\n\n const qb = await this.mqMessageRepository.createSecurityRuleAwareQueryBuilder(\"mqMessage\");\n applyMqDashboardFilters(qb, ctxt.variables ?? {}, { ensureQueueJoin: true });\n qb.andWhere(\"mqMessage.elapsedMillis IS NOT NULL\");\n\n const bucketExpr = `DATE_TRUNC('${bucket}', mqMessage.createdAt)`;\n const rows = await qb\n .select(bucketExpr, \"bucket\")\n .addSelect(\"mqMessageQueue.name\", \"queueName\")\n .addSelect(\"AVG(mqMessage.elapsedMillis)\", \"avgElapsedMillis\")\n .addSelect(\"COUNT(mqMessage.id)\", \"messageCount\")\n .addSelect(\"MAX(mqMessage.elapsedMillis)\", \"peakElapsedMillis\")\n .groupBy(bucketExpr)\n .addGroupBy(\"mqMessageQueue.name\")\n .orderBy(\"bucket\", \"ASC\")\n .addOrderBy(\"mqMessageQueue.name\", \"ASC\")\n .getRawMany<{\n bucket: string;\n queueName: string;\n avgElapsedMillis: string | number;\n messageCount: string | number;\n peakElapsedMillis: string | number;\n }>();\n\n const xCategories = Array.from(\n new Set(\n rows\n .map((row) => row?.bucket ? new Date(row.bucket).toISOString() : \"\")\n .filter((bucketValue) => !!bucketValue)\n )\n ).sort();\n const yCategories = Array.from(\n new Set(rows.map((row) => `${row?.queueName ?? \"\"}`.trim()).filter((queueName) => !!queueName))\n ).sort((left, right) => left.localeCompare(right));\n\n const xIndexMap = new Map(xCategories.map((value, index) => [value, index]));\n const yIndexMap = new Map(yCategories.map((value, index) => [value, index]));\n\n const points: [number, number, number][] = [];\n const pointDetails: HeatmapPointDetail[] = [];\n\n for (const row of rows) {\n const bucketValue = row?.bucket ? new Date(row.bucket).toISOString() : \"\";\n const queueName = `${row?.queueName ?? \"\"}`.trim();\n const xIndex = xIndexMap.get(bucketValue);\n const yIndex = yIndexMap.get(queueName);\n\n if (xIndex === undefined || yIndex === undefined) {\n continue;\n }\n\n const avgElapsedMillis = Number(toNumber(row.avgElapsedMillis).toFixed(2));\n const messageCount = toNumber(row.messageCount);\n const peakElapsedMillis = Number(toNumber(row.peakElapsedMillis).toFixed(2));\n\n points.push([xIndex, yIndex, avgElapsedMillis]);\n pointDetails.push({\n xIndex,\n yIndex,\n bucket: bucketValue,\n queueName,\n avgElapsedMillis,\n messageCount,\n peakElapsedMillis,\n });\n }\n\n return {\n meta: {\n providerName: this.name(),\n generatedAt: new Date().toISOString(),\n widgetName: ctxt.widgetName,\n durationMs: 0,\n },\n data: {\n xCategories,\n yCategories,\n points,\n metric: \"avg_elapsed_millis\",\n bucket,\n tooltipFields,\n pointDetails,\n legendThresholds,\n },\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"mq-dashboard-queue-sla-heatmap-provider.service.js","sourceRoot":"","sources":["../../../src/services/dashboard-providers/mq-dashboard-queue-sla-heatmap-provider.service.ts"],"names":[],"mappings":"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","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { DashboardWidgetDataProvider } from \"src/decorators/dashboard-widget-data-provider.decorator\";\nimport { IDashboardWidgetDataProvider, IDashboardWidgetDataProviderContext, IDashboardWidgetDataResponseEnvelope } from \"src/interfaces\";\nimport { MqMessageRepository } from \"src/repository/mq-message.repository\";\nimport {\n applyMqDashboardFilters,\n buildMqDashboardBucketExpression,\n normalizeBucket,\n normalizeMqDashboardBucketValue,\n toNumber,\n} from \"src/services/dashboard-providers/mq-dashboard-provider-utils\";\n\ntype HeatmapLegendThreshold = {\n label: string;\n color: string;\n lte?: number;\n gte?: number;\n gt?: number;\n};\n\ntype HeatmapPointDetail = {\n xIndex: number;\n yIndex: number;\n bucket: string;\n queueName: string;\n avgElapsedMillis: number;\n messageCount: number;\n peakElapsedMillis: number;\n};\n\ntype QueueSlaHeatmapResponse = {\n xCategories: string[];\n yCategories: string[];\n points: [number, number, number][];\n metric: string;\n bucket: string;\n tooltipFields?: string[];\n pointDetails?: HeatmapPointDetail[];\n legendThresholds?: HeatmapLegendThreshold[];\n};\n\nconst DEFAULT_LEGEND_THRESHOLDS: HeatmapLegendThreshold[] = [\n { label: \"0-5s\", color: \"#22c55e\", lte: 5000 },\n { label: \"5-15s\", color: \"#f59e0b\", gt: 5000, lte: 15000 },\n { label: \"15-30s\", color: \"#f97316\", gt: 15000, lte: 30000 },\n { label: \"30s+\", color: \"#ef4444\", gt: 30000 },\n];\n\n@DashboardWidgetDataProvider()\n@Injectable()\nexport class MqDashboardQueueSlaHeatmapProvider implements IDashboardWidgetDataProvider {\n constructor(\n private readonly mqMessageRepository: MqMessageRepository,\n ) { }\n\n name(): string {\n return \"MqDashboardQueueSlaHeatmapProvider\";\n }\n\n help(): string {\n return \"Returns queue-wise SLA heatmap data using average elapsed millis across time buckets.\";\n }\n\n async getData(\n widgetDefinition: Record<string, any>,\n ctxt: IDashboardWidgetDataProviderContext,\n ): Promise<IDashboardWidgetDataResponseEnvelope<QueueSlaHeatmapResponse>> {\n const bucket = normalizeBucket(ctxt?.providerContext?.bucket);\n const legendThresholds = Array.isArray(ctxt?.providerContext?.legendThresholds) && ctxt.providerContext.legendThresholds.length > 0\n ? ctxt.providerContext.legendThresholds\n : DEFAULT_LEGEND_THRESHOLDS;\n const tooltipFields = Array.isArray(ctxt?.providerContext?.tooltipFields) && ctxt.providerContext.tooltipFields.length > 0\n ? ctxt.providerContext.tooltipFields\n : [\"avgElapsedMillis\", \"messageCount\", \"peakElapsedMillis\"];\n\n const qb = await this.mqMessageRepository.createSecurityRuleAwareQueryBuilder(\"mqMessage\");\n applyMqDashboardFilters(qb, ctxt.variables ?? {}, { ensureQueueJoin: true });\n qb.andWhere(\"mqMessage.elapsedMillis IS NOT NULL\");\n\n const bucketExpr = buildMqDashboardBucketExpression(qb, bucket, \"mqMessage.createdAt\");\n const rows = await qb\n .select(bucketExpr, \"bucket\")\n .addSelect(\"mqMessageQueue.name\", \"queueName\")\n .addSelect(\"AVG(mqMessage.elapsedMillis)\", \"avgElapsedMillis\")\n .addSelect(\"COUNT(mqMessage.id)\", \"messageCount\")\n .addSelect(\"MAX(mqMessage.elapsedMillis)\", \"peakElapsedMillis\")\n .groupBy(bucketExpr)\n .addGroupBy(\"mqMessageQueue.name\")\n .orderBy(\"bucket\", \"ASC\")\n .addOrderBy(\"mqMessageQueue.name\", \"ASC\")\n .getRawMany<{\n bucket: string;\n queueName: string;\n avgElapsedMillis: string | number;\n messageCount: string | number;\n peakElapsedMillis: string | number;\n }>();\n\n const xCategories = Array.from(\n new Set(\n rows\n .map((row) => normalizeMqDashboardBucketValue(row?.bucket))\n .filter((bucketValue) => !!bucketValue)\n )\n ).sort();\n const yCategories = Array.from(\n new Set(rows.map((row) => `${row?.queueName ?? \"\"}`.trim()).filter((queueName) => !!queueName))\n ).sort((left, right) => left.localeCompare(right));\n\n const xIndexMap = new Map(xCategories.map((value, index) => [value, index]));\n const yIndexMap = new Map(yCategories.map((value, index) => [value, index]));\n\n const points: [number, number, number][] = [];\n const pointDetails: HeatmapPointDetail[] = [];\n\n for (const row of rows) {\n const bucketValue = normalizeMqDashboardBucketValue(row?.bucket);\n const queueName = `${row?.queueName ?? \"\"}`.trim();\n const xIndex = xIndexMap.get(bucketValue);\n const yIndex = yIndexMap.get(queueName);\n\n if (xIndex === undefined || yIndex === undefined) {\n continue;\n }\n\n const avgElapsedMillis = Number(toNumber(row.avgElapsedMillis).toFixed(2));\n const messageCount = toNumber(row.messageCount);\n const peakElapsedMillis = Number(toNumber(row.peakElapsedMillis).toFixed(2));\n\n points.push([xIndex, yIndex, avgElapsedMillis]);\n pointDetails.push({\n xIndex,\n yIndex,\n bucket: bucketValue,\n queueName,\n avgElapsedMillis,\n messageCount,\n peakElapsedMillis,\n });\n }\n\n return {\n meta: {\n providerName: this.name(),\n generatedAt: new Date().toISOString(),\n widgetName: ctxt.widgetName,\n durationMs: 0,\n },\n data: {\n xCategories,\n yCategories,\n points,\n metric: \"avg_elapsed_millis\",\n bucket,\n tooltipFields,\n pointDetails,\n legendThresholds,\n },\n };\n }\n}\n"]}
|
package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { DataSource } from "typeorm";
|
|
2
|
+
import { DatasourceIntrospectionColumn, DatasourceIntrospectionProvider, DatasourceIntrospectionTableRef } from "../../interfaces/datasource-introspection-provider.interface";
|
|
3
|
+
export declare class MssqlDatasourceIntrospectionProviderService implements DatasourceIntrospectionProvider {
|
|
4
|
+
readonly type = "mssql";
|
|
5
|
+
supports(type: string): boolean;
|
|
6
|
+
listTables(dataSource: DataSource): Promise<DatasourceIntrospectionTableRef[]>;
|
|
7
|
+
listColumns(dataSource: DataSource): Promise<DatasourceIntrospectionColumn[]>;
|
|
8
|
+
getTableDefinition(dataSource: DataSource, table: DatasourceIntrospectionTableRef): Promise<string | null>;
|
|
9
|
+
private toNumberOrNull;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=mssql-datasource-introspection-provider.service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mssql-datasource-introspection-provider.service.d.ts","sourceRoot":"","sources":["../../../src/services/datasource-introspection/mssql-datasource-introspection-provider.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EACH,6BAA6B,EAC7B,+BAA+B,EAC/B,+BAA+B,EAClC,MAAM,4DAA4D,CAAC;AAEpE,qBACa,2CAA4C,YAAW,+BAA+B;IAC/F,QAAQ,CAAC,IAAI,WAAW;IAExB,QAAQ,CAAC,IAAI,EAAE,MAAM;IAIf,UAAU,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,+BAA+B,EAAE,CAAC;IAiB9E,WAAW,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,6BAA6B,EAAE,CAAC;IAwC7E,kBAAkB,CAAC,UAAU,EAAE,UAAU,EAAE,KAAK,EAAE,+BAA+B,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAuGhH,OAAO,CAAC,cAAc;CAQzB"}
|
package/dist/services/datasource-introspection/mssql-datasource-introspection-provider.service.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.MssqlDatasourceIntrospectionProviderService = void 0;
|
|
10
|
+
const common_1 = require("@nestjs/common");
|
|
11
|
+
let MssqlDatasourceIntrospectionProviderService = class MssqlDatasourceIntrospectionProviderService {
|
|
12
|
+
constructor() {
|
|
13
|
+
this.type = "mssql";
|
|
14
|
+
}
|
|
15
|
+
supports(type) {
|
|
16
|
+
return type?.toLowerCase() === this.type;
|
|
17
|
+
}
|
|
18
|
+
async listTables(dataSource) {
|
|
19
|
+
const rows = await dataSource.query(`
|
|
20
|
+
SELECT
|
|
21
|
+
TABLE_SCHEMA AS tableSchema,
|
|
22
|
+
TABLE_NAME AS tableName
|
|
23
|
+
FROM INFORMATION_SCHEMA.TABLES
|
|
24
|
+
WHERE TABLE_TYPE = 'BASE TABLE'
|
|
25
|
+
AND TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')
|
|
26
|
+
ORDER BY TABLE_SCHEMA, TABLE_NAME
|
|
27
|
+
`);
|
|
28
|
+
return rows.map((row) => ({
|
|
29
|
+
tableSchema: row.tableSchema ?? null,
|
|
30
|
+
tableName: row.tableName,
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
async listColumns(dataSource) {
|
|
34
|
+
const rows = await dataSource.query(`
|
|
35
|
+
SELECT
|
|
36
|
+
schema_name(t.schema_id) AS tableSchema,
|
|
37
|
+
t.name AS tableName,
|
|
38
|
+
c.name AS columnName,
|
|
39
|
+
ty.name AS dataType,
|
|
40
|
+
c.is_identity AS isAutoGenerated,
|
|
41
|
+
CASE WHEN c.is_nullable = 1 THEN 'YES' ELSE 'NO' END AS isNullable,
|
|
42
|
+
dc.definition AS defaultValue,
|
|
43
|
+
CASE
|
|
44
|
+
WHEN ty.name IN ('nchar', 'nvarchar') AND c.max_length > 0 THEN c.max_length / 2
|
|
45
|
+
ELSE c.max_length
|
|
46
|
+
END AS characterMaximumLength,
|
|
47
|
+
c.precision AS numericPrecision,
|
|
48
|
+
c.scale AS numericScale,
|
|
49
|
+
c.column_id AS ordinalPosition
|
|
50
|
+
FROM sys.tables t
|
|
51
|
+
INNER JOIN sys.columns c ON c.object_id = t.object_id
|
|
52
|
+
INNER JOIN sys.types ty ON ty.user_type_id = c.user_type_id
|
|
53
|
+
LEFT JOIN sys.default_constraints dc ON dc.object_id = c.default_object_id
|
|
54
|
+
WHERE schema_name(t.schema_id) NOT IN ('sys', 'INFORMATION_SCHEMA')
|
|
55
|
+
ORDER BY schema_name(t.schema_id), t.name, c.column_id
|
|
56
|
+
`);
|
|
57
|
+
return rows.map((row) => ({
|
|
58
|
+
tableSchema: row.tableSchema ?? null,
|
|
59
|
+
tableName: row.tableName,
|
|
60
|
+
columnName: row.columnName,
|
|
61
|
+
dataType: row.dataType,
|
|
62
|
+
isAutoGenerated: Boolean(row.isAutoGenerated),
|
|
63
|
+
isNullable: String(row.isNullable).toUpperCase() === "YES",
|
|
64
|
+
defaultValue: row.defaultValue ?? null,
|
|
65
|
+
characterMaximumLength: this.toNumberOrNull(row.characterMaximumLength),
|
|
66
|
+
numericPrecision: this.toNumberOrNull(row.numericPrecision),
|
|
67
|
+
numericScale: this.toNumberOrNull(row.numericScale),
|
|
68
|
+
ordinalPosition: this.toNumberOrNull(row.ordinalPosition),
|
|
69
|
+
}));
|
|
70
|
+
}
|
|
71
|
+
async getTableDefinition(dataSource, table) {
|
|
72
|
+
const rows = await dataSource.query(`
|
|
73
|
+
DECLARE @schemaName NVARCHAR(128) = @0;
|
|
74
|
+
DECLARE @tableName NVARCHAR(128) = @1;
|
|
75
|
+
|
|
76
|
+
WITH target_table AS (
|
|
77
|
+
SELECT t.object_id, s.name AS schema_name, t.name AS table_name
|
|
78
|
+
FROM sys.tables t
|
|
79
|
+
INNER JOIN sys.schemas s ON s.schema_id = t.schema_id
|
|
80
|
+
WHERE t.name = @tableName
|
|
81
|
+
AND (@schemaName IS NULL OR s.name = @schemaName)
|
|
82
|
+
),
|
|
83
|
+
column_lines AS (
|
|
84
|
+
SELECT
|
|
85
|
+
c.column_id,
|
|
86
|
+
' [' + c.name + '] '
|
|
87
|
+
+ UPPER(ty.name)
|
|
88
|
+
+ CASE
|
|
89
|
+
WHEN ty.name IN ('varchar', 'char', 'varbinary', 'binary') THEN
|
|
90
|
+
'(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(16)) END + ')'
|
|
91
|
+
WHEN ty.name IN ('nvarchar', 'nchar') THEN
|
|
92
|
+
'(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length / 2 AS VARCHAR(16)) END + ')'
|
|
93
|
+
WHEN ty.name IN ('decimal', 'numeric') THEN
|
|
94
|
+
'(' + CAST(c.precision AS VARCHAR(16)) + ',' + CAST(c.scale AS VARCHAR(16)) + ')'
|
|
95
|
+
WHEN ty.name IN ('datetime2', 'datetimeoffset', 'time') THEN
|
|
96
|
+
'(' + CAST(c.scale AS VARCHAR(16)) + ')'
|
|
97
|
+
ELSE
|
|
98
|
+
''
|
|
99
|
+
END
|
|
100
|
+
+ CASE
|
|
101
|
+
WHEN ic.object_id IS NOT NULL THEN
|
|
102
|
+
' IDENTITY(' + CAST(CONVERT(BIGINT, ic.seed_value) AS VARCHAR(32)) + ',' + CAST(CONVERT(BIGINT, ic.increment_value) AS VARCHAR(32)) + ')'
|
|
103
|
+
ELSE
|
|
104
|
+
''
|
|
105
|
+
END
|
|
106
|
+
+ CASE
|
|
107
|
+
WHEN dc.definition IS NOT NULL THEN ' DEFAULT ' + dc.definition
|
|
108
|
+
ELSE ''
|
|
109
|
+
END
|
|
110
|
+
+ CASE
|
|
111
|
+
WHEN c.is_nullable = 1 THEN ' NULL'
|
|
112
|
+
ELSE ' NOT NULL'
|
|
113
|
+
END AS line
|
|
114
|
+
FROM target_table tt
|
|
115
|
+
INNER JOIN sys.columns c ON c.object_id = tt.object_id
|
|
116
|
+
INNER JOIN sys.types ty ON ty.user_type_id = c.user_type_id
|
|
117
|
+
LEFT JOIN sys.identity_columns ic
|
|
118
|
+
ON ic.object_id = c.object_id
|
|
119
|
+
AND ic.column_id = c.column_id
|
|
120
|
+
LEFT JOIN sys.default_constraints dc ON dc.object_id = c.default_object_id
|
|
121
|
+
),
|
|
122
|
+
constraint_lines AS (
|
|
123
|
+
SELECT
|
|
124
|
+
kc.name AS constraint_name,
|
|
125
|
+
' CONSTRAINT [' + kc.name + '] PRIMARY KEY ('
|
|
126
|
+
+ STUFF((
|
|
127
|
+
SELECT ', [' + c.name + ']'
|
|
128
|
+
FROM sys.index_columns ic
|
|
129
|
+
INNER JOIN sys.columns c
|
|
130
|
+
ON c.object_id = ic.object_id
|
|
131
|
+
AND c.column_id = ic.column_id
|
|
132
|
+
WHERE ic.object_id = kc.parent_object_id
|
|
133
|
+
AND ic.index_id = kc.unique_index_id
|
|
134
|
+
ORDER BY ic.key_ordinal
|
|
135
|
+
FOR XML PATH(''), TYPE
|
|
136
|
+
).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
|
|
137
|
+
+ ')' AS line
|
|
138
|
+
FROM target_table tt
|
|
139
|
+
INNER JOIN sys.key_constraints kc ON kc.parent_object_id = tt.object_id
|
|
140
|
+
WHERE kc.type = 'PK'
|
|
141
|
+
)
|
|
142
|
+
SELECT
|
|
143
|
+
'CREATE TABLE [' + tt.schema_name + '].[' + tt.table_name + '] (' + CHAR(10)
|
|
144
|
+
+ ISNULL((
|
|
145
|
+
SELECT STUFF((
|
|
146
|
+
SELECT ',' + CHAR(10) + cl.line
|
|
147
|
+
FROM column_lines cl
|
|
148
|
+
ORDER BY cl.column_id
|
|
149
|
+
FOR XML PATH(''), TYPE
|
|
150
|
+
).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
|
|
151
|
+
), '')
|
|
152
|
+
+ ISNULL((
|
|
153
|
+
SELECT CASE
|
|
154
|
+
WHEN EXISTS (SELECT 1 FROM constraint_lines)
|
|
155
|
+
THEN ',' + CHAR(10) + STUFF((
|
|
156
|
+
SELECT ',' + CHAR(10) + cn.line
|
|
157
|
+
FROM constraint_lines cn
|
|
158
|
+
ORDER BY cn.constraint_name
|
|
159
|
+
FOR XML PATH(''), TYPE
|
|
160
|
+
).value('.', 'NVARCHAR(MAX)'), 1, 2, '')
|
|
161
|
+
ELSE ''
|
|
162
|
+
END
|
|
163
|
+
), '')
|
|
164
|
+
+ CHAR(10) + ');' AS ddl
|
|
165
|
+
FROM target_table tt
|
|
166
|
+
`, [table.tableSchema, table.tableName]);
|
|
167
|
+
return rows?.[0]?.ddl ?? null;
|
|
168
|
+
}
|
|
169
|
+
toNumberOrNull(value) {
|
|
170
|
+
if (value === null || value === undefined || value === "") {
|
|
171
|
+
return null;
|
|
172
|
+
}
|
|
173
|
+
const parsed = Number(value);
|
|
174
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
exports.MssqlDatasourceIntrospectionProviderService = MssqlDatasourceIntrospectionProviderService;
|
|
178
|
+
exports.MssqlDatasourceIntrospectionProviderService = MssqlDatasourceIntrospectionProviderService = __decorate([
|
|
179
|
+
(0, common_1.Injectable)()
|
|
180
|
+
], MssqlDatasourceIntrospectionProviderService);
|
|
181
|
+
//# sourceMappingURL=mssql-datasource-introspection-provider.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mssql-datasource-introspection-provider.service.js","sourceRoot":"","sources":["../../../src/services/datasource-introspection/mssql-datasource-introspection-provider.service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAA4C;AASrC,IAAM,2CAA2C,GAAjD,MAAM,2CAA2C;IAAjD;QACM,SAAI,GAAG,OAAO,CAAC;IA8K5B,CAAC;IA5KG,QAAQ,CAAC,IAAY;QACjB,OAAO,IAAI,EAAE,WAAW,EAAE,KAAK,IAAI,CAAC,IAAI,CAAC;IAC7C,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,UAAsB;QACnC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC;;;;;;;;SAQnC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC;YAC3B,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI;YACpC,SAAS,EAAE,GAAG,CAAC,SAAS;SAC3B,CAAC,CAAC,CAAC;IACR,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,UAAsB;QACpC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;SAsBnC,CAAC,CAAC;QAEH,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC;YAC3B,WAAW,EAAE,GAAG,CAAC,WAAW,IAAI,IAAI;YACpC,SAAS,EAAE,GAAG,CAAC,SAAS;YACxB,UAAU,EAAE,GAAG,CAAC,UAAU;YAC1B,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;YAC7C,UAAU,EAAE,MAAM,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK;YAC1D,YAAY,EAAE,GAAG,CAAC,YAAY,IAAI,IAAI;YACtC,sBAAsB,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,sBAAsB,CAAC;YACvE,gBAAgB,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,gBAAgB,CAAC;YAC3D,YAAY,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,YAAY,CAAC;YACnD,eAAe,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,eAAe,CAAC;SAC5D,CAAC,CAAC,CAAC;IACR,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,UAAsB,EAAE,KAAsC;QACnF,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,KAAK,CAC/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aA8FC,EACD,CAAC,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,CACvC,CAAC;QAEF,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,IAAI,CAAC;IAClC,CAAC;IAEO,cAAc,CAAC,KAAc;QACjC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,EAAE,EAAE,CAAC;YACxD,OAAO,IAAI,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;QAC7B,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;IACnD,CAAC;CACJ,CAAA;AA/KY,kGAA2C;sDAA3C,2CAA2C;IADvD,IAAA,mBAAU,GAAE;GACA,2CAA2C,CA+KvD","sourcesContent":["import { Injectable } from \"@nestjs/common\";\nimport { DataSource } from \"typeorm\";\nimport {\n DatasourceIntrospectionColumn,\n DatasourceIntrospectionProvider,\n DatasourceIntrospectionTableRef,\n} from \"src/interfaces/datasource-introspection-provider.interface\";\n\n@Injectable()\nexport class MssqlDatasourceIntrospectionProviderService implements DatasourceIntrospectionProvider {\n readonly type = \"mssql\";\n\n supports(type: string) {\n return type?.toLowerCase() === this.type;\n }\n\n async listTables(dataSource: DataSource): Promise<DatasourceIntrospectionTableRef[]> {\n const rows = await dataSource.query(`\n SELECT\n TABLE_SCHEMA AS tableSchema,\n TABLE_NAME AS tableName\n FROM INFORMATION_SCHEMA.TABLES\n WHERE TABLE_TYPE = 'BASE TABLE'\n AND TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')\n ORDER BY TABLE_SCHEMA, TABLE_NAME\n `);\n\n return rows.map((row: any) => ({\n tableSchema: row.tableSchema ?? null,\n tableName: row.tableName,\n }));\n }\n\n async listColumns(dataSource: DataSource): Promise<DatasourceIntrospectionColumn[]> {\n const rows = await dataSource.query(`\n SELECT\n schema_name(t.schema_id) AS tableSchema,\n t.name AS tableName,\n c.name AS columnName,\n ty.name AS dataType,\n c.is_identity AS isAutoGenerated,\n CASE WHEN c.is_nullable = 1 THEN 'YES' ELSE 'NO' END AS isNullable,\n dc.definition AS defaultValue,\n CASE\n WHEN ty.name IN ('nchar', 'nvarchar') AND c.max_length > 0 THEN c.max_length / 2\n ELSE c.max_length\n END AS characterMaximumLength,\n c.precision AS numericPrecision,\n c.scale AS numericScale,\n c.column_id AS ordinalPosition\n FROM sys.tables t\n INNER JOIN sys.columns c ON c.object_id = t.object_id\n INNER JOIN sys.types ty ON ty.user_type_id = c.user_type_id\n LEFT JOIN sys.default_constraints dc ON dc.object_id = c.default_object_id\n WHERE schema_name(t.schema_id) NOT IN ('sys', 'INFORMATION_SCHEMA')\n ORDER BY schema_name(t.schema_id), t.name, c.column_id\n `);\n\n return rows.map((row: any) => ({\n tableSchema: row.tableSchema ?? null,\n tableName: row.tableName,\n columnName: row.columnName,\n dataType: row.dataType,\n isAutoGenerated: Boolean(row.isAutoGenerated),\n isNullable: String(row.isNullable).toUpperCase() === \"YES\",\n defaultValue: row.defaultValue ?? null,\n characterMaximumLength: this.toNumberOrNull(row.characterMaximumLength),\n numericPrecision: this.toNumberOrNull(row.numericPrecision),\n numericScale: this.toNumberOrNull(row.numericScale),\n ordinalPosition: this.toNumberOrNull(row.ordinalPosition),\n }));\n }\n\n async getTableDefinition(dataSource: DataSource, table: DatasourceIntrospectionTableRef): Promise<string | null> {\n const rows = await dataSource.query(\n `\n DECLARE @schemaName NVARCHAR(128) = @0;\n DECLARE @tableName NVARCHAR(128) = @1;\n\n WITH target_table AS (\n SELECT t.object_id, s.name AS schema_name, t.name AS table_name\n FROM sys.tables t\n INNER JOIN sys.schemas s ON s.schema_id = t.schema_id\n WHERE t.name = @tableName\n AND (@schemaName IS NULL OR s.name = @schemaName)\n ),\n column_lines AS (\n SELECT\n c.column_id,\n ' [' + c.name + '] '\n + UPPER(ty.name)\n + CASE\n WHEN ty.name IN ('varchar', 'char', 'varbinary', 'binary') THEN\n '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length AS VARCHAR(16)) END + ')'\n WHEN ty.name IN ('nvarchar', 'nchar') THEN\n '(' + CASE WHEN c.max_length = -1 THEN 'MAX' ELSE CAST(c.max_length / 2 AS VARCHAR(16)) END + ')'\n WHEN ty.name IN ('decimal', 'numeric') THEN\n '(' + CAST(c.precision AS VARCHAR(16)) + ',' + CAST(c.scale AS VARCHAR(16)) + ')'\n WHEN ty.name IN ('datetime2', 'datetimeoffset', 'time') THEN\n '(' + CAST(c.scale AS VARCHAR(16)) + ')'\n ELSE\n ''\n END\n + CASE\n WHEN ic.object_id IS NOT NULL THEN\n ' IDENTITY(' + CAST(CONVERT(BIGINT, ic.seed_value) AS VARCHAR(32)) + ',' + CAST(CONVERT(BIGINT, ic.increment_value) AS VARCHAR(32)) + ')'\n ELSE\n ''\n END\n + CASE\n WHEN dc.definition IS NOT NULL THEN ' DEFAULT ' + dc.definition\n ELSE ''\n END\n + CASE\n WHEN c.is_nullable = 1 THEN ' NULL'\n ELSE ' NOT NULL'\n END AS line\n FROM target_table tt\n INNER JOIN sys.columns c ON c.object_id = tt.object_id\n INNER JOIN sys.types ty ON ty.user_type_id = c.user_type_id\n LEFT JOIN sys.identity_columns ic\n ON ic.object_id = c.object_id\n AND ic.column_id = c.column_id\n LEFT JOIN sys.default_constraints dc ON dc.object_id = c.default_object_id\n ),\n constraint_lines AS (\n SELECT\n kc.name AS constraint_name,\n ' CONSTRAINT [' + kc.name + '] PRIMARY KEY ('\n + STUFF((\n SELECT ', [' + c.name + ']'\n FROM sys.index_columns ic\n INNER JOIN sys.columns c\n ON c.object_id = ic.object_id\n AND c.column_id = ic.column_id\n WHERE ic.object_id = kc.parent_object_id\n AND ic.index_id = kc.unique_index_id\n ORDER BY ic.key_ordinal\n FOR XML PATH(''), TYPE\n ).value('.', 'NVARCHAR(MAX)'), 1, 2, '')\n + ')' AS line\n FROM target_table tt\n INNER JOIN sys.key_constraints kc ON kc.parent_object_id = tt.object_id\n WHERE kc.type = 'PK'\n )\n SELECT\n 'CREATE TABLE [' + tt.schema_name + '].[' + tt.table_name + '] (' + CHAR(10)\n + ISNULL((\n SELECT STUFF((\n SELECT ',' + CHAR(10) + cl.line\n FROM column_lines cl\n ORDER BY cl.column_id\n FOR XML PATH(''), TYPE\n ).value('.', 'NVARCHAR(MAX)'), 1, 2, '')\n ), '')\n + ISNULL((\n SELECT CASE\n WHEN EXISTS (SELECT 1 FROM constraint_lines)\n THEN ',' + CHAR(10) + STUFF((\n SELECT ',' + CHAR(10) + cn.line\n FROM constraint_lines cn\n ORDER BY cn.constraint_name\n FOR XML PATH(''), TYPE\n ).value('.', 'NVARCHAR(MAX)'), 1, 2, '')\n ELSE ''\n END\n ), '')\n + CHAR(10) + ');' AS ddl\n FROM target_table tt\n `,\n [table.tableSchema, table.tableName],\n );\n\n return rows?.[0]?.ddl ?? null;\n }\n\n private toNumberOrNull(value: unknown) {\n if (value === null || value === undefined || value === \"\") {\n return null;\n }\n\n const parsed = Number(value);\n return Number.isFinite(parsed) ? parsed : null;\n }\n}\n"]}
|