From f771fef87ea8c0e4941fbde31f081aec389e1f80 Mon Sep 17 00:00:00 2001 From: mertmit Date: Wed, 5 Oct 2022 01:45:26 +0300 Subject: [PATCH 1/4] fix: select column operations for mysql Signed-off-by: mertmit --- .../nocodb/src/lib/meta/api/columnApis.ts | 111 ++++++++++++------ 1 file changed, 76 insertions(+), 35 deletions(-) diff --git a/packages/nocodb/src/lib/meta/api/columnApis.ts b/packages/nocodb/src/lib/meta/api/columnApis.ts index d625ac1474..f6e86d0967 100644 --- a/packages/nocodb/src/lib/meta/api/columnApis.ts +++ b/packages/nocodb/src/lib/meta/api/columnApis.ts @@ -935,17 +935,30 @@ export async function columnUpdate(req: Request, res: Response) { } } else if (column.uidt === UITypes.MultiSelect) { if (driverType === 'mysql' || driverType === 'mysql2') { - await dbDriver.raw( - `UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), ',')) WHERE FIND_IN_SET(?, ??)`, - [ - table.table_name, - column.column_name, - column.column_name, - option.title, - option.title, - column.column_name, - ] - ); + if (colBody.dt === 'set') { + await dbDriver.raw( + `UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), ',')) WHERE FIND_IN_SET(?, ??)`, + [ + table.table_name, + column.column_name, + column.column_name, + option.title, + option.title, + column.column_name, + ] + ); + } else { + await dbDriver.raw( + `UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), ','))`, + [ + table.table_name, + column.column_name, + column.column_name, + option.title, + ] + ); + } + } else if (driverType === 'pg') { await dbDriver.raw( `UPDATE ?? SET ?? = array_to_string(array_remove(string_to_array(??, ','), ?), ',')`, @@ -1101,18 +1114,31 @@ export async function columnUpdate(req: Request, res: Response) { } } else if (column.uidt === UITypes.MultiSelect) { if (driverType === 'mysql' || driverType === 'mysql2') { - await dbDriver.raw( - `UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), CONCAT(',', ?, ','))) WHERE FIND_IN_SET(?, ??)`, - [ - table.table_name, - column.column_name, - column.column_name, - option.title, - newOp.title, - option.title, - column.column_name, - ] - ); + if (colBody.dt === 'set') { + await dbDriver.raw( + `UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), CONCAT(',', ?, ','))) WHERE FIND_IN_SET(?, ??)`, + [ + table.table_name, + column.column_name, + column.column_name, + option.title, + newOp.title, + option.title, + column.column_name, + ] + ); + } else { + await dbDriver.raw( + `UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), CONCAT(',', ?, ',')))`, + [ + table.table_name, + column.column_name, + column.column_name, + option.title, + newOp.title, + ] + ); + } } else if (driverType === 'pg') { await dbDriver.raw( `UPDATE ?? SET ?? = array_to_string(array_replace(string_to_array(??, ','), ?, ?), ',')`, @@ -1174,18 +1200,33 @@ export async function columnUpdate(req: Request, res: Response) { } } else if (column.uidt === UITypes.MultiSelect) { if (driverType === 'mysql' || driverType === 'mysql2') { - await dbDriver.raw( - `UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), CONCAT(',', ?, ','))) WHERE FIND_IN_SET(?, ??)`, - [ - table.table_name, - column.column_name, - column.column_name, - ch.temp_title, - newOp.title, - ch.temp_title, - column.column_name, - ] - ); + if (colBody.dt === 'set') { + await dbDriver.raw( + `UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), CONCAT(',', ?, ','))) WHERE FIND_IN_SET(?, ??)`, + [ + table.table_name, + column.column_name, + column.column_name, + ch.temp_title, + newOp.title, + ch.temp_title, + column.column_name, + ] + ); + } else { + await dbDriver.raw( + `UPDATE ?? SET ?? = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', ??, ','), CONCAT(',', ?, ','), CONCAT(',', ?, ',')))`, + [ + table.table_name, + column.column_name, + column.column_name, + ch.temp_title, + newOp.title, + ch.temp_title, + column.column_name, + ] + ); + } } else if (driverType === 'pg') { await dbDriver.raw( `UPDATE ?? SET ?? = array_to_string(array_replace(string_to_array(??, ','), ?, ?), ',')`, From 7645f5c5c0dda87f3be0bba930249a711085fcd9 Mon Sep 17 00:00:00 2001 From: mertmit Date: Wed, 5 Oct 2022 01:47:42 +0300 Subject: [PATCH 2/4] fix(at-import): select options match duplicates case-insensitive Signed-off-by: mertmit --- packages/nocodb/src/lib/meta/api/sync/helpers/job.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts b/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts index 506ad03799..090d54a274 100644 --- a/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts +++ b/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts @@ -446,7 +446,7 @@ export default async ( // TODO fix record mapping (this causes every record to map first option, we can't handle them using data api as they don't provide option id within data we might instead get the correct mapping from schema file ) let dupNo = 1; const defaultName = (value as any).name; - while (options.find((el) => el.title === (value as any).name)) { + while (options.find((el) => el.title.toLowerCase() === (value as any).name.toLowerCase())) { (value as any).name = `${defaultName}_${dupNo++}`; } options.push({ From 1cfbdb2e83d1802c2500cd4640fa7b48a8afe662 Mon Sep 17 00:00:00 2001 From: mertmit Date: Sat, 15 Oct 2022 16:33:48 +0300 Subject: [PATCH 3/4] fix: handle more than 64 options for mysql Signed-off-by: mertmit --- packages/nocodb/src/lib/meta/api/columnApis.ts | 12 ++++++++++++ .../nocodb/src/lib/meta/api/sync/helpers/job.ts | 14 +++++++++----- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/nocodb/src/lib/meta/api/columnApis.ts b/packages/nocodb/src/lib/meta/api/columnApis.ts index f6e86d0967..883ed17cc3 100644 --- a/packages/nocodb/src/lib/meta/api/columnApis.ts +++ b/packages/nocodb/src/lib/meta/api/columnApis.ts @@ -605,6 +605,12 @@ export async function columnAdd(req: Request, res: Response) { ) { colBody.dtxp = "''"; } + + if (colBody.dt === 'set') { + if (colBody.colOptions?.options.length > 64) { + colBody.dt = 'text'; + } + } } } @@ -901,6 +907,12 @@ export async function columnUpdate(req: Request, res: Response) { ) { colBody.dtxp = "''"; } + + if (colBody.dt === 'set') { + if (colBody.colOptions?.options.length > 64) { + colBody.dt = 'text'; + } + } } // Handle option delete diff --git a/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts b/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts index 090d54a274..39202e609b 100644 --- a/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts +++ b/packages/nocodb/src/lib/meta/api/sync/helpers/job.ts @@ -577,11 +577,15 @@ export default async ( ncCol.colOptions = { options: [...colOptions.data], }; - // if options are empty, configure '' as default option - ncCol.dtxp = - colOptions.data - .map((el) => `'${el.title.replace(/'/gi, "''")}'`) - .join(',') || "''"; + + if (['mysql', 'mysql2'].includes(getRootDbType())) { + // if options are empty, configure '' as an option + ncCol.dtxp = + colOptions.data + .map((el) => `'${el.title.replace(/'/gi, "''")}'`) + .join(',') || "''"; + } + break; case undefined: break; From 783c4d532622502d7749f1b278c96d99a078bd30 Mon Sep 17 00:00:00 2001 From: mertmit Date: Sat, 15 Oct 2022 17:30:39 +0300 Subject: [PATCH 4/4] fix: mysql use text for multiselect if more than 64 options Signed-off-by: mertmit --- packages/nocodb-sdk/src/lib/sqlUi/MysqlUi.ts | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/nocodb-sdk/src/lib/sqlUi/MysqlUi.ts b/packages/nocodb-sdk/src/lib/sqlUi/MysqlUi.ts index 5bea5252e1..79dc5a25cc 100644 --- a/packages/nocodb-sdk/src/lib/sqlUi/MysqlUi.ts +++ b/packages/nocodb-sdk/src/lib/sqlUi/MysqlUi.ts @@ -944,7 +944,7 @@ export class MysqlUi { } } - static getDataTypeForUiType(col: { uidt: UITypes }, idType?: IDType) { + static getDataTypeForUiType(col: { uidt: UITypes, dtxp?: string, colOptions?: any }, idType?: IDType) { const colProp: any = {}; switch (col.uidt) { case 'ID': @@ -977,6 +977,9 @@ export class MysqlUi { break; case 'MultiSelect': colProp.dt = 'set'; + if (col.colOptions?.options.length > 64 || col.dtxp?.split(',').length > 64) { + colProp.dt = 'text'; + } break; case 'SingleSelect': colProp.dt = 'enum';