From bc03f73408d11b8a13135b8e3a344df696814462 Mon Sep 17 00:00:00 2001 From: Mert Ersoy Date: Mon, 7 Mar 2022 03:06:16 +0300 Subject: [PATCH 1/2] fix: incorrect datetime for MySQL Signed-off-by: Mert Ersoy --- .../components/editableCell/dateTimePickerCell.vue | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/nc-gui/components/project/spreadsheet/components/editableCell/dateTimePickerCell.vue b/packages/nc-gui/components/project/spreadsheet/components/editableCell/dateTimePickerCell.vue index b61e32c277..1501cc7ce2 100644 --- a/packages/nc-gui/components/project/spreadsheet/components/editableCell/dateTimePickerCell.vue +++ b/packages/nc-gui/components/project/spreadsheet/components/editableCell/dateTimePickerCell.vue @@ -42,7 +42,11 @@ export default { .format('YYYY-MM-DD HH:mm') }, set(val) { - this.$emit('input', val && dayjs(val).format('YYYY-MM-DD HH:mm:ssZ')) + if(this.$parent.sqlUi.name == 'MysqlUi') { + this.$emit('input', val && dayjs(val).format('YYYY-MM-DD HH:mm:ss')) + } else { + this.$emit('input', val && dayjs(val).format('YYYY-MM-DD HH:mm:ssZ')) + } } }, parentListeners() { From 99d2c77c5e0e05ca7b6b8af6796f8326e9caba99 Mon Sep 17 00:00:00 2001 From: Mert Ersoy Date: Mon, 7 Mar 2022 03:06:33 +0300 Subject: [PATCH 2/2] feat: DATEADD formula for date arithmetics Signed-off-by: Mert Ersoy --- packages/nc-gui/helpers/formulaList.js | 1 + .../lib/sql/formulaQueryBuilderFromString.ts | 9 +++++++ .../lib/sql/functionMappings/mssql.ts | 24 +++++++++++++++++ .../lib/sql/functionMappings/mysql.ts | 26 +++++++++++++++++++ .../dataMapper/lib/sql/functionMappings/pg.ts | 24 +++++++++++++++++ .../lib/sql/functionMappings/sqlite.ts | 24 +++++++++++++++++ 6 files changed, 108 insertions(+) diff --git a/packages/nc-gui/helpers/formulaList.js b/packages/nc-gui/helpers/formulaList.js index 6a2135dc96..cf6d2b5e7b 100644 --- a/packages/nc-gui/helpers/formulaList.js +++ b/packages/nc-gui/helpers/formulaList.js @@ -55,6 +55,7 @@ const validations = { IF: { validation: { args: { min: 2, max: 3 } } }, SWITCH: { validation: { args: { min: 3 } } }, URL: { validation: { args: { rqd: 1 } } }, + DATEADD: { validation: { args: { rqd: 3 } } }, }; export default Object.keys(validations); diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/formulaQueryBuilderFromString.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/formulaQueryBuilderFromString.ts index d31310403d..20d0a7d271 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/formulaQueryBuilderFromString.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/formulaQueryBuilderFromString.ts @@ -90,6 +90,15 @@ export default function formulaQueryBuilder( prevBinaryOp ); break; + case 'DATEADD': + if(pt.arguments[1].value) { + pt.callee.name = "DATE_ADD"; + return fn(pt, a, prevBinaryOp); + } else if(pt.arguments[1].operator == '-') { + pt.callee.name = "DATE_SUB"; + return fn(pt, a, prevBinaryOp); + } + break; default: { const res = mapFunctionName({ diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts index dd7a207851..cc06d88561 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mssql.ts @@ -88,6 +88,30 @@ const mssql = { return args.knex .raw(`CAST(${args.fn(args.pt.arguments[0])} as FLOAT)${args.colAlias}`) .wrap('(', ')'); + }, + DATE_ADD: (args: MapFnArgs) => { + return args.knex.raw( + `CASE + WHEN ${args.fn(args.pt.arguments[0])} LIKE '%:%' THEN + FORMAT(DATEADD(${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}, + +${args.fn(args.pt.arguments[1])}, ${args.fn(args.pt.arguments[0])}), 'yyyy-MM-dd HH:mm') + ELSE + FORMAT(DATEADD(${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}, + +${args.fn(args.pt.arguments[1])}, ${args.fn(args.pt.arguments[0])}), 'yyyy-MM-dd') + END${args.colAlias}` + ); + }, + DATE_SUB: (args: MapFnArgs) => { + return args.knex.raw( + `CASE + WHEN ${args.fn(args.pt.arguments[0])} LIKE '%:%' THEN + FORMAT(DATEADD(${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}, + -${args.fn(args.pt.arguments[1])}.argument.value, ${args.fn(args.pt.arguments[0])}), 'yyyy-MM-dd HH:mm') + ELSE + FORMAT(DATEADD(${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}, + -${args.fn(args.pt.arguments[1])}.argument.value, ${args.fn(args.pt.arguments[0])}), 'yyyy-MM-dd') + END${args.colAlias}` + ); } }; diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts index 73e00d3ae3..c8d47834a5 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/mysql.ts @@ -36,6 +36,32 @@ const mysql2 = { return args.knex .raw(`CAST(${args.fn(args.pt.arguments[0])} as DOUBLE)${args.colAlias}`) .wrap('(', ')'); + }, + DATE_ADD: (args: MapFnArgs) => { + return args.knex.raw( + `CASE + WHEN ${args.fn(args.pt.arguments[0])} LIKE '%:%' THEN + DATE_FORMAT(DATE_ADD(${args.fn(args.pt.arguments[0])}, INTERVAL + ${args.fn(args.pt.arguments[1])} ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}), '%Y-%m-%d %H:%i') + ELSE + DATE(DATE_ADD(${args.fn(args.pt.arguments[0])}, INTERVAL + ${args.fn(args.pt.arguments[1])} ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")})) + END${args.colAlias}` + ); + }, + DATE_SUB: (args: MapFnArgs) => { + return args.knex.raw( + `CASE + WHEN ${args.fn(args.pt.arguments[0])} LIKE '%:%' THEN + DATE_FORMAT(DATE_ADD(${args.fn(args.pt.arguments[0])}, INTERVAL + ${args.fn(args.pt.arguments[1])}.argument.value + ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}), '%Y-%m-%d %H:%i') + ELSE + DATE(DATE_ADD(${args.fn(args.pt.arguments[0])}, INTERVAL + ${args.fn(args.pt.arguments[1])}.argument.value + ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")})) + END${args.colAlias}` + ); } }; diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts index 41519fa11c..ef7fe9a091 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/pg.ts @@ -36,6 +36,30 @@ const pg = { }` ) .wrap('(', ')'); + }, + DATE_ADD: (args: MapFnArgs) => { + return args.knex.raw( + `CASE + WHEN CAST(${args.fn(args.pt.arguments[0])} AS text) LIKE '%:%' THEN + to_char(${args.fn(args.pt.arguments[0])} + INTERVAL '${args.fn(args.pt.arguments[1])} + ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}', 'YYYY-MM-DD HH24:MI') + ELSE + to_char(${args.fn(args.pt.arguments[0])} + INTERVAL '${args.fn(args.pt.arguments[1])} + ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}', 'YYYY-MM-DD') + END${args.colAlias}` + ); + }, + DATE_SUB: (args: MapFnArgs) => { + return args.knex.raw( + `CASE + WHEN CAST(${args.fn(args.pt.arguments[0])} AS text) LIKE '%:%' THEN + to_char(${args.fn(args.pt.arguments[0])} - INTERVAL '${args.fn(args.pt.arguments[1]).argument.value} + ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}', 'YYYY-MM-DD HH24:MI') + ELSE + to_char(${args.fn(args.pt.arguments[0])} - INTERVAL '${args.fn(args.pt.arguments[1]).argument.value} + ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}', 'YYYY-MM-DD') + END${args.colAlias}` + ); } }; diff --git a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts index d8ca5564de..74dfaa8f32 100644 --- a/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts +++ b/packages/nocodb/src/lib/dataMapper/lib/sql/functionMappings/sqlite.ts @@ -55,6 +55,30 @@ const sqlite3 = { return args.knex .raw(`CAST(${args.fn(args.pt.arguments[0])} as FLOAT)${args.colAlias}`) .wrap('(', ')'); + }, + DATE_ADD: (args: MapFnArgs) => { + return args.knex.raw( + `CASE + WHEN ${args.fn(args.pt.arguments[0])} LIKE '%:%' THEN + STRFTIME('%Y-%m-%d %H:%M', DATETIME(DATETIME(${args.fn(args.pt.arguments[0])}, 'localtime'), + '+${args.fn(args.pt.arguments[1])} ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}')) + ELSE + DATE(DATETIME(${args.fn(args.pt.arguments[0])}, 'localtime'), + '+${args.fn(args.pt.arguments[1])} ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}') + END${args.colAlias}` + ); + }, + DATE_SUB: (args: MapFnArgs) => { + return args.knex.raw( + `CASE + WHEN ${args.fn(args.pt.arguments[0])} LIKE '%:%' THEN + STRFTIME('%Y-%m-%d %H:%M', DATETIME(DATETIME(${args.fn(args.pt.arguments[0])}, 'localtime'), + '-${args.fn(args.pt.arguments[1]).argument.value} ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}')) + ELSE + DATE(DATETIME(${args.fn(args.pt.arguments[0])}, 'localtime'), + '-${args.fn(args.pt.arguments[1]).argument.value} ${String(args.fn(args.pt.arguments[2])).replace(/["']/g, "")}') + END${args.colAlias}` + ); } };