mirror of
https://github.com/n8n-io/n8n.git
synced 2025-02-02 07:01:30 -08:00
fix(MySQL Node): Query to statements splitting fix (#9207)
This commit is contained in:
parent
093dcefafc
commit
dc844528f4
|
@ -11,7 +11,7 @@ export class MySql extends VersionedNodeType {
|
||||||
name: 'mySql',
|
name: 'mySql',
|
||||||
icon: 'file:mysql.svg',
|
icon: 'file:mysql.svg',
|
||||||
group: ['input'],
|
group: ['input'],
|
||||||
defaultVersion: 2.3,
|
defaultVersion: 2.4,
|
||||||
description: 'Get, add and update data in MySQL',
|
description: 'Get, add and update data in MySQL',
|
||||||
parameterPane: 'wide',
|
parameterPane: 'wide',
|
||||||
};
|
};
|
||||||
|
@ -22,6 +22,7 @@ export class MySql extends VersionedNodeType {
|
||||||
2.1: new MySqlV2(baseDescription),
|
2.1: new MySqlV2(baseDescription),
|
||||||
2.2: new MySqlV2(baseDescription),
|
2.2: new MySqlV2(baseDescription),
|
||||||
2.3: new MySqlV2(baseDescription),
|
2.3: new MySqlV2(baseDescription),
|
||||||
|
2.4: new MySqlV2(baseDescription),
|
||||||
};
|
};
|
||||||
|
|
||||||
super(nodeVersions, baseDescription);
|
super(nodeVersions, baseDescription);
|
||||||
|
|
|
@ -8,6 +8,7 @@ import {
|
||||||
addSortRules,
|
addSortRules,
|
||||||
replaceEmptyStringsByNulls,
|
replaceEmptyStringsByNulls,
|
||||||
escapeSqlIdentifier,
|
escapeSqlIdentifier,
|
||||||
|
splitQueryToStatements,
|
||||||
} from '../../v2/helpers/utils';
|
} from '../../v2/helpers/utils';
|
||||||
|
|
||||||
const mySqlMockNode: INode = {
|
const mySqlMockNode: INode = {
|
||||||
|
@ -175,3 +176,29 @@ describe('Test MySql V2, escapeSqlIdentifier', () => {
|
||||||
expect(escapedIdentifier).toEqual('`db_name`.`some.dotted.tbl_name`');
|
expect(escapedIdentifier).toEqual('`db_name`.`some.dotted.tbl_name`');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('Test MySql V2, splitQueryToStatements', () => {
|
||||||
|
it('should split query into statements', () => {
|
||||||
|
const query =
|
||||||
|
"insert into models (`created_at`, custom_ship_time, id) values ('2023-09-07 10:26:20', 'some random; data with a semicolon', 1); insert into models (`created_at`, custom_ship_time, id) values ('2023-09-07 10:27:55', 'random data without semicolon\n', 2);";
|
||||||
|
|
||||||
|
const statements = splitQueryToStatements(query);
|
||||||
|
|
||||||
|
expect(statements).toBeDefined();
|
||||||
|
expect(statements).toEqual([
|
||||||
|
"insert into models (`created_at`, custom_ship_time, id) values ('2023-09-07 10:26:20', 'some random; data with a semicolon', 1)",
|
||||||
|
"insert into models (`created_at`, custom_ship_time, id) values ('2023-09-07 10:27:55', 'random data without semicolon', 2)",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
it('should not split by ; inside string literal', () => {
|
||||||
|
const query =
|
||||||
|
"SELECT custom_ship_time FROM models WHERE models.custom_ship_time LIKE CONCAT('%', ';', '%') LIMIT 10";
|
||||||
|
|
||||||
|
const statements = splitQueryToStatements(query);
|
||||||
|
|
||||||
|
expect(statements).toBeDefined();
|
||||||
|
expect(statements).toEqual([
|
||||||
|
"SELECT custom_ship_time FROM models WHERE models.custom_ship_time LIKE CONCAT('%', ';', '%') LIMIT 10",
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
@ -8,7 +8,7 @@ export const versionDescription: INodeTypeDescription = {
|
||||||
name: 'mySql',
|
name: 'mySql',
|
||||||
icon: 'file:mysql.svg',
|
icon: 'file:mysql.svg',
|
||||||
group: ['input'],
|
group: ['input'],
|
||||||
version: [2, 2.1, 2.2, 2.3],
|
version: [2, 2.1, 2.2, 2.3, 2.4],
|
||||||
subtitle: '={{ $parameter["operation"] }}',
|
subtitle: '={{ $parameter["operation"] }}',
|
||||||
description: 'Get, add and update data in MySQL',
|
description: 'Get, add and update data in MySQL',
|
||||||
defaults: {
|
defaults: {
|
||||||
|
|
|
@ -190,6 +190,14 @@ export function prepareOutput(
|
||||||
|
|
||||||
return returnData;
|
return returnData;
|
||||||
}
|
}
|
||||||
|
const END_OF_STATEMENT = /;(?=(?:[^'\\]|'[^']*?'|\\[\s\S])*?$)/g;
|
||||||
|
export const splitQueryToStatements = (query: string, filterOutEmpty = true) => {
|
||||||
|
const statements = query
|
||||||
|
.replace(/\n/g, '')
|
||||||
|
.split(END_OF_STATEMENT)
|
||||||
|
.map((statement) => statement.trim());
|
||||||
|
return filterOutEmpty ? statements.filter((statement) => statement !== '') : statements;
|
||||||
|
};
|
||||||
|
|
||||||
export function configureQueryRunner(
|
export function configureQueryRunner(
|
||||||
this: IExecuteFunctions,
|
this: IExecuteFunctions,
|
||||||
|
@ -225,10 +233,15 @@ export function configureQueryRunner(
|
||||||
|
|
||||||
if (!response) return [];
|
if (!response) return [];
|
||||||
|
|
||||||
const statements = singleQuery
|
let statements;
|
||||||
.replace(/\n/g, '')
|
if ((options?.nodeVersion as number) <= 2.3) {
|
||||||
.split(';')
|
statements = singleQuery
|
||||||
.filter((statement) => statement !== '');
|
.replace(/\n/g, '')
|
||||||
|
.split(';')
|
||||||
|
.filter((statement) => statement !== '');
|
||||||
|
} else {
|
||||||
|
statements = splitQueryToStatements(singleQuery);
|
||||||
|
}
|
||||||
|
|
||||||
if (Array.isArray(response)) {
|
if (Array.isArray(response)) {
|
||||||
if (statements.length === 1) response = [response];
|
if (statements.length === 1) response = [response];
|
||||||
|
@ -261,7 +274,13 @@ export function configureQueryRunner(
|
||||||
try {
|
try {
|
||||||
const { query, values } = queryWithValues;
|
const { query, values } = queryWithValues;
|
||||||
formatedQuery = connection.format(query, values);
|
formatedQuery = connection.format(query, values);
|
||||||
const statements = formatedQuery.split(';').map((q) => q.trim());
|
|
||||||
|
let statements;
|
||||||
|
if ((options?.nodeVersion as number) <= 2.3) {
|
||||||
|
statements = formatedQuery.split(';').map((q) => q.trim());
|
||||||
|
} else {
|
||||||
|
statements = splitQueryToStatements(formatedQuery, false);
|
||||||
|
}
|
||||||
|
|
||||||
const responses: IDataObject[] = [];
|
const responses: IDataObject[] = [];
|
||||||
for (const statement of statements) {
|
for (const statement of statements) {
|
||||||
|
@ -300,7 +319,13 @@ export function configureQueryRunner(
|
||||||
try {
|
try {
|
||||||
const { query, values } = queryWithValues;
|
const { query, values } = queryWithValues;
|
||||||
formatedQuery = connection.format(query, values);
|
formatedQuery = connection.format(query, values);
|
||||||
const statements = formatedQuery.split(';').map((q) => q.trim());
|
|
||||||
|
let statements;
|
||||||
|
if ((options?.nodeVersion as number) <= 2.3) {
|
||||||
|
statements = formatedQuery.split(';').map((q) => q.trim());
|
||||||
|
} else {
|
||||||
|
statements = splitQueryToStatements(formatedQuery, false);
|
||||||
|
}
|
||||||
|
|
||||||
const responses: IDataObject[] = [];
|
const responses: IDataObject[] = [];
|
||||||
for (const statement of statements) {
|
for (const statement of statements) {
|
||||||
|
|
Loading…
Reference in a new issue