@squadbase/vite-server 0.1.9-dev.08f5c5f → 0.1.9-dev.3841401

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.
@@ -20254,6 +20254,230 @@ var ParameterDefinition = class {
20254
20254
  }
20255
20255
  };
20256
20256
 
20257
+ // ../connectors/src/connectors/sqlserver/utils.ts
20258
+ var SQLSERVER_PREFIX_RE = /^(?:jdbc:)?sqlserver:\/\//i;
20259
+ var TRUE_VALUES = /* @__PURE__ */ new Set(["true", "1", "yes"]);
20260
+ var FALSE_VALUES = /* @__PURE__ */ new Set(["false", "0", "no"]);
20261
+ function parseBoolean(value) {
20262
+ if (value == null) return void 0;
20263
+ const lower = value.toLowerCase();
20264
+ if (TRUE_VALUES.has(lower)) return true;
20265
+ if (FALSE_VALUES.has(lower)) return false;
20266
+ return void 0;
20267
+ }
20268
+ function parseSqlServerJdbcUrl(jdbcUrl, options = {}) {
20269
+ const trimmed = jdbcUrl.trim();
20270
+ if (!SQLSERVER_PREFIX_RE.test(trimmed)) {
20271
+ throw new Error(
20272
+ `Unsupported SQL Server URL "${redactSqlServerUrl(trimmed)}". Expected prefix: jdbc:sqlserver:// or sqlserver://.`
20273
+ );
20274
+ }
20275
+ const withoutPrefix = trimmed.replace(SQLSERVER_PREFIX_RE, "");
20276
+ const [hostAndPath, ...propertySegments] = withoutPrefix.split(";");
20277
+ const props = {};
20278
+ for (const segment of propertySegments) {
20279
+ if (!segment) continue;
20280
+ const eqIdx = segment.indexOf("=");
20281
+ if (eqIdx === -1) continue;
20282
+ const key = segment.slice(0, eqIdx).trim().toLowerCase();
20283
+ const value = segment.slice(eqIdx + 1).trim();
20284
+ if (key) props[key] = value;
20285
+ }
20286
+ const url = new URL(`mssql://${hostAndPath}`);
20287
+ for (const [key, value] of url.searchParams.entries()) {
20288
+ if (!(key.toLowerCase() in props)) {
20289
+ props[key.toLowerCase()] = value;
20290
+ }
20291
+ }
20292
+ const server = url.hostname;
20293
+ const port = url.port ? Number(url.port) : 1433;
20294
+ const pathname = url.pathname.replace(/^\//, "");
20295
+ const database = pathname || props["database"] || props["databasename"];
20296
+ const user = props["user"] || props["username"] || props["userid"] || options.username;
20297
+ const password = props["password"] || options.password;
20298
+ return {
20299
+ server,
20300
+ port,
20301
+ database,
20302
+ user,
20303
+ password,
20304
+ options: props
20305
+ };
20306
+ }
20307
+ function toMssqlConfig(parsed, defaults = {}) {
20308
+ const encrypt = parseBoolean(parsed.options["encrypt"]) ?? defaults.encrypt ?? false;
20309
+ const trustServerCertificate = parseBoolean(parsed.options["trustservercertificate"]) ?? !encrypt;
20310
+ return {
20311
+ server: parsed.server,
20312
+ port: parsed.port,
20313
+ database: parsed.database,
20314
+ user: parsed.user,
20315
+ password: parsed.password,
20316
+ connectionTimeout: 1e4,
20317
+ requestTimeout: 6e4,
20318
+ options: {
20319
+ encrypt,
20320
+ trustServerCertificate
20321
+ }
20322
+ };
20323
+ }
20324
+ function redactSqlServerUrl(jdbcUrl) {
20325
+ return jdbcUrl.replace(/(:\/\/)([^@/;]+)@/, "$1***@").replace(/(password\s*=\s*)([^;]+)/gi, "$1***");
20326
+ }
20327
+
20328
+ // ../connectors/src/lib/mssql-runner.ts
20329
+ async function importMssql() {
20330
+ const mod = await import("mssql");
20331
+ return mod.default ?? mod;
20332
+ }
20333
+ async function runMssqlQuery(parsed, sql, options = {}) {
20334
+ const sqlMod = await importMssql();
20335
+ const config = toMssqlConfig(parsed, {
20336
+ encrypt: options.forceEncrypt
20337
+ });
20338
+ const pool = new sqlMod.ConnectionPool(config);
20339
+ await pool.connect();
20340
+ try {
20341
+ const result = await pool.request().query(sql);
20342
+ const recordset = result.recordset ?? [];
20343
+ return { rows: recordset };
20344
+ } finally {
20345
+ await pool.close();
20346
+ }
20347
+ }
20348
+ async function checkMssqlConnection(url, credentials, options = {}) {
20349
+ let parsed;
20350
+ try {
20351
+ parsed = parseSqlServerJdbcUrl(url, credentials);
20352
+ } catch (err) {
20353
+ return {
20354
+ success: false,
20355
+ error: err instanceof Error ? err.message : String(err)
20356
+ };
20357
+ }
20358
+ try {
20359
+ await runMssqlQuery(parsed, "SELECT 1 AS one", options);
20360
+ return { success: true };
20361
+ } catch (err) {
20362
+ let msg = err instanceof Error ? err.message : String(err);
20363
+ msg = msg.replaceAll(url, redactSqlServerUrl(url));
20364
+ return { success: false, error: msg };
20365
+ }
20366
+ }
20367
+
20368
+ // ../connectors/src/connectors/oracle/utils.ts
20369
+ var JDBC_THIN_PREFIX_RE = /^jdbc:oracle:thin:/i;
20370
+ var JDBC_OCI_PREFIX_RE = /^jdbc:oracle:oci/i;
20371
+ var URL_PREFIX_RE = /^oracle:\/\//i;
20372
+ function parseOracleJdbcUrl(jdbcUrl, options = {}) {
20373
+ const trimmed = jdbcUrl.trim();
20374
+ if (JDBC_OCI_PREFIX_RE.test(trimmed)) {
20375
+ throw new Error(
20376
+ "Oracle OCI driver URLs are not supported. Use the thin driver form: jdbc:oracle:thin:@host:port/service"
20377
+ );
20378
+ }
20379
+ if (URL_PREFIX_RE.test(trimmed)) {
20380
+ const url = new URL(trimmed);
20381
+ const path2 = url.pathname.replace(/^\//, "");
20382
+ if (!url.hostname || !path2) {
20383
+ throw new Error(
20384
+ `Invalid Oracle URL "${redactOracleUrl(trimmed)}". Expected oracle://[user:password@]host:port/service`
20385
+ );
20386
+ }
20387
+ const port = url.port || "1521";
20388
+ return {
20389
+ connectString: `${url.hostname}:${port}/${path2}`,
20390
+ user: url.username ? decodeURIComponent(url.username) : options.username,
20391
+ password: url.password ? decodeURIComponent(url.password) : options.password
20392
+ };
20393
+ }
20394
+ if (!JDBC_THIN_PREFIX_RE.test(trimmed)) {
20395
+ throw new Error(
20396
+ `Unsupported Oracle URL "${redactOracleUrl(trimmed)}". Expected prefix: jdbc:oracle:thin:@ or oracle://`
20397
+ );
20398
+ }
20399
+ const afterPrefix = trimmed.replace(JDBC_THIN_PREFIX_RE, "");
20400
+ const atIdx = afterPrefix.indexOf("@");
20401
+ if (atIdx === -1) {
20402
+ throw new Error(
20403
+ `Invalid Oracle JDBC URL "${redactOracleUrl(trimmed)}". Expected '@' separator before host.`
20404
+ );
20405
+ }
20406
+ const credentialsPart = afterPrefix.slice(0, atIdx);
20407
+ const target = afterPrefix.slice(atIdx + 1).replace(/^\/\//, "");
20408
+ let user = options.username;
20409
+ let password = options.password;
20410
+ if (credentialsPart) {
20411
+ const slashIdx = credentialsPart.indexOf("/");
20412
+ if (slashIdx === -1) {
20413
+ user = credentialsPart || user;
20414
+ } else {
20415
+ user = credentialsPart.slice(0, slashIdx) || user;
20416
+ password = credentialsPart.slice(slashIdx + 1) || password;
20417
+ }
20418
+ }
20419
+ if (!target) {
20420
+ throw new Error(
20421
+ `Invalid Oracle JDBC URL "${redactOracleUrl(trimmed)}". Missing host portion after '@'.`
20422
+ );
20423
+ }
20424
+ return {
20425
+ connectString: target,
20426
+ user,
20427
+ password
20428
+ };
20429
+ }
20430
+ function redactOracleUrl(jdbcUrl) {
20431
+ return jdbcUrl.replace(/(:\/\/)([^@/]+)@/, "$1***@").replace(/(thin:)([^@]+)@/i, "$1***@");
20432
+ }
20433
+
20434
+ // ../connectors/src/lib/oracle-runner.ts
20435
+ async function importOracleDb() {
20436
+ const mod = await import("oracledb");
20437
+ return mod.default ?? mod;
20438
+ }
20439
+ async function runOracleQuery(parsed, sql) {
20440
+ const oracledb = await importOracleDb();
20441
+ const connection2 = await oracledb.getConnection({
20442
+ user: parsed.user,
20443
+ password: parsed.password,
20444
+ connectString: parsed.connectString
20445
+ });
20446
+ try {
20447
+ const result = await connection2.execute(sql, [], {
20448
+ outFormat: oracledb.OUT_FORMAT_OBJECT,
20449
+ // Bound by the connector's own row cap, but keep the driver from
20450
+ // streaming arbitrarily large result sets.
20451
+ maxRows: 5e3
20452
+ });
20453
+ return { rows: result.rows ?? [] };
20454
+ } finally {
20455
+ try {
20456
+ await connection2.close();
20457
+ } catch {
20458
+ }
20459
+ }
20460
+ }
20461
+ async function checkOracleConnection(url, credentials) {
20462
+ let parsed;
20463
+ try {
20464
+ parsed = parseOracleJdbcUrl(url, credentials);
20465
+ } catch (err) {
20466
+ return {
20467
+ success: false,
20468
+ error: err instanceof Error ? err.message : String(err)
20469
+ };
20470
+ }
20471
+ try {
20472
+ await runOracleQuery(parsed, "SELECT 1 FROM DUAL");
20473
+ return { success: true };
20474
+ } catch (err) {
20475
+ let msg = err instanceof Error ? err.message : String(err);
20476
+ msg = msg.replaceAll(url, redactOracleUrl(url));
20477
+ return { success: false, error: msg };
20478
+ }
20479
+ }
20480
+
20257
20481
  // ../connectors/src/lib/ssh-tunnel.ts
20258
20482
  var sshTunnelParameters = {
20259
20483
  sshHost: new ParameterDefinition({
@@ -20415,20 +20639,82 @@ var parameters = {
20415
20639
  };
20416
20640
 
20417
20641
  // ../connectors/src/connectors/jdbc/utils.ts
20418
- var JDBC_PREFIX_RE = /^jdbc:(postgresql|postgres|mysql|mariadb):\/\//i;
20642
+ var POSTGRES_PREFIX_RE = /^jdbc:(postgresql|postgres):\/\//i;
20643
+ var MYSQL_PREFIX_RE = /^jdbc:(mysql|mariadb):\/\//i;
20644
+ var REDSHIFT_PREFIX_RE = /^jdbc:redshift:\/\//i;
20645
+ var SQLSERVER_PREFIX_RE2 = /^jdbc:sqlserver:\/\//i;
20646
+ var ORACLE_PREFIX_RE = /^jdbc:oracle:thin:/i;
20647
+ var KNOWN_UNSUPPORTED = [
20648
+ {
20649
+ prefix: /^jdbc:snowflake:\/\//i,
20650
+ message: "Snowflake JDBC URLs are not routable through the generic `jdbc` connector. Use the dedicated `snowflake` connector."
20651
+ },
20652
+ {
20653
+ prefix: /^jdbc:bigquery:\/\//i,
20654
+ message: "BigQuery JDBC URLs are not routable through the generic `jdbc` connector. Use the dedicated `bigquery` connector."
20655
+ },
20656
+ {
20657
+ prefix: /^jdbc:databricks:\/\//i,
20658
+ message: "Databricks JDBC URLs are not routable through the generic `jdbc` connector. Use the dedicated `databricks` connector."
20659
+ },
20660
+ {
20661
+ prefix: /^jdbc:(trino|presto):\/\//i,
20662
+ message: "Trino/Presto JDBC URLs are not yet supported by the `jdbc` connector (no Node.js client bundled)."
20663
+ },
20664
+ {
20665
+ prefix: /^jdbc:td:\/\//i,
20666
+ message: "Treasure Data JDBC URLs are not yet supported by the `jdbc` connector (no Node.js client bundled). The TD JDBC driver speaks Presto under the hood; Trino/Presto support is the same prerequisite."
20667
+ },
20668
+ {
20669
+ prefix: /^jdbc:oracle:oci/i,
20670
+ message: "Oracle OCI driver URLs are not supported. Use the thin driver form: jdbc:oracle:thin:@host:port/service"
20671
+ },
20672
+ {
20673
+ prefix: /^jdbc:db2:\/\//i,
20674
+ message: "DB2 JDBC URLs are not yet supported by the `jdbc` connector."
20675
+ },
20676
+ {
20677
+ prefix: /^jdbc:(sybase|h2|hsqldb|derby|firebird|sqlite):/i,
20678
+ message: "This JDBC dialect is not supported by the `jdbc` connector."
20679
+ }
20680
+ ];
20419
20681
  function parseJdbcUrl(jdbcUrl, options = {}) {
20420
20682
  const trimmed = jdbcUrl.trim();
20421
- const match = JDBC_PREFIX_RE.exec(trimmed);
20422
- if (!match) {
20683
+ if (SQLSERVER_PREFIX_RE2.test(trimmed)) {
20684
+ return { driver: "sqlserver", originalUrl: trimmed };
20685
+ }
20686
+ if (ORACLE_PREFIX_RE.test(trimmed)) {
20687
+ return { driver: "oracle", originalUrl: trimmed };
20688
+ }
20689
+ let driver;
20690
+ let defaultPort;
20691
+ let forceSsl = false;
20692
+ let nativeProtocol;
20693
+ let withoutPrefix;
20694
+ if (POSTGRES_PREFIX_RE.test(trimmed)) {
20695
+ driver = "postgresql";
20696
+ defaultPort = 5432;
20697
+ nativeProtocol = "postgresql://";
20698
+ withoutPrefix = trimmed.replace(POSTGRES_PREFIX_RE, nativeProtocol);
20699
+ } else if (REDSHIFT_PREFIX_RE.test(trimmed)) {
20700
+ driver = "postgresql";
20701
+ defaultPort = 5439;
20702
+ forceSsl = true;
20703
+ nativeProtocol = "postgresql://";
20704
+ withoutPrefix = trimmed.replace(REDSHIFT_PREFIX_RE, nativeProtocol);
20705
+ } else if (MYSQL_PREFIX_RE.test(trimmed)) {
20706
+ driver = "mysql";
20707
+ defaultPort = 3306;
20708
+ nativeProtocol = "mysql://";
20709
+ withoutPrefix = trimmed.replace(MYSQL_PREFIX_RE, nativeProtocol);
20710
+ } else {
20711
+ for (const { prefix, message } of KNOWN_UNSUPPORTED) {
20712
+ if (prefix.test(trimmed)) throw new Error(message);
20713
+ }
20423
20714
  throw new Error(
20424
- `Unsupported JDBC URL "${redactJdbcUrl(trimmed)}". Supported prefixes: jdbc:postgresql://, jdbc:mysql://, jdbc:mariadb://.`
20715
+ `Unsupported JDBC URL "${redactJdbcUrl(trimmed)}". Supported prefixes: jdbc:postgresql://, jdbc:postgres://, jdbc:mysql://, jdbc:mariadb://, jdbc:sqlserver://, jdbc:oracle:thin:@, jdbc:redshift://.`
20425
20716
  );
20426
20717
  }
20427
- const subProtocol = match[1].toLowerCase();
20428
- const driver = subProtocol === "mysql" || subProtocol === "mariadb" ? "mysql" : "postgresql";
20429
- const defaultPort = driver === "postgresql" ? 5432 : 3306;
20430
- const nativeProtocol = driver === "postgresql" ? "postgresql://" : "mysql://";
20431
- const withoutPrefix = trimmed.replace(JDBC_PREFIX_RE, nativeProtocol);
20432
20718
  const url = new URL(withoutPrefix);
20433
20719
  if (options.username && !url.username) {
20434
20720
  url.username = encodeURIComponent(options.username);
@@ -20436,10 +20722,10 @@ function parseJdbcUrl(jdbcUrl, options = {}) {
20436
20722
  if (options.password && !url.password) {
20437
20723
  url.password = encodeURIComponent(options.password);
20438
20724
  }
20439
- return { driver, nativeUrl: url.toString(), defaultPort };
20725
+ return { driver, nativeUrl: url.toString(), defaultPort, forceSsl };
20440
20726
  }
20441
20727
  function redactJdbcUrl(jdbcUrl) {
20442
- return jdbcUrl.replace(/(:\/\/)([^@/]+)@/, "$1***@");
20728
+ return jdbcUrl.replace(/(:\/\/)([^@/]+)@/, "$1***@").replace(/(password\s*=\s*)([^;&]+)/gi, "$1***");
20443
20729
  }
20444
20730
 
20445
20731
  // ../connectors/src/connectors/jdbc/sdk/index.ts
@@ -20452,46 +20738,76 @@ function createClient(params) {
20452
20738
  const password = params[parameters.password.slug];
20453
20739
  const parsed = parseJdbcUrl(jdbcUrl, { username, password });
20454
20740
  async function runQuery(sql, queryParams) {
20455
- let tunnel;
20456
20741
  try {
20457
- tunnel = await maybeOpenSshTunnel(
20742
+ if (parsed.driver === "sqlserver") {
20743
+ if (queryParams && queryParams.length > 0) {
20744
+ throw new Error(
20745
+ "jdbc sdk: positional parameters are not yet supported for the sqlserver route. Inline literals into the SQL."
20746
+ );
20747
+ }
20748
+ const mssqlParsed = parseSqlServerJdbcUrl(parsed.originalUrl, {
20749
+ username,
20750
+ password
20751
+ });
20752
+ const result = await runMssqlQuery(mssqlParsed, sql);
20753
+ return result.rows;
20754
+ }
20755
+ if (parsed.driver === "oracle") {
20756
+ if (queryParams && queryParams.length > 0) {
20757
+ throw new Error(
20758
+ "jdbc sdk: positional parameters are not yet supported for the oracle route. Inline literals into the SQL."
20759
+ );
20760
+ }
20761
+ const oracleParsed = parseOracleJdbcUrl(parsed.originalUrl, {
20762
+ username,
20763
+ password
20764
+ });
20765
+ const cleanSql = sql.replace(/;\s*$/, "");
20766
+ const result = await runOracleQuery(oracleParsed, cleanSql);
20767
+ return result.rows;
20768
+ }
20769
+ const tunnel = await maybeOpenSshTunnel(
20458
20770
  params,
20459
20771
  parsed.nativeUrl,
20460
20772
  parsed.defaultPort
20461
20773
  );
20462
- if (parsed.driver === "postgresql") {
20463
- const { Pool } = await import("pg");
20464
- const pool2 = new Pool({
20465
- connectionString: tunnel.connectionUrl,
20466
- ssl: { rejectUnauthorized: false },
20467
- connectionTimeoutMillis: 1e4,
20468
- statement_timeout: 6e4
20774
+ try {
20775
+ if (parsed.driver === "postgresql") {
20776
+ const { Pool } = await import("pg");
20777
+ const pool2 = new Pool({
20778
+ connectionString: tunnel.connectionUrl,
20779
+ ssl: { rejectUnauthorized: false },
20780
+ connectionTimeoutMillis: 1e4,
20781
+ statement_timeout: 6e4
20782
+ });
20783
+ try {
20784
+ const result = await pool2.query(sql, queryParams);
20785
+ return result.rows;
20786
+ } finally {
20787
+ await pool2.end();
20788
+ }
20789
+ }
20790
+ const mysql = await import("mysql2/promise");
20791
+ const pool = mysql.createPool({
20792
+ uri: tunnel.connectionUrl,
20793
+ connectTimeout: 1e4
20469
20794
  });
20470
20795
  try {
20471
- const result = await pool2.query(sql, queryParams);
20472
- return result.rows;
20796
+ const [rows] = await pool.query(sql, queryParams);
20797
+ return Array.isArray(rows) ? rows : [];
20473
20798
  } finally {
20474
- await pool2.end();
20799
+ await pool.end();
20475
20800
  }
20476
- }
20477
- const mysql = await import("mysql2/promise");
20478
- const pool = mysql.createPool({
20479
- uri: tunnel.connectionUrl,
20480
- connectTimeout: 1e4
20481
- });
20482
- try {
20483
- const [rows] = await pool.query(sql, queryParams);
20484
- return Array.isArray(rows) ? rows : [];
20485
20801
  } finally {
20486
- await pool.end();
20802
+ await tunnel.close();
20487
20803
  }
20488
20804
  } catch (err) {
20489
20805
  let msg = err instanceof Error ? err.message : String(err);
20490
- msg = msg.replaceAll(parsed.nativeUrl, redactJdbcUrl(jdbcUrl));
20806
+ if (parsed.driver === "postgresql" || parsed.driver === "mysql") {
20807
+ msg = msg.replaceAll(parsed.nativeUrl, redactJdbcUrl(jdbcUrl));
20808
+ }
20491
20809
  msg = msg.replaceAll(jdbcUrl, redactJdbcUrl(jdbcUrl));
20492
20810
  throw new Error(msg);
20493
- } finally {
20494
- await tunnel?.close();
20495
20811
  }
20496
20812
  }
20497
20813
  return {
@@ -20678,7 +20994,7 @@ var inputSchema = z.object({
20678
20994
  ),
20679
20995
  connectionId: z.string().describe("ID of the JDBC connection to use"),
20680
20996
  sql: z.string().describe(
20681
- "SQL query to execute. Use the dialect that matches the JDBC URL (PostgreSQL or MySQL/MariaDB). Always include LIMIT."
20997
+ "SQL query to execute. Use the dialect that matches the JDBC URL prefix (PostgreSQL / Redshift: LIMIT N; MySQL/MariaDB: LIMIT N; SQL Server: TOP N; Oracle: FETCH FIRST N ROWS ONLY). Always bound the row count."
20682
20998
  )
20683
20999
  });
20684
21000
  var outputSchema = z.discriminatedUnion("success", [
@@ -20696,9 +21012,10 @@ var outputSchema = z.discriminatedUnion("success", [
20696
21012
  var executeQueryTool = new ConnectorTool({
20697
21013
  name: "executeQuery",
20698
21014
  description: `Execute a SQL query through the JDBC connector. Returns up to ${MAX_ROWS} rows.
20699
- Use for: schema exploration via \`information_schema\`, data sampling, analytical queries.
20700
- The connector dispatches by JDBC URL prefix to the matching driver (PostgreSQL or MySQL/MariaDB),
20701
- so use the dialect that matches the connection. Always include LIMIT.`,
21015
+ Use for: schema exploration via \`information_schema\` (or USER_TABLES on Oracle), data sampling, analytical queries.
21016
+ The connector dispatches by JDBC URL prefix to the matching driver
21017
+ (PostgreSQL / Redshift / MySQL / MariaDB / SQL Server / Oracle), so use the dialect that matches the connection.
21018
+ Always bound results: LIMIT for PG/MySQL/Redshift, TOP for SQL Server, FETCH FIRST for Oracle.`,
20702
21019
  inputSchema,
20703
21020
  outputSchema,
20704
21021
  async execute({ connectionId, sql }, connections) {
@@ -20724,87 +21041,121 @@ so use the dialect that matches the connection. Always include LIMIT.`,
20724
21041
  error: err instanceof Error ? err.message : String(err)
20725
21042
  };
20726
21043
  }
20727
- let tunnel;
20728
21044
  try {
20729
- tunnel = await maybeOpenSshTunnel(
20730
- connectionParamsToRecord(connection2),
20731
- parsed.nativeUrl,
20732
- parsed.defaultPort
20733
- );
20734
- if (parsed.driver === "postgresql") {
20735
- const { Pool } = await import("pg");
20736
- const pool2 = new Pool({
20737
- connectionString: tunnel.connectionUrl,
20738
- ssl: { rejectUnauthorized: false },
20739
- connectionTimeoutMillis: CONNECT_TIMEOUT_MS,
20740
- statement_timeout: STATEMENT_TIMEOUT_MS
21045
+ if (parsed.driver === "sqlserver") {
21046
+ const mssqlParsed = parseSqlServerJdbcUrl(parsed.originalUrl, {
21047
+ username,
21048
+ password
21049
+ });
21050
+ const result = await runMssqlQuery(mssqlParsed, sql);
21051
+ const rows = result.rows;
21052
+ return {
21053
+ success: true,
21054
+ rowCount: Math.min(rows.length, MAX_ROWS),
21055
+ truncated: rows.length > MAX_ROWS,
21056
+ rows: rows.slice(0, MAX_ROWS)
21057
+ };
21058
+ }
21059
+ if (parsed.driver === "oracle") {
21060
+ const oracleParsed = parseOracleJdbcUrl(parsed.originalUrl, {
21061
+ username,
21062
+ password
21063
+ });
21064
+ const cleanSql = sql.replace(/;\s*$/, "");
21065
+ const result = await runOracleQuery(oracleParsed, cleanSql);
21066
+ const rows = result.rows;
21067
+ return {
21068
+ success: true,
21069
+ rowCount: Math.min(rows.length, MAX_ROWS),
21070
+ truncated: rows.length > MAX_ROWS,
21071
+ rows: rows.slice(0, MAX_ROWS)
21072
+ };
21073
+ }
21074
+ let tunnel;
21075
+ try {
21076
+ tunnel = await maybeOpenSshTunnel(
21077
+ connectionParamsToRecord(connection2),
21078
+ parsed.nativeUrl,
21079
+ parsed.defaultPort
21080
+ );
21081
+ if (parsed.driver === "postgresql") {
21082
+ const { Pool } = await import("pg");
21083
+ const pool2 = new Pool({
21084
+ connectionString: tunnel.connectionUrl,
21085
+ ssl: { rejectUnauthorized: false },
21086
+ connectionTimeoutMillis: CONNECT_TIMEOUT_MS,
21087
+ statement_timeout: STATEMENT_TIMEOUT_MS
21088
+ });
21089
+ try {
21090
+ const result = await pool2.query(sql);
21091
+ const rows = result.rows;
21092
+ const truncated = rows.length > MAX_ROWS;
21093
+ return {
21094
+ success: true,
21095
+ rowCount: Math.min(rows.length, MAX_ROWS),
21096
+ truncated,
21097
+ rows: rows.slice(0, MAX_ROWS)
21098
+ };
21099
+ } finally {
21100
+ await pool2.end();
21101
+ }
21102
+ }
21103
+ const mysql = await import("mysql2/promise");
21104
+ const pool = mysql.createPool({
21105
+ uri: tunnel.connectionUrl,
21106
+ connectTimeout: CONNECT_TIMEOUT_MS
20741
21107
  });
20742
21108
  try {
20743
- const result = await pool2.query(sql);
20744
- const rows = result.rows;
20745
- const truncated = rows.length > MAX_ROWS;
21109
+ const queryPromise = pool.query(sql);
21110
+ const timeoutPromise = new Promise(
21111
+ (_, reject) => setTimeout(
21112
+ () => reject(new Error("Query timed out after 60 seconds")),
21113
+ STATEMENT_TIMEOUT_MS
21114
+ )
21115
+ );
21116
+ const [rows] = await Promise.race([queryPromise, timeoutPromise]);
21117
+ const resultRows = Array.isArray(rows) ? rows : [];
21118
+ const truncated = resultRows.length > MAX_ROWS;
20746
21119
  return {
20747
21120
  success: true,
20748
- rowCount: Math.min(rows.length, MAX_ROWS),
21121
+ rowCount: Math.min(resultRows.length, MAX_ROWS),
20749
21122
  truncated,
20750
- rows: rows.slice(0, MAX_ROWS)
21123
+ rows: resultRows.slice(0, MAX_ROWS)
20751
21124
  };
20752
21125
  } finally {
20753
- await pool2.end();
21126
+ await pool.end();
20754
21127
  }
20755
- }
20756
- const mysql = await import("mysql2/promise");
20757
- const pool = mysql.createPool({
20758
- uri: tunnel.connectionUrl,
20759
- connectTimeout: CONNECT_TIMEOUT_MS
20760
- });
20761
- try {
20762
- const queryPromise = pool.query(sql);
20763
- const timeoutPromise = new Promise(
20764
- (_, reject) => setTimeout(
20765
- () => reject(new Error("Query timed out after 60 seconds")),
20766
- STATEMENT_TIMEOUT_MS
20767
- )
20768
- );
20769
- const [rows] = await Promise.race([queryPromise, timeoutPromise]);
20770
- const resultRows = Array.isArray(rows) ? rows : [];
20771
- const truncated = resultRows.length > MAX_ROWS;
20772
- return {
20773
- success: true,
20774
- rowCount: Math.min(resultRows.length, MAX_ROWS),
20775
- truncated,
20776
- rows: resultRows.slice(0, MAX_ROWS)
20777
- };
20778
21128
  } finally {
20779
- await pool.end();
21129
+ await tunnel?.close();
20780
21130
  }
20781
21131
  } catch (err) {
20782
21132
  let msg = err instanceof Error ? err.message : String(err);
20783
- msg = msg.replaceAll(parsed.nativeUrl, redactJdbcUrl(jdbcUrl));
21133
+ if (parsed.driver === "postgresql" || parsed.driver === "mysql") {
21134
+ msg = msg.replaceAll(parsed.nativeUrl, redactJdbcUrl(jdbcUrl));
21135
+ }
20784
21136
  msg = msg.replaceAll(jdbcUrl, redactJdbcUrl(jdbcUrl));
20785
21137
  return { success: false, error: msg };
20786
- } finally {
20787
- await tunnel?.close();
20788
21138
  }
20789
21139
  }
20790
21140
  });
20791
21141
 
20792
21142
  // ../connectors/src/connectors/jdbc/index.ts
20793
21143
  var tools = { executeQuery: executeQueryTool };
21144
+ var SAMPLE_WRAPPER_RE = /^\s*SELECT\s+\*\s+FROM\s+\(([\s\S]+)\)\s+AS\s+_sq\s+LIMIT\s+(\d+)\s*;?\s*$/i;
20794
21145
  var jdbcConnector = new ConnectorPlugin({
20795
21146
  slug: "jdbc",
20796
21147
  authType: AUTH_TYPES.USER_PASSWORD,
20797
21148
  name: "JDBC",
20798
- description: "Generic JDBC-style connection. Accepts a JDBC URL and dispatches to the matching driver (PostgreSQL, MySQL, MariaDB).",
21149
+ description: "Generic JDBC-style connection. Accepts a JDBC URL and dispatches to the matching driver (PostgreSQL, MySQL/MariaDB, SQL Server, Oracle, Redshift).",
20799
21150
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/4Hgb5qQffrdu5nOkc49WtM/76d82ef6b108c7780e42998137c61b83/jdbc-icon.png",
20800
21151
  parameters,
20801
- releaseFlag: { dev1: true, dev2: false, prod: false },
21152
+ releaseFlag: { dev1: true, dev2: true, prod: true },
20802
21153
  categories: ["database"],
20803
21154
  onboarding: jdbcOnboarding,
20804
21155
  systemPrompt: {
20805
21156
  en: `### Tools
20806
21157
 
20807
- - \`jdbc_executeQuery\`: Executes a SQL query through a JDBC URL and returns rows. The connector dispatches by URL prefix to the matching driver (PostgreSQL or MySQL/MariaDB), so use the dialect that matches the connection. Use this for schema exploration via \`information_schema\` and for sampling data. See the SQL Reference below.
21158
+ - \`jdbc_executeQuery\`: Executes a SQL query through a JDBC URL and returns rows. The connector dispatches by URL prefix to the matching native driver, so use the dialect that matches the connection. Use this for schema exploration via \`information_schema\` (or vendor equivalent) and for sampling data. See the SQL Reference below.
20808
21159
 
20809
21160
  ### Business Logic
20810
21161
 
@@ -20814,16 +21165,29 @@ The business logic type for this connector is "sql".
20814
21165
 
20815
21166
  The dialect depends on the JDBC URL prefix:
20816
21167
 
20817
- - \`jdbc:postgresql://...\` \u2192 PostgreSQL dialect
21168
+ - \`jdbc:postgresql://...\` / \`jdbc:postgres://...\` \u2192 PostgreSQL (driver: \`pg\`). \`LIMIT N\` is native.
20818
21169
  - List tables: \`SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'\`
20819
21170
  - List columns: \`SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'xxx'\`
20820
- - \`jdbc:mysql://...\` / \`jdbc:mariadb://...\` \u2192 MySQL dialect
21171
+ - \`jdbc:redshift://...\` \u2192 Amazon Redshift (driver: \`pg\` with SSL forced; default port 5439). PostgreSQL-compatible wire protocol; \`LIMIT N\` is native.
21172
+ - \`jdbc:mysql://...\` / \`jdbc:mariadb://...\` \u2192 MySQL / MariaDB (driver: \`mysql2\`). \`LIMIT N\` is native.
20821
21173
  - List tables: \`SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()\`
20822
21174
  - List columns: \`SELECT COLUMN_NAME, DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'xxx'\`
20823
- - Always include LIMIT in queries`,
21175
+ - \`jdbc:sqlserver://...\` \u2192 Microsoft SQL Server / Azure SQL (driver: \`mssql\` / \`tedious\`). T-SQL dialect. **Use \`TOP N\` instead of \`LIMIT N\`** in queries you write.
21176
+ - List tables: \`SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'\`
21177
+ - List columns: \`SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'xxx'\`
21178
+ - \`jdbc:oracle:thin:@host:port/service\` (or \`@//host:port/service\` / \`@host:port:sid\`) \u2192 Oracle Database (driver: \`oracledb\` thin). Oracle SQL. **No \`LIMIT\` keyword** \u2014 use \`FETCH FIRST N ROWS ONLY\`, \`OFFSET m ROWS FETCH NEXT N ROWS ONLY\`, or \`ROWNUM\` filters.
21179
+ - List tables: \`SELECT TABLE_NAME FROM USER_TABLES\`
21180
+ - List columns: \`SELECT COLUMN_NAME, DATA_TYPE FROM USER_TAB_COLUMNS WHERE TABLE_NAME = UPPER('xxx')\`
21181
+
21182
+ Explicitly **not** supported via this connector \u2014 use the dedicated connector or open a request:
21183
+ \`jdbc:snowflake://\` (use \`snowflake\`), \`jdbc:bigquery://\` (use \`bigquery\`), \`jdbc:databricks://\` (use \`databricks\`), \`jdbc:trino://\` / \`jdbc:presto://\` / \`jdbc:td://\` (Treasure Data) \u2014 no Node.js client bundled.
21184
+
21185
+ ### Row-limit compatibility (server-logic schema inference)
21186
+
21187
+ The platform's server-logic schema inference may wrap your query as \`SELECT * FROM (<inner>) AS _sq LIMIT N\` (PostgreSQL/MySQL syntax). For PostgreSQL / Redshift / MySQL routes this executes natively. For \`jdbc:sqlserver://\` and \`jdbc:oracle:thin:\` routes, the connector detects this exact wrapper at \`query()\` time, executes \`<inner>\` directly via the dialect-specific driver, and slices the first N rows in JS. You do not need to handle this \u2014 but in queries **you author**, do not use \`LIMIT\` for the SQL Server / Oracle routes; use \`TOP\` / \`FETCH FIRST\` as listed above.`,
20824
21188
  ja: `### \u30C4\u30FC\u30EB
20825
21189
 
20826
- - \`jdbc_executeQuery\`: JDBC URL \u7D4C\u7531\u3067 SQL \u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u3057\u3001\u884C\u30C7\u30FC\u30BF\u3092\u8FD4\u3057\u307E\u3059\u3002\u30B3\u30CD\u30AF\u30BF\u306F URL \u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u304B\u3089\u5BFE\u5FDC\u3059\u308B\u30C9\u30E9\u30A4\u30D0\uFF08PostgreSQL \u307E\u305F\u306F MySQL/MariaDB\uFF09\u306B\u632F\u308A\u5206\u3051\u308B\u305F\u3081\u3001\u63A5\u7D9A\u5148\u306B\u5408\u3063\u305F\u65B9\u8A00\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\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\u3002\u4E0B\u90E8\u306E\u300CSQL \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
21190
+ - \`jdbc_executeQuery\`: JDBC URL \u7D4C\u7531\u3067 SQL \u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u3057\u3001\u884C\u30C7\u30FC\u30BF\u3092\u8FD4\u3057\u307E\u3059\u3002\u30B3\u30CD\u30AF\u30BF\u306F URL \u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u304B\u3089\u5BFE\u5FDC\u3059\u308B\u30CD\u30A4\u30C6\u30A3\u30D6\u30C9\u30E9\u30A4\u30D0\u3078\u632F\u308A\u5206\u3051\u308B\u305F\u3081\u3001\u63A5\u7D9A\u5148\u306B\u5408\u3063\u305F\u65B9\u8A00\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\`information_schema\`\uFF08\u307E\u305F\u306F\u5404 DB \u306E\u540C\u7B49\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u30D3\u30E5\u30FC\uFF09\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\u3002\u4E0B\u90E8\u306E\u300CSQL \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
20827
21191
 
20828
21192
  ### Business Logic
20829
21193
 
@@ -20833,13 +21197,26 @@ The dialect depends on the JDBC URL prefix:
20833
21197
 
20834
21198
  JDBC URL \u306E\u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u306B\u3088\u308A\u65B9\u8A00\u304C\u6C7A\u307E\u308A\u307E\u3059:
20835
21199
 
20836
- - \`jdbc:postgresql://...\` \u2192 PostgreSQL \u65B9\u8A00
21200
+ - \`jdbc:postgresql://...\` / \`jdbc:postgres://...\` \u2192 PostgreSQL\uFF08\u30C9\u30E9\u30A4\u30D0: \`pg\`\uFF09\u3002\`LIMIT N\` \u304C\u30CD\u30A4\u30C6\u30A3\u30D6\u3067\u4F7F\u3048\u307E\u3059\u3002
20837
21201
  - \u30C6\u30FC\u30D6\u30EB\u4E00\u89A7: \`SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'\`
20838
21202
  - \u30AB\u30E9\u30E0\u4E00\u89A7: \`SELECT column_name, data_type FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'xxx'\`
20839
- - \`jdbc:mysql://...\` / \`jdbc:mariadb://...\` \u2192 MySQL \u65B9\u8A00
21203
+ - \`jdbc:redshift://...\` \u2192 Amazon Redshift\uFF08\u30C9\u30E9\u30A4\u30D0: \`pg\`\u3001SSL \u5F37\u5236\u3001\u30C7\u30D5\u30A9\u30EB\u30C8\u30DD\u30FC\u30C8 5439\uFF09\u3002PostgreSQL \u30EF\u30A4\u30E4\u4E92\u63DB\u306E\u305F\u3081 \`LIMIT N\` \u304C\u305D\u306E\u307E\u307E\u4F7F\u3048\u307E\u3059\u3002
21204
+ - \`jdbc:mysql://...\` / \`jdbc:mariadb://...\` \u2192 MySQL / MariaDB\uFF08\u30C9\u30E9\u30A4\u30D0: \`mysql2\`\uFF09\u3002\`LIMIT N\` \u304C\u30CD\u30A4\u30C6\u30A3\u30D6\u3067\u4F7F\u3048\u307E\u3059\u3002
20840
21205
  - \u30C6\u30FC\u30D6\u30EB\u4E00\u89A7: \`SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()\`
20841
21206
  - \u30AB\u30E9\u30E0\u4E00\u89A7: \`SELECT COLUMN_NAME, DATA_TYPE FROM information_schema.COLUMNS WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = 'xxx'\`
20842
- - \u30AF\u30A8\u30EA\u306B\u306F\u5FC5\u305A LIMIT \u3092\u542B\u3081\u3066\u304F\u3060\u3055\u3044`
21207
+ - \`jdbc:sqlserver://...\` \u2192 Microsoft SQL Server / Azure SQL\uFF08\u30C9\u30E9\u30A4\u30D0: \`mssql\` / \`tedious\`\uFF09\u3002T-SQL \u65B9\u8A00\u3002**\u81EA\u5206\u3067\u66F8\u304F SQL \u3067\u306F \`LIMIT N\` \u3067\u306F\u306A\u304F \`TOP N\` \u3092\u4F7F\u3046\u3053\u3068**\u3002
21208
+ - \u30C6\u30FC\u30D6\u30EB\u4E00\u89A7: \`SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'\`
21209
+ - \u30AB\u30E9\u30E0\u4E00\u89A7: \`SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'xxx'\`
21210
+ - \`jdbc:oracle:thin:@host:port/service\`\uFF08\`@//host:port/service\` / \`@host:port:sid\` \u3082\u53EF\uFF09\u2192 Oracle Database\uFF08\u30C9\u30E9\u30A4\u30D0: \`oracledb\` thin\uFF09\u3002Oracle SQL\u3002**\`LIMIT\` \u30AD\u30FC\u30EF\u30FC\u30C9\u306F\u5B58\u5728\u3057\u307E\u305B\u3093** \u2014 \`FETCH FIRST N ROWS ONLY\` / \`OFFSET m ROWS FETCH NEXT N ROWS ONLY\` / \`ROWNUM\` \u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002
21211
+ - \u30C6\u30FC\u30D6\u30EB\u4E00\u89A7: \`SELECT TABLE_NAME FROM USER_TABLES\`
21212
+ - \u30AB\u30E9\u30E0\u4E00\u89A7: \`SELECT COLUMN_NAME, DATA_TYPE FROM USER_TAB_COLUMNS WHERE TABLE_NAME = UPPER('xxx')\`
21213
+
21214
+ \u3053\u306E\u30B3\u30CD\u30AF\u30BF\u3067\u306F **\u30B5\u30DD\u30FC\u30C8\u5916**\uFF08\u5C02\u7528\u30B3\u30CD\u30AF\u30BF\u3092\u4F7F\u3046\u304B\u3001\u30EA\u30AF\u30A8\u30B9\u30C8\u8FFD\u52A0\u3057\u3066\u304F\u3060\u3055\u3044\uFF09:
21215
+ \`jdbc:snowflake://\`\uFF08\`snowflake\` \u3092\u4F7F\u7528\uFF09\u3001\`jdbc:bigquery://\`\uFF08\`bigquery\` \u3092\u4F7F\u7528\uFF09\u3001\`jdbc:databricks://\`\uFF08\`databricks\` \u3092\u4F7F\u7528\uFF09\u3001\`jdbc:trino://\` / \`jdbc:presto://\` / \`jdbc:td://\`\uFF08Treasure Data\uFF09\u2014 Node.js \u30AF\u30E9\u30A4\u30A2\u30F3\u30C8\u3092\u540C\u68B1\u3057\u3066\u3044\u307E\u305B\u3093\u3002
21216
+
21217
+ ### \u884C\u6570\u5236\u9650\u306E\u4E92\u63DB\u6027\uFF08server-logic \u30B9\u30AD\u30FC\u30DE\u63A8\u8AD6\uFF09
21218
+
21219
+ \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\`\uFF08PostgreSQL/MySQL \u69CB\u6587\uFF09\u306E\u5F62\u3067\u30E9\u30C3\u30D7\u3057\u3066\u304F\u308B\u3053\u3068\u304C\u3042\u308A\u307E\u3059\u3002PostgreSQL / Redshift / MySQL \u30EB\u30FC\u30C8\u3067\u306F\u305D\u306E\u307E\u307E\u5B9F\u884C\u3055\u308C\u307E\u3059\u3002\`jdbc:sqlserver://\` \u304A\u3088\u3073 \`jdbc:oracle:thin:\` \u30EB\u30FC\u30C8\u3067\u306F\u3001\u30B3\u30CD\u30AF\u30BF\u304C \`query()\` \u5185\u3067\u3053\u306E\u30E9\u30C3\u30D1\u3092\u691C\u51FA\u3057\u3001\`<inner>\` \u3092\u65B9\u8A00\u56FA\u6709\u306E\u30C9\u30E9\u30A4\u30D0\u3067\u76F4\u63A5\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 SQL Server / Oracle \u30EB\u30FC\u30C8\u3067 \`LIMIT\` \u3092\u4F7F\u308F\u305A\u3001\u4E0A\u8A18\u306E \`TOP\` / \`FETCH FIRST\` \u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002`
20843
21220
  },
20844
21221
  tools,
20845
21222
  async checkConnection(params, _config) {
@@ -20855,6 +21232,12 @@ JDBC URL \u306E\u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u306B\u3088\u308A\u65B
20855
21232
  error: e instanceof Error ? e.message : String(e)
20856
21233
  };
20857
21234
  }
21235
+ if (parsed.driver === "sqlserver") {
21236
+ return checkMssqlConnection(parsed.originalUrl, { username, password });
21237
+ }
21238
+ if (parsed.driver === "oracle") {
21239
+ return checkOracleConnection(parsed.originalUrl, { username, password });
21240
+ }
20858
21241
  const tunnel = await maybeOpenSshTunnel(
20859
21242
  params,
20860
21243
  parsed.nativeUrl,
@@ -20864,7 +21247,7 @@ JDBC URL \u306E\u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u306B\u3088\u308A\u65B
20864
21247
  const { Pool } = await import("pg");
20865
21248
  const pool2 = new Pool({
20866
21249
  connectionString: tunnel.connectionUrl,
20867
- ssl: { rejectUnauthorized: false },
21250
+ ssl: parsed.forceSsl ? { rejectUnauthorized: false } : { rejectUnauthorized: false },
20868
21251
  connectionTimeoutMillis: 1e4
20869
21252
  });
20870
21253
  try {
@@ -20903,6 +21286,35 @@ JDBC URL \u306E\u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u306B\u3088\u308A\u65B
20903
21286
  const username = params[parameters.username.slug];
20904
21287
  const password = params[parameters.password.slug];
20905
21288
  const parsed = parseJdbcUrl(jdbcUrl, { username, password });
21289
+ if (parsed.driver === "sqlserver") {
21290
+ const mssqlParsed = parseSqlServerJdbcUrl(parsed.originalUrl, {
21291
+ username,
21292
+ password
21293
+ });
21294
+ const wrapper = sql.match(SAMPLE_WRAPPER_RE);
21295
+ if (wrapper) {
21296
+ const inner = wrapper[1].trim();
21297
+ const limit = Number.parseInt(wrapper[2], 10);
21298
+ const result = await runMssqlQuery(mssqlParsed, inner);
21299
+ return { rows: result.rows.slice(0, limit) };
21300
+ }
21301
+ return runMssqlQuery(mssqlParsed, sql);
21302
+ }
21303
+ if (parsed.driver === "oracle") {
21304
+ const oracleParsed = parseOracleJdbcUrl(parsed.originalUrl, {
21305
+ username,
21306
+ password
21307
+ });
21308
+ const wrapper = sql.match(SAMPLE_WRAPPER_RE);
21309
+ if (wrapper) {
21310
+ const inner = wrapper[1].trim().replace(/;\s*$/, "");
21311
+ const limit = Number.parseInt(wrapper[2], 10);
21312
+ const result = await runOracleQuery(oracleParsed, inner);
21313
+ return { rows: result.rows.slice(0, limit) };
21314
+ }
21315
+ const cleanSql = sql.replace(/;\s*$/, "");
21316
+ return runOracleQuery(oracleParsed, cleanSql);
21317
+ }
20906
21318
  const tunnel = await maybeOpenSshTunnel(
20907
21319
  params,
20908
21320
  parsed.nativeUrl,
@@ -20913,7 +21325,7 @@ JDBC URL \u306E\u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u306B\u3088\u308A\u65B
20913
21325
  const cleanSql = sql.replace(/;\s*$/, "");
20914
21326
  const pool2 = new Pool({
20915
21327
  connectionString: tunnel.connectionUrl,
20916
- ssl: { rejectUnauthorized: false },
21328
+ ssl: parsed.forceSsl ? { rejectUnauthorized: false } : { rejectUnauthorized: false },
20917
21329
  connectionTimeoutMillis: 1e4,
20918
21330
  statement_timeout: 6e4
20919
21331
  });