@squadbase/vite-server 0.1.17-dev.a9ddcfa → 0.1.17-dev.e4768d1
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/cli/index.js +8941 -3700
- package/dist/connectors/airtable-oauth.js +87 -23
- package/dist/connectors/airtable.js +130 -23
- package/dist/connectors/amplitude.js +47 -23
- package/dist/connectors/anthropic.js +41 -17
- package/dist/connectors/asana.js +76 -25
- package/dist/connectors/attio.js +69 -28
- package/dist/connectors/aws-billing.js +47 -23
- package/dist/connectors/azure-sql.js +322 -25
- package/dist/connectors/backlog-api-key.js +79 -30
- package/dist/connectors/clickup.js +89 -25
- package/dist/connectors/cosmosdb.js +51 -27
- package/dist/connectors/customerio.js +47 -23
- package/dist/connectors/dbt.js +725 -40
- package/dist/connectors/freshdesk.js +121 -23
- package/dist/connectors/freshsales.js +47 -23
- package/dist/connectors/freshservice.js +47 -23
- package/dist/connectors/gamma.js +54 -30
- package/dist/connectors/gemini.js +41 -17
- package/dist/connectors/github.js +51 -27
- package/dist/connectors/gmail-oauth.js +42 -23
- package/dist/connectors/gmail.js +43 -19
- package/dist/connectors/google-ads.js +47 -23
- package/dist/connectors/google-analytics-oauth.js +191 -40
- package/dist/connectors/google-analytics.js +529 -111
- package/dist/connectors/google-audit-log.js +43 -19
- package/dist/connectors/google-calendar-oauth.js +100 -30
- package/dist/connectors/google-calendar.js +100 -26
- package/dist/connectors/google-docs.js +42 -23
- package/dist/connectors/google-drive.js +64 -23
- package/dist/connectors/google-search-console-oauth.js +165 -32
- package/dist/connectors/google-sheets.js +142 -199
- package/dist/connectors/google-slides.js +42 -23
- package/dist/connectors/grafana.js +84 -25
- package/dist/connectors/hackernews.d.ts +5 -0
- package/dist/connectors/hackernews.js +909 -0
- package/dist/connectors/hubspot-oauth.js +73 -22
- package/dist/connectors/hubspot.js +64 -24
- package/dist/connectors/influxdb.js +47 -23
- package/dist/connectors/intercom-oauth.js +104 -25
- package/dist/connectors/intercom.js +51 -27
- package/dist/connectors/jdbc.js +76 -25
- package/dist/connectors/jira-api-key.js +107 -26
- package/dist/connectors/kintone-api-token.js +105 -33
- package/dist/connectors/kintone.js +182 -26
- package/dist/connectors/linear.js +93 -27
- package/dist/connectors/linkedin-ads.js +80 -29
- package/dist/connectors/mailchimp-oauth.js +45 -21
- package/dist/connectors/mailchimp.js +45 -21
- package/dist/connectors/meta-ads-oauth.js +72 -29
- package/dist/connectors/meta-ads.js +74 -29
- package/dist/connectors/mixpanel.js +47 -23
- package/dist/connectors/monday.js +48 -24
- package/dist/connectors/mongodb.js +47 -23
- package/dist/connectors/notion-oauth.js +92 -24
- package/dist/connectors/notion.js +144 -26
- package/dist/connectors/openai.js +41 -17
- package/dist/connectors/oracle.js +316 -26
- package/dist/connectors/outlook-oauth.js +53 -34
- package/dist/connectors/powerbi-oauth.js +45 -26
- package/dist/connectors/salesforce.js +150 -24
- package/dist/connectors/semrush.js +45 -21
- package/dist/connectors/sentry.js +75 -25
- package/dist/connectors/shopify-oauth.js +75 -23
- package/dist/connectors/shopify.js +47 -23
- package/dist/connectors/sqlserver.js +322 -25
- package/dist/connectors/stripe-api-key.js +105 -30
- package/dist/connectors/stripe-oauth.js +102 -32
- package/dist/connectors/supabase.js +315 -21
- package/dist/connectors/tableau.js +54 -30
- package/dist/connectors/tiktok-ads.js +76 -31
- package/dist/connectors/wix-store.js +47 -23
- package/dist/connectors/x.d.ts +5 -0
- package/dist/connectors/x.js +951 -0
- package/dist/connectors/zendesk-oauth.js +87 -25
- package/dist/connectors/zendesk.js +51 -27
- package/dist/index.js +9005 -3709
- package/dist/main.js +9005 -3709
- package/dist/vite-plugin.js +8939 -3698
- package/package.json +12 -4
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
|
-
var __esm = (fn, res) => function __init() {
|
|
3
|
-
|
|
2
|
+
var __esm = (fn, res, err) => function __init() {
|
|
3
|
+
if (err) throw err[0];
|
|
4
|
+
try {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
+
} catch (e) {
|
|
7
|
+
throw err = [e], e;
|
|
8
|
+
}
|
|
4
9
|
};
|
|
5
10
|
|
|
6
11
|
// ../connectors/src/parameter-definition.ts
|
|
@@ -362,6 +367,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
362
367
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
363
368
|
*/
|
|
364
369
|
setup;
|
|
370
|
+
/**
|
|
371
|
+
* 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
|
|
372
|
+
* メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
|
|
373
|
+
* {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
|
|
374
|
+
* 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
|
|
375
|
+
* `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
|
|
376
|
+
* coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
|
|
377
|
+
*/
|
|
378
|
+
introspect;
|
|
365
379
|
/**
|
|
366
380
|
* Opt-out of the default "verify before save" behavior on connection
|
|
367
381
|
* creation. The backend invokes `checkConnection` synchronously while
|
|
@@ -376,6 +390,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
376
390
|
* the default verify-on-create behavior without opt-in.
|
|
377
391
|
*/
|
|
378
392
|
skipConnectionCheckOnCreate;
|
|
393
|
+
/**
|
|
394
|
+
* 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
|
|
395
|
+
* read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
|
|
396
|
+
* recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
|
|
397
|
+
* driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
|
|
398
|
+
* 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
|
|
399
|
+
*/
|
|
400
|
+
surveyProbes;
|
|
379
401
|
constructor(config) {
|
|
380
402
|
this.slug = config.slug;
|
|
381
403
|
this.authType = config.authType;
|
|
@@ -393,7 +415,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
393
415
|
this.query = config.query;
|
|
394
416
|
this.checkConnection = config.checkConnection;
|
|
395
417
|
this.setup = config.setup;
|
|
418
|
+
this.introspect = config.introspect;
|
|
396
419
|
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
420
|
+
this.surveyProbes = config.surveyProbes;
|
|
397
421
|
}
|
|
398
422
|
get connectorKey() {
|
|
399
423
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -401,7 +425,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
401
425
|
/**
|
|
402
426
|
* Create tools for connections that belong to this connector.
|
|
403
427
|
* Filters connections by connectorKey internally.
|
|
404
|
-
* Returns tools keyed as
|
|
428
|
+
* Returns tools keyed as `connector_${connectorKey}_${toolName}`.
|
|
405
429
|
*/
|
|
406
430
|
createTools(connections, config, opts) {
|
|
407
431
|
const myConnections = connections.filter(
|
|
@@ -411,7 +435,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
411
435
|
for (const t of Object.values(this.tools)) {
|
|
412
436
|
const tool = t.createTool(myConnections, config);
|
|
413
437
|
const originalToModelOutput = tool.toModelOutput;
|
|
414
|
-
result[
|
|
438
|
+
result[`connector_${this.connectorKey}_${t.name}`] = {
|
|
415
439
|
...tool,
|
|
416
440
|
toModelOutput: async (options) => {
|
|
417
441
|
if (!originalToModelOutput) {
|
|
@@ -431,25 +455,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
431
455
|
if (authType) return `${slug}-${authType}`;
|
|
432
456
|
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
433
457
|
// user-password
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
458
|
+
postgresql: "user-password",
|
|
459
|
+
mysql: "user-password",
|
|
460
|
+
clickhouse: "user-password",
|
|
461
|
+
kintone: "user-password",
|
|
438
462
|
"squadbase-db": "user-password",
|
|
439
463
|
// service-account
|
|
440
|
-
|
|
441
|
-
|
|
464
|
+
snowflake: "service-account",
|
|
465
|
+
bigquery: "service-account",
|
|
442
466
|
"google-analytics": "service-account",
|
|
443
467
|
"google-calendar": "service-account",
|
|
444
468
|
"aws-athena": "service-account",
|
|
445
|
-
|
|
469
|
+
redshift: "service-account",
|
|
446
470
|
// api-key
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
471
|
+
databricks: "api-key",
|
|
472
|
+
dbt: "api-key",
|
|
473
|
+
airtable: "api-key",
|
|
474
|
+
openai: "api-key",
|
|
475
|
+
gemini: "api-key",
|
|
476
|
+
anthropic: "api-key",
|
|
453
477
|
"wix-store": "api-key"
|
|
454
478
|
};
|
|
455
479
|
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|
|
@@ -536,11 +560,11 @@ var AUTH_TYPES = {
|
|
|
536
560
|
// ../connectors/src/connectors/shopify/setup.ts
|
|
537
561
|
var shopifyOnboarding = new ConnectorOnboarding({
|
|
538
562
|
dataOverviewInstructions: {
|
|
539
|
-
en: `1. Call
|
|
540
|
-
2. Call
|
|
563
|
+
en: `1. Call connector_shopify_request with GET /admin/api/2024-10/products.json?limit=5 to explore products structure
|
|
564
|
+
2. Call connector_shopify_request with GET /admin/api/2024-10/orders.json?limit=5&status=any to explore orders structure
|
|
541
565
|
3. Explore other endpoints (customers, inventory, collections) as needed`,
|
|
542
|
-
ja: `1.
|
|
543
|
-
2.
|
|
566
|
+
ja: `1. connector_shopify_request \u3067 GET /admin/api/2024-10/products.json?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u5546\u54C1\u306E\u69CB\u9020\u3092\u78BA\u8A8D
|
|
567
|
+
2. connector_shopify_request \u3067 GET /admin/api/2024-10/orders.json?limit=5&status=any \u3092\u547C\u3073\u51FA\u3057\u3001\u6CE8\u6587\u306E\u69CB\u9020\u3092\u78BA\u8A8D
|
|
544
568
|
3. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u4ED6\u306E\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08\u9867\u5BA2\u3001\u5728\u5EAB\u3001\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\uFF09\u3092\u63A2\u7D22`
|
|
545
569
|
}
|
|
546
570
|
});
|
|
@@ -792,7 +816,7 @@ var shopifyConnector = new ConnectorPlugin({
|
|
|
792
816
|
systemPrompt: {
|
|
793
817
|
en: `### Tools
|
|
794
818
|
|
|
795
|
-
- \`
|
|
819
|
+
- \`connector_shopify_request\`: The only way to call the Shopify Admin REST API. Use it to query products, orders, customers, inventory, collections, and more. Authentication (Custom App Client ID + Client Secret) is configured automatically \u2014 an access token is obtained on each request. Only provide the path starting with \`/admin/api/\`. Shopify uses cursor-based pagination via the \`page_info\` query parameter (obtained from the Link header in the response).
|
|
796
820
|
|
|
797
821
|
### Business Logic
|
|
798
822
|
|
|
@@ -864,7 +888,7 @@ export default async function handler(c: Context) {
|
|
|
864
888
|
- \`status\` \u2014 Filter by status (e.g., active, draft, archived for products; open, closed, cancelled, any for orders)`,
|
|
865
889
|
ja: `### \u30C4\u30FC\u30EB
|
|
866
890
|
|
|
867
|
-
- \`
|
|
891
|
+
- \`connector_shopify_request\`: Shopify Admin REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u5546\u54C1\u3001\u6CE8\u6587\u3001\u9867\u5BA2\u3001\u5728\u5EAB\u3001\u30B3\u30EC\u30AF\u30B7\u30E7\u30F3\u306A\u3069\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08\u30AB\u30B9\u30BF\u30E0\u30A2\u30D7\u30EA\u306E Client ID + Client Secret\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u3001\u30EA\u30AF\u30A8\u30B9\u30C8\u3054\u3068\u306B\u30A2\u30AF\u30BB\u30B9\u30C8\u30FC\u30AF\u30F3\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002\`/admin/api/\` \u304B\u3089\u59CB\u307E\u308B\u30D1\u30B9\u306E\u307F\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044\u3002Shopify\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E Link \u30D8\u30C3\u30C0\u30FC\u304B\u3089\u53D6\u5F97\u3059\u308B \`page_info\` \u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
|
|
868
892
|
|
|
869
893
|
### Business Logic
|
|
870
894
|
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
3
|
-
var __esm = (fn, res) => function __init() {
|
|
4
|
-
|
|
3
|
+
var __esm = (fn, res, err) => function __init() {
|
|
4
|
+
if (err) throw err[0];
|
|
5
|
+
try {
|
|
6
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
7
|
+
} catch (e) {
|
|
8
|
+
throw err = [e], e;
|
|
9
|
+
}
|
|
5
10
|
};
|
|
6
11
|
var __export = (target, all) => {
|
|
7
12
|
for (var name in all)
|
|
@@ -308,7 +313,7 @@ async function runMssqlQuery(parsed, sql, options = {}) {
|
|
|
308
313
|
try {
|
|
309
314
|
const result = await pool.request().query(sql);
|
|
310
315
|
const recordset = result.recordset ?? [];
|
|
311
|
-
return { rows: recordset };
|
|
316
|
+
return { rows: recordset, rowsAffected: result.rowsAffected ?? [] };
|
|
312
317
|
} finally {
|
|
313
318
|
await pool.close();
|
|
314
319
|
}
|
|
@@ -473,6 +478,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
473
478
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
474
479
|
*/
|
|
475
480
|
setup;
|
|
481
|
+
/**
|
|
482
|
+
* 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
|
|
483
|
+
* メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
|
|
484
|
+
* {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
|
|
485
|
+
* 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
|
|
486
|
+
* `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
|
|
487
|
+
* coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
|
|
488
|
+
*/
|
|
489
|
+
introspect;
|
|
476
490
|
/**
|
|
477
491
|
* Opt-out of the default "verify before save" behavior on connection
|
|
478
492
|
* creation. The backend invokes `checkConnection` synchronously while
|
|
@@ -487,6 +501,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
487
501
|
* the default verify-on-create behavior without opt-in.
|
|
488
502
|
*/
|
|
489
503
|
skipConnectionCheckOnCreate;
|
|
504
|
+
/**
|
|
505
|
+
* 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
|
|
506
|
+
* read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
|
|
507
|
+
* recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
|
|
508
|
+
* driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
|
|
509
|
+
* 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
|
|
510
|
+
*/
|
|
511
|
+
surveyProbes;
|
|
490
512
|
constructor(config) {
|
|
491
513
|
this.slug = config.slug;
|
|
492
514
|
this.authType = config.authType;
|
|
@@ -504,7 +526,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
504
526
|
this.query = config.query;
|
|
505
527
|
this.checkConnection = config.checkConnection;
|
|
506
528
|
this.setup = config.setup;
|
|
529
|
+
this.introspect = config.introspect;
|
|
507
530
|
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
531
|
+
this.surveyProbes = config.surveyProbes;
|
|
508
532
|
}
|
|
509
533
|
get connectorKey() {
|
|
510
534
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -512,7 +536,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
512
536
|
/**
|
|
513
537
|
* Create tools for connections that belong to this connector.
|
|
514
538
|
* Filters connections by connectorKey internally.
|
|
515
|
-
* Returns tools keyed as
|
|
539
|
+
* Returns tools keyed as `connector_${connectorKey}_${toolName}`.
|
|
516
540
|
*/
|
|
517
541
|
createTools(connections, config, opts) {
|
|
518
542
|
const myConnections = connections.filter(
|
|
@@ -522,7 +546,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
522
546
|
for (const t of Object.values(this.tools)) {
|
|
523
547
|
const tool = t.createTool(myConnections, config);
|
|
524
548
|
const originalToModelOutput = tool.toModelOutput;
|
|
525
|
-
result[
|
|
549
|
+
result[`connector_${this.connectorKey}_${t.name}`] = {
|
|
526
550
|
...tool,
|
|
527
551
|
toModelOutput: async (options) => {
|
|
528
552
|
if (!originalToModelOutput) {
|
|
@@ -542,25 +566,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
542
566
|
if (authType) return `${slug}-${authType}`;
|
|
543
567
|
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
544
568
|
// user-password
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
569
|
+
postgresql: "user-password",
|
|
570
|
+
mysql: "user-password",
|
|
571
|
+
clickhouse: "user-password",
|
|
572
|
+
kintone: "user-password",
|
|
549
573
|
"squadbase-db": "user-password",
|
|
550
574
|
// service-account
|
|
551
|
-
|
|
552
|
-
|
|
575
|
+
snowflake: "service-account",
|
|
576
|
+
bigquery: "service-account",
|
|
553
577
|
"google-analytics": "service-account",
|
|
554
578
|
"google-calendar": "service-account",
|
|
555
579
|
"aws-athena": "service-account",
|
|
556
|
-
|
|
580
|
+
redshift: "service-account",
|
|
557
581
|
// api-key
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
582
|
+
databricks: "api-key",
|
|
583
|
+
dbt: "api-key",
|
|
584
|
+
airtable: "api-key",
|
|
585
|
+
openai: "api-key",
|
|
586
|
+
gemini: "api-key",
|
|
587
|
+
anthropic: "api-key",
|
|
564
588
|
"wix-store": "api-key"
|
|
565
589
|
};
|
|
566
590
|
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|
|
@@ -569,6 +593,84 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
569
593
|
}
|
|
570
594
|
};
|
|
571
595
|
|
|
596
|
+
// ../connectors/src/survey-probe.ts
|
|
597
|
+
function rowsOf(output) {
|
|
598
|
+
if (!output || typeof output !== "object") return [];
|
|
599
|
+
const o = output;
|
|
600
|
+
if (o.success === false) return [];
|
|
601
|
+
return Array.isArray(o.rows) ? o.rows : [];
|
|
602
|
+
}
|
|
603
|
+
function pickString(row, candidates) {
|
|
604
|
+
for (const key of candidates) {
|
|
605
|
+
const v = row[key] ?? row[key.toUpperCase()] ?? row[key.toLowerCase()];
|
|
606
|
+
if (typeof v === "string" && v.length > 0) return v;
|
|
607
|
+
}
|
|
608
|
+
return void 0;
|
|
609
|
+
}
|
|
610
|
+
var TABLE_NAME_FIELDS = [
|
|
611
|
+
"table_name",
|
|
612
|
+
"name",
|
|
613
|
+
"tableName",
|
|
614
|
+
"tab_name",
|
|
615
|
+
"Table",
|
|
616
|
+
"table"
|
|
617
|
+
];
|
|
618
|
+
function makeQuoteIdent(opts) {
|
|
619
|
+
if (opts.bracket) {
|
|
620
|
+
return (name) => `[${name.replaceAll("]", "]]")}]`;
|
|
621
|
+
}
|
|
622
|
+
const q = opts.quote ?? '"';
|
|
623
|
+
return (name) => `${q}${name.replaceAll(q, q + q)}${q}`;
|
|
624
|
+
}
|
|
625
|
+
function sampleSql(ref, limit) {
|
|
626
|
+
return `SELECT * FROM (SELECT * FROM ${ref}) AS _sq LIMIT ${limit}`;
|
|
627
|
+
}
|
|
628
|
+
function distinctTables(prior, max) {
|
|
629
|
+
const names = [];
|
|
630
|
+
const seen = /* @__PURE__ */ new Set();
|
|
631
|
+
for (const row of rowsOf(prior[0]?.output)) {
|
|
632
|
+
const name = pickString(row, TABLE_NAME_FIELDS);
|
|
633
|
+
if (!name || seen.has(name)) continue;
|
|
634
|
+
seen.add(name);
|
|
635
|
+
names.push(name);
|
|
636
|
+
if (names.length >= max) break;
|
|
637
|
+
}
|
|
638
|
+
return names;
|
|
639
|
+
}
|
|
640
|
+
function makeStandardSqlSurveyProbes(opts) {
|
|
641
|
+
const queryTool = opts.queryTool ?? "executeQuery";
|
|
642
|
+
const sampleLimit = opts.sampleLimit ?? 5;
|
|
643
|
+
const maxSampleTables = opts.maxSampleTables ?? 4;
|
|
644
|
+
const quoteIdent = makeQuoteIdent(opts);
|
|
645
|
+
const whereSchema = opts.schemaLiteral ? ` WHERE table_schema = '${opts.schemaLiteral.replaceAll("'", "''")}'` : opts.schemaExpr ? ` WHERE table_schema = ${opts.schemaExpr}` : "";
|
|
646
|
+
return (_connectionId, prior) => {
|
|
647
|
+
if (prior.length === 0) {
|
|
648
|
+
return [
|
|
649
|
+
{
|
|
650
|
+
tool: queryTool,
|
|
651
|
+
input: {
|
|
652
|
+
toolUseIntent: "Survey table/column metadata",
|
|
653
|
+
sql: `SELECT table_name, column_name, data_type FROM information_schema.columns${whereSchema} ORDER BY table_name, ordinal_position LIMIT 1000`
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
];
|
|
657
|
+
}
|
|
658
|
+
if (prior.length === 1) {
|
|
659
|
+
return distinctTables(prior, maxSampleTables).map((name) => {
|
|
660
|
+
const ref = opts.schemaLiteral ? `${quoteIdent(opts.schemaLiteral)}.${quoteIdent(name)}` : quoteIdent(name);
|
|
661
|
+
return {
|
|
662
|
+
tool: queryTool,
|
|
663
|
+
input: {
|
|
664
|
+
toolUseIntent: `Sample ${name}`,
|
|
665
|
+
sql: sampleSql(ref, sampleLimit)
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
});
|
|
669
|
+
}
|
|
670
|
+
return [];
|
|
671
|
+
};
|
|
672
|
+
}
|
|
673
|
+
|
|
572
674
|
// ../connectors/src/setup-flow.ts
|
|
573
675
|
async function runSetupFlow(flow, params, ctx, config) {
|
|
574
676
|
const runtime = {
|
|
@@ -639,6 +741,55 @@ async function resolveSetupSelection(params) {
|
|
|
639
741
|
return resolved.slice(0, limit);
|
|
640
742
|
}
|
|
641
743
|
|
|
744
|
+
// ../connectors/src/introspect-concurrency.ts
|
|
745
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
746
|
+
const results = new Array(items.length);
|
|
747
|
+
let next = 0;
|
|
748
|
+
const workers = Array.from(
|
|
749
|
+
{ length: Math.min(Math.max(limit, 1), items.length) },
|
|
750
|
+
async () => {
|
|
751
|
+
for (; ; ) {
|
|
752
|
+
const i = next++;
|
|
753
|
+
if (i >= items.length) return;
|
|
754
|
+
results[i] = await fn(items[i]);
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
);
|
|
758
|
+
await Promise.all(workers);
|
|
759
|
+
return results;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// ../connectors/src/introspect-profile.ts
|
|
763
|
+
var DEFAULT_MAX_TABLES = 200;
|
|
764
|
+
var DEFAULT_CONCURRENCY = 5;
|
|
765
|
+
var quoteBracket = (schema, name) => `[${schema.replace(/\]/g, "]]")}].[${name.replace(/\]/g, "]]")}]`;
|
|
766
|
+
async function withRowCounts(ctx, schemaPromise, quoteRef, opts = {}) {
|
|
767
|
+
const schema = await schemaPromise;
|
|
768
|
+
if (!ctx.profile || !ctx.query) return schema;
|
|
769
|
+
return attachRowCounts(ctx.query, schema, quoteRef, opts);
|
|
770
|
+
}
|
|
771
|
+
async function attachRowCounts(run, schema, quoteRef, opts = {}) {
|
|
772
|
+
const targets = schema.tables.slice(0, opts.maxTables ?? DEFAULT_MAX_TABLES);
|
|
773
|
+
await mapWithConcurrency(
|
|
774
|
+
targets,
|
|
775
|
+
opts.concurrency ?? DEFAULT_CONCURRENCY,
|
|
776
|
+
async (table) => {
|
|
777
|
+
try {
|
|
778
|
+
const { rows } = await run(
|
|
779
|
+
`SELECT COUNT(*) AS row_count FROM ${quoteRef(table.schema, table.name)}`
|
|
780
|
+
);
|
|
781
|
+
const first = rows[0] ? Object.values(rows[0])[0] : void 0;
|
|
782
|
+
const rowCount = Number(first);
|
|
783
|
+
if (Number.isFinite(rowCount)) {
|
|
784
|
+
table.profile = { ...table.profile ?? {}, rowCount };
|
|
785
|
+
}
|
|
786
|
+
} catch {
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
);
|
|
790
|
+
return schema;
|
|
791
|
+
}
|
|
792
|
+
|
|
642
793
|
// ../connectors/src/auth-types.ts
|
|
643
794
|
var AUTH_TYPES = {
|
|
644
795
|
OAUTH: "oauth",
|
|
@@ -649,6 +800,69 @@ var AUTH_TYPES = {
|
|
|
649
800
|
USER_PASSWORD: "user-password"
|
|
650
801
|
};
|
|
651
802
|
|
|
803
|
+
// ../connectors/src/introspect-information-schema.ts
|
|
804
|
+
function pickCI(row, key) {
|
|
805
|
+
if (key in row) return String(row[key] ?? "");
|
|
806
|
+
const lower = key.toLowerCase();
|
|
807
|
+
for (const k of Object.keys(row)) {
|
|
808
|
+
if (k.toLowerCase() === lower) return String(row[k] ?? "");
|
|
809
|
+
}
|
|
810
|
+
return "";
|
|
811
|
+
}
|
|
812
|
+
function assembleIntrospectedSchema(input) {
|
|
813
|
+
const { colRows, pkRows = [], fkRows = [] } = input;
|
|
814
|
+
const pkSet = /* @__PURE__ */ new Set();
|
|
815
|
+
for (const r of pkRows) {
|
|
816
|
+
pkSet.add(
|
|
817
|
+
`${pickCI(r, "table_schema")}.${pickCI(r, "table_name")}.${pickCI(r, "column_name")}`
|
|
818
|
+
);
|
|
819
|
+
}
|
|
820
|
+
const fkMap = /* @__PURE__ */ new Map();
|
|
821
|
+
for (const r of fkRows) {
|
|
822
|
+
fkMap.set(
|
|
823
|
+
`${pickCI(r, "table_schema")}.${pickCI(r, "table_name")}.${pickCI(r, "column_name")}`,
|
|
824
|
+
{
|
|
825
|
+
schema: pickCI(r, "foreign_table_schema"),
|
|
826
|
+
table: pickCI(r, "foreign_table_name"),
|
|
827
|
+
column: pickCI(r, "foreign_column_name")
|
|
828
|
+
}
|
|
829
|
+
);
|
|
830
|
+
}
|
|
831
|
+
const tableMap = /* @__PURE__ */ new Map();
|
|
832
|
+
for (const r of colRows) {
|
|
833
|
+
const schema = pickCI(r, "table_schema");
|
|
834
|
+
const name = pickCI(r, "table_name");
|
|
835
|
+
const key = `${schema}.${name}`;
|
|
836
|
+
let table = tableMap.get(key);
|
|
837
|
+
if (!table) {
|
|
838
|
+
table = {
|
|
839
|
+
schema,
|
|
840
|
+
name,
|
|
841
|
+
type: pickCI(r, "table_type").toUpperCase() === "VIEW" ? "view" : "table",
|
|
842
|
+
columns: []
|
|
843
|
+
};
|
|
844
|
+
tableMap.set(key, table);
|
|
845
|
+
}
|
|
846
|
+
const colKey = `${schema}.${name}.${pickCI(r, "column_name")}`;
|
|
847
|
+
const column = {
|
|
848
|
+
name: pickCI(r, "column_name"),
|
|
849
|
+
dataType: pickCI(r, "data_type"),
|
|
850
|
+
nullable: pickCI(r, "is_nullable").toUpperCase() === "YES"
|
|
851
|
+
};
|
|
852
|
+
if (pkSet.has(colKey)) column.isPrimaryKey = true;
|
|
853
|
+
const fk = fkMap.get(colKey);
|
|
854
|
+
if (fk) column.foreignKey = fk;
|
|
855
|
+
table.columns.push(column);
|
|
856
|
+
}
|
|
857
|
+
return { tables: [...tableMap.values()] };
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// ../connectors/src/lib/sql-dml.ts
|
|
861
|
+
function isDmlStatement(sql) {
|
|
862
|
+
const stripped = sql.replace(/^(\s*(--[^\n]*\n|\/\*[\s\S]*?\*\/))+/, "").trimStart();
|
|
863
|
+
return /^(insert|update|delete|merge)\b/i.test(stripped);
|
|
864
|
+
}
|
|
865
|
+
|
|
652
866
|
// ../connectors/src/lib/unwrap-sample-limit.ts
|
|
653
867
|
var STRICT_WRAPPER_RE = /^\s*SELECT\s+\*\s+FROM\s+\(([\s\S]+)\)\s+AS\s+\w+\s+LIMIT\s+(\d+)\s*;?\s*$/i;
|
|
654
868
|
var TRAILING_LIMIT_RE = /\s+LIMIT\s+(\d+)\s*;?\s*$/i;
|
|
@@ -671,11 +885,11 @@ init_mssql_runner();
|
|
|
671
885
|
// ../connectors/src/connectors/sqlserver/setup.ts
|
|
672
886
|
var sqlserverOnboarding = new ConnectorOnboarding({
|
|
673
887
|
dataOverviewInstructions: {
|
|
674
|
-
en: `1. Use
|
|
888
|
+
en: `1. Use connector_sqlserver_executeQuery to discover the database flavor and version: \`SELECT @@VERSION\`
|
|
675
889
|
2. List user tables: \`SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')\`
|
|
676
890
|
3. For key tables, fetch column info: \`SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'xxx'\`
|
|
677
891
|
4. Sample up to 3 tables. SQL Server uses \`TOP\` rather than \`LIMIT\`: \`SELECT TOP 5 * FROM <schema>.<table_name>\``,
|
|
678
|
-
ja: `1.
|
|
892
|
+
ja: `1. connector_sqlserver_executeQuery \u3067\u30D0\u30FC\u30B8\u30E7\u30F3\u60C5\u5831\u3092\u53D6\u5F97: \`SELECT @@VERSION\`
|
|
679
893
|
2. \u30E6\u30FC\u30B6\u30FC\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u3092\u53D6\u5F97: \`SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')\`
|
|
680
894
|
3. \u4E3B\u8981\u30C6\u30FC\u30D6\u30EB\u306E\u30AB\u30E9\u30E0\u60C5\u5831\u3092\u53D6\u5F97: \`SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = 'dbo' AND TABLE_NAME = 'xxx'\`
|
|
681
895
|
4. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u6700\u59273\u30C6\u30FC\u30D6\u30EB\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u3002SQL Server \u3067\u306F \`LIMIT\` \u3067\u306F\u306A\u304F \`TOP\` \u3092\u4F7F\u7528: \`SELECT TOP 5 * FROM <schema>.<table_name>\``
|
|
@@ -772,6 +986,28 @@ function buildFlow(options) {
|
|
|
772
986
|
fetchAll: () => fetchTableNames(rt.params, schema),
|
|
773
987
|
limit: SQLSERVER_SETUP_MAX_TABLES
|
|
774
988
|
});
|
|
989
|
+
let rowCounts = /* @__PURE__ */ new Map();
|
|
990
|
+
try {
|
|
991
|
+
const countRows = await runSqlServerSetupQuery(
|
|
992
|
+
rt.params,
|
|
993
|
+
`SELECT t.TABLE_NAME, SUM(p.rows) AS row_count
|
|
994
|
+
FROM INFORMATION_SCHEMA.TABLES t
|
|
995
|
+
JOIN sys.partitions p
|
|
996
|
+
ON OBJECT_ID(t.TABLE_SCHEMA + '.' + t.TABLE_NAME) = p.object_id
|
|
997
|
+
AND p.index_id IN (0, 1)
|
|
998
|
+
WHERE t.TABLE_SCHEMA = ${quoteLiteral(schema)}
|
|
999
|
+
AND t.TABLE_TYPE IN ('BASE TABLE', 'VIEW')
|
|
1000
|
+
GROUP BY t.TABLE_NAME`,
|
|
1001
|
+
forceEncrypt
|
|
1002
|
+
);
|
|
1003
|
+
rowCounts = new Map(
|
|
1004
|
+
countRows.map((r) => [
|
|
1005
|
+
String(r["TABLE_NAME"] ?? ""),
|
|
1006
|
+
Number(r["row_count"] ?? 0)
|
|
1007
|
+
])
|
|
1008
|
+
);
|
|
1009
|
+
} catch {
|
|
1010
|
+
}
|
|
775
1011
|
const sections = [
|
|
776
1012
|
`## ${connectorName}`,
|
|
777
1013
|
"",
|
|
@@ -788,7 +1024,9 @@ function buildFlow(options) {
|
|
|
788
1024
|
ORDER BY ORDINAL_POSITION`,
|
|
789
1025
|
forceEncrypt
|
|
790
1026
|
);
|
|
791
|
-
|
|
1027
|
+
const rowCount = rowCounts.get(table);
|
|
1028
|
+
const heading = typeof rowCount === "number" ? `#### Table: ${table} (~${rowCount.toLocaleString()} rows)` : `#### Table: ${table}`;
|
|
1029
|
+
sections.push(heading, "");
|
|
792
1030
|
sections.push("| Column | Type | Nullable | Default |");
|
|
793
1031
|
sections.push("|--------|------|----------|---------|");
|
|
794
1032
|
for (const c of cols) {
|
|
@@ -814,6 +1052,52 @@ var sqlserverSetupFlow = createSqlServerSetupFlow({
|
|
|
814
1052
|
forceEncrypt: false
|
|
815
1053
|
});
|
|
816
1054
|
|
|
1055
|
+
// ../connectors/src/connectors/sqlserver/introspect.ts
|
|
1056
|
+
async function introspectMssql(run) {
|
|
1057
|
+
const [{ rows: colRows }, { rows: pkRows }, { rows: fkRows }] = await Promise.all([
|
|
1058
|
+
// 1) 全カラム(型 / nullable)+ テーブル種別(BASE TABLE / VIEW)
|
|
1059
|
+
run(
|
|
1060
|
+
`SELECT c.TABLE_SCHEMA AS table_schema, c.TABLE_NAME AS table_name,
|
|
1061
|
+
c.COLUMN_NAME AS column_name, c.DATA_TYPE AS data_type,
|
|
1062
|
+
c.IS_NULLABLE AS is_nullable, c.ORDINAL_POSITION AS ordinal_position,
|
|
1063
|
+
t.TABLE_TYPE AS table_type
|
|
1064
|
+
FROM INFORMATION_SCHEMA.COLUMNS c
|
|
1065
|
+
JOIN INFORMATION_SCHEMA.TABLES t
|
|
1066
|
+
ON t.TABLE_SCHEMA = c.TABLE_SCHEMA AND t.TABLE_NAME = c.TABLE_NAME
|
|
1067
|
+
WHERE c.TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')
|
|
1068
|
+
ORDER BY c.TABLE_SCHEMA, c.TABLE_NAME, c.ORDINAL_POSITION`
|
|
1069
|
+
),
|
|
1070
|
+
// 2) 主キー
|
|
1071
|
+
run(
|
|
1072
|
+
`SELECT tc.TABLE_SCHEMA AS table_schema, tc.TABLE_NAME AS table_name,
|
|
1073
|
+
kcu.COLUMN_NAME AS column_name
|
|
1074
|
+
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
|
|
1075
|
+
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
|
|
1076
|
+
ON kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
|
|
1077
|
+
AND kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
|
|
1078
|
+
AND kcu.TABLE_NAME = tc.TABLE_NAME
|
|
1079
|
+
WHERE tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
|
|
1080
|
+
AND tc.TABLE_SCHEMA NOT IN ('sys', 'INFORMATION_SCHEMA')`
|
|
1081
|
+
),
|
|
1082
|
+
// 3) 外部キー(参照元列 → 参照先列)。sys カタログで複合 FK も 1:1 に解決する。
|
|
1083
|
+
run(
|
|
1084
|
+
`SELECT sch.name AS table_schema, tab.name AS table_name, col.name AS column_name,
|
|
1085
|
+
rsch.name AS foreign_table_schema, rtab.name AS foreign_table_name,
|
|
1086
|
+
rcol.name AS foreign_column_name
|
|
1087
|
+
FROM sys.foreign_key_columns fkc
|
|
1088
|
+
JOIN sys.tables tab ON tab.object_id = fkc.parent_object_id
|
|
1089
|
+
JOIN sys.schemas sch ON sch.schema_id = tab.schema_id
|
|
1090
|
+
JOIN sys.columns col ON col.object_id = fkc.parent_object_id
|
|
1091
|
+
AND col.column_id = fkc.parent_column_id
|
|
1092
|
+
JOIN sys.tables rtab ON rtab.object_id = fkc.referenced_object_id
|
|
1093
|
+
JOIN sys.schemas rsch ON rsch.schema_id = rtab.schema_id
|
|
1094
|
+
JOIN sys.columns rcol ON rcol.object_id = fkc.referenced_object_id
|
|
1095
|
+
AND rcol.column_id = fkc.referenced_column_id`
|
|
1096
|
+
)
|
|
1097
|
+
]);
|
|
1098
|
+
return assembleIntrospectedSchema({ colRows, pkRows, fkRows });
|
|
1099
|
+
}
|
|
1100
|
+
|
|
817
1101
|
// ../connectors/src/connectors/sqlserver/tools/execute-query.ts
|
|
818
1102
|
import { z } from "zod";
|
|
819
1103
|
init_mssql_runner();
|
|
@@ -833,6 +1117,9 @@ var outputSchema = z.discriminatedUnion("success", [
|
|
|
833
1117
|
z.object({
|
|
834
1118
|
success: z.literal(true),
|
|
835
1119
|
rowCount: z.number(),
|
|
1120
|
+
rowsAffected: z.number().optional().describe(
|
|
1121
|
+
"Affected rows for INSERT/UPDATE/DELETE; undefined for SELECT"
|
|
1122
|
+
),
|
|
836
1123
|
truncated: z.boolean(),
|
|
837
1124
|
rows: z.array(z.record(z.string(), z.unknown()))
|
|
838
1125
|
}),
|
|
@@ -846,7 +1133,8 @@ var executeQueryTool = new ConnectorTool({
|
|
|
846
1133
|
description: `Execute a T-SQL query against Microsoft SQL Server. Returns up to ${MAX_ROWS} rows.
|
|
847
1134
|
Use for: schema exploration via \`INFORMATION_SCHEMA\`, data sampling, and analytical queries.
|
|
848
1135
|
SQL Server uses \`TOP n\` instead of \`LIMIT n\`. Identifiers can be wrapped in square brackets (\`[schema].[table]\`).
|
|
849
|
-
Avoid loading large amounts of data; always include \`TOP\` in queries
|
|
1136
|
+
Avoid loading large amounts of data; always include \`TOP\` in queries.
|
|
1137
|
+
For INSERT/UPDATE/DELETE, \`rowCount\` is 0 and \`rows\` is empty (rowCount counts returned rows, not affected rows) \u2014 this is normal, not a failure; check \`rowsAffected\` for the number of affected rows.`,
|
|
850
1138
|
inputSchema,
|
|
851
1139
|
outputSchema,
|
|
852
1140
|
async execute({ connectionId, sql }, connections) {
|
|
@@ -873,13 +1161,16 @@ Avoid loading large amounts of data; always include \`TOP\` in queries.`,
|
|
|
873
1161
|
};
|
|
874
1162
|
}
|
|
875
1163
|
try {
|
|
876
|
-
const { rows } = await runMssqlQuery(parsed, sql, {
|
|
1164
|
+
const { rows, rowsAffected } = await runMssqlQuery(parsed, sql, {
|
|
877
1165
|
tunnelParams: connectionParamsToRecord(connection2)
|
|
878
1166
|
});
|
|
879
1167
|
const truncated = rows.length > MAX_ROWS;
|
|
880
1168
|
return {
|
|
881
1169
|
success: true,
|
|
882
1170
|
rowCount: Math.min(rows.length, MAX_ROWS),
|
|
1171
|
+
// tedious counts SELECT result rows in rowsAffected too, so only
|
|
1172
|
+
// report it for DML. Multi-statement batches are summed.
|
|
1173
|
+
rowsAffected: isDmlStatement(sql) ? rowsAffected.reduce((sum, n) => sum + n, 0) : void 0,
|
|
883
1174
|
truncated,
|
|
884
1175
|
rows: rows.slice(0, MAX_ROWS)
|
|
885
1176
|
};
|
|
@@ -907,7 +1198,7 @@ var sqlserverConnector = new ConnectorPlugin({
|
|
|
907
1198
|
systemPrompt: {
|
|
908
1199
|
en: `### Tools
|
|
909
1200
|
|
|
910
|
-
- \`
|
|
1201
|
+
- \`connector_sqlserver_executeQuery\`: Executes a T-SQL query against Microsoft SQL Server and returns rows. Use this for schema exploration via \`INFORMATION_SCHEMA\` and for sampling data. See the SQL Reference below for SQL Server-specific syntax.
|
|
911
1202
|
|
|
912
1203
|
### Business Logic
|
|
913
1204
|
|
|
@@ -924,7 +1215,7 @@ The business logic type for this connector is "sql".
|
|
|
924
1215
|
- Row-limit compatibility: the platform's server-logic schema inference may wrap your query as \`SELECT * FROM (<inner>) AS _sq LIMIT N\`. T-SQL does not understand \`LIMIT\`, so the connector detects this exact wrapper at \`query()\` time, executes \`<inner>\` directly, and slices the first N rows in JS. You do not need to handle this \u2014 but do not author your own \`LIMIT\` clauses; use \`TOP\` / \`OFFSET ... FETCH NEXT\` in queries you write.`,
|
|
925
1216
|
ja: `### \u30C4\u30FC\u30EB
|
|
926
1217
|
|
|
927
|
-
- \`
|
|
1218
|
+
- \`connector_sqlserver_executeQuery\`: Microsoft SQL Server \u306B\u5BFE\u3057\u3066 T-SQL \u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u3057\u3001\u884C\u30C7\u30FC\u30BF\u3092\u8FD4\u3057\u307E\u3059\u3002\`INFORMATION_SCHEMA\` \u3092\u4F7F\u3063\u305F\u30B9\u30AD\u30FC\u30DE\u63A2\u7D22\u3084\u30C7\u30FC\u30BF\u306E\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u306B\u4F7F\u3044\u307E\u3059\u3002SQL Server \u56FA\u6709\u306E\u69CB\u6587\u306F\u4E0B\u90E8\u306E\u300CSQL \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
|
928
1219
|
|
|
929
1220
|
### Business Logic
|
|
930
1221
|
|
|
@@ -941,6 +1232,12 @@ The business logic type for this connector is "sql".
|
|
|
941
1232
|
- \u884C\u6570\u5236\u9650\u306E\u4E92\u63DB\u6027: \u30D7\u30E9\u30C3\u30C8\u30D5\u30A9\u30FC\u30E0\u306E server-logic \u30B9\u30AD\u30FC\u30DE\u63A8\u8AD6\u306F\u3001\u30AF\u30A8\u30EA\u3092 \`SELECT * FROM (<inner>) AS _sq LIMIT N\` \u306E\u5F62\u3067\u30E9\u30C3\u30D7\u3057\u3066\u304F\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002T-SQL \u306B\u306F \`LIMIT\` \u304C\u7121\u3044\u305F\u3081\u3001\u30B3\u30CD\u30AF\u30BF\u306F \`query()\` \u5185\u3067\u3053\u306E\u30E9\u30C3\u30D1\u3092\u691C\u51FA\u3057\u3001\`<inner>\` \u3092\u305D\u306E\u307E\u307E\u5B9F\u884C\u3057\u3066 JS \u5074\u3067\u5148\u982D N \u884C\u306B\u5207\u308A\u8A70\u3081\u307E\u3059\u3002\u5229\u7528\u8005\u5074\u3067\u5BFE\u51E6\u3059\u308B\u5FC5\u8981\u306F\u3042\u308A\u307E\u305B\u3093\u304C\u3001\u81EA\u5206\u3067\u66F8\u304F SQL \u3067\u306F \`LIMIT\` \u3092\u4F7F\u308F\u305A \`TOP\` / \`OFFSET ... FETCH NEXT\` \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002`
|
|
942
1233
|
},
|
|
943
1234
|
tools,
|
|
1235
|
+
// 決定論的な立ち上げ survey(ルールベース prewarm)。SQL Server はユーザーオブジェクトが既定 `dbo`、識別子は `[ ]`。
|
|
1236
|
+
surveyProbes: makeStandardSqlSurveyProbes({
|
|
1237
|
+
schemaLiteral: "dbo",
|
|
1238
|
+
bracket: true
|
|
1239
|
+
}),
|
|
1240
|
+
introspect: (ctx) => withRowCounts(ctx, introspectMssql(ctx.query), quoteBracket),
|
|
944
1241
|
setup: (params, ctx, config) => runSetupFlow(sqlserverSetupFlow, params, ctx, config),
|
|
945
1242
|
async checkConnection(params, _config) {
|
|
946
1243
|
return checkMssqlConnection(
|