diff --git a/packages/server/src/integrations/mysql.ts b/packages/server/src/integrations/mysql.ts index cb71a78013..b88162c59a 100644 --- a/packages/server/src/integrations/mysql.ts +++ b/packages/server/src/integrations/mysql.ts @@ -93,6 +93,21 @@ const SCHEMA: Integration = { }, } +const defaultTypeCasting = function (field: any, next: any) { + if ( + field.type == "DATETIME" || + field.type === "DATE" || + field.type === "TIMESTAMP" || + field.type === "LONGLONG" + ) { + return field.string() + } + if (field.type === "BIT" && field.length === 1) { + return field.buffer()?.[0] + } + return next() +} + export function bindingTypeCoerce(bindings: any[]) { for (let i = 0; i < bindings.length; i++) { const binding = bindings[i] @@ -147,24 +162,9 @@ class MySQLIntegration extends Sql implements DatasourcePlus { delete config.rejectUnauthorized this.config = { ...config, + typeCast: defaultTypeCasting, multipleStatements: true, } - if (!this.config.typeCast) { - this.config.typeCast = function (field: any, next: any) { - if ( - field.type == "DATETIME" || - field.type === "DATE" || - field.type === "TIMESTAMP" || - field.type === "LONGLONG" - ) { - return field.string() - } - if (field.type === "BIT" && field.length === 1) { - return field.buffer()?.[0] - } - return next() - } - } } async testConnection() { @@ -196,6 +196,37 @@ class MySQLIntegration extends Sql implements DatasourcePlus { return `concat(${parts.join(", ")})` } + defineTypeCastingFromSchema(schema: { + [key: string]: { name: string; type: string } + }): void { + if (!schema) { + return + } + this.config.typeCast = function (field: any, next: any) { + if (schema[field.name]?.name === field.name) { + if (["LONGLONG", "NEWDECIMAL", "DECIMAL"].includes(field.type)) { + if (schema[field.name]?.type === "number") { + const value = field.string() + return value ? Number(value) : null + } else { + return field.string() + } + } + } + if ( + field.type == "DATETIME" || + field.type === "DATE" || + field.type === "TIMESTAMP" + ) { + return field.string() + } + if (field.type === "BIT" && field.length === 1) { + return field.buffer()?.[0] + } + return next() + } + } + async connect() { this.client = await mysql.createConnection(this.config) } diff --git a/packages/server/src/threads/query.ts b/packages/server/src/threads/query.ts index d3949f7e25..37720c66ba 100644 --- a/packages/server/src/threads/query.ts +++ b/packages/server/src/threads/query.ts @@ -70,34 +70,11 @@ class QueryRunner { datasourceClone.config.authConfigs = updatedConfigs } - if (datasource.source === SourceName.MYSQL && schema) { - datasourceClone.config.typeCast = function (field: any, next: any) { - if (schema[field.name]?.name === field.name) { - if (["LONGLONG", "NEWDECIMAL", "DECIMAL"].includes(field.type)) { - if (schema[field.name]?.type === "number") { - const value = field.string() - return value ? Number(value) : null - } else { - return field.string() - } - } - } - if ( - field.type == "DATETIME" || - field.type === "DATE" || - field.type === "TIMESTAMP" - ) { - return field.string() - } - if (field.type === "BIT" && field.length === 1) { - return field.buffer()?.[0] - } - return next() - } - } - const integration = new Integration(datasourceClone.config) + // define the type casting from the schema + integration.defineTypeCastingFromSchema?.(schema) + // pre-query, make sure datasource variables are added to parameters const parameters = await this.addDatasourceVariables() diff --git a/packages/types/src/sdk/datasources.ts b/packages/types/src/sdk/datasources.ts index 2391f6e878..d6a0d4a7c8 100644 --- a/packages/types/src/sdk/datasources.ts +++ b/packages/types/src/sdk/datasources.ts @@ -166,6 +166,12 @@ export interface IntegrationBase { delete?(query: any): Promise testConnection?(): Promise getExternalSchema?(): Promise + defineTypeCastingFromSchema?(schema: { + [key: string]: { + name: string + type: string + } + }): void } export interface DatasourcePlus extends IntegrationBase {