diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts index 6bf5e41831..ad38851993 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/mssql.ts @@ -14,9 +14,7 @@ const mssql = { for (const [i, arg] of Object.entries(args.pt.arguments)) { if (+i === args.pt.arguments.length - 1) { query += args.knex - .raw( - `\n\tElse ${(await await args.fn(arg)).builder.builder.toQuery()}` - ) + .raw(`\n\tElse ${(await args.fn(arg)).builder.builder.toQuery()}`) .toQuery(); } else { query += args.knex @@ -37,7 +35,7 @@ const mssql = { .toQuery(); } } - return args.knex.raw(`Case ${query}\n End${args.colAlias}`); + return { builder: args.knex.raw(`Case ${query}\n End${args.colAlias}`) }; }, MAX: async (args: MapFnArgs) => { if (args.pt.arguments.length === 1) { @@ -66,18 +64,20 @@ const mssql = { } } - return args.knex.raw(`Case ${query}\n End${args.colAlias}`); + return { builder: args.knex.raw(`Case ${query}\n End${args.colAlias}`) }; }, LOG: async (args: MapFnArgs) => { - return args.knex.raw( - `LOG(${( - await Promise.all( - args.pt.arguments - .reverse() - .map(async (ar) => (await args.fn(ar)).builder.toQuery()) - ) - ).join(',')})${args.colAlias}` - ); + return { + builder: args.knex.raw( + `LOG(${( + await Promise.all( + args.pt.arguments + .reverse() + .map(async (ar) => (await args.fn(ar)).builder.toQuery()) + ) + ).join(',')})${args.colAlias}` + ), + }; }, MOD: (pt) => { Object.assign(pt, { @@ -96,94 +96,118 @@ const mssql = { args.pt.arguments[1] = temp; }, INT: async (args: MapFnArgs) => { - return args.knex.raw( - `CASE WHEN ISNUMERIC(${( - await args.fn(args.pt.arguments[0]) - ).builder.toQuery()}) = 1 THEN FLOOR(${( - await args.fn(args.pt.arguments[0]) - ).builder.toQuery()}) ELSE 0 END${args.colAlias}` - ); + return { + builder: args.knex.raw( + `CASE WHEN ISNUMERIC(${( + await args.fn(args.pt.arguments[0]) + ).builder.toQuery()}) = 1 THEN FLOOR(${( + await args.fn(args.pt.arguments[0]) + ).builder.toQuery()}) ELSE 0 END${args.colAlias}` + ), + }; }, MID: 'SUBSTR', - FLOAT: (args: MapFnArgs) => { - return args.knex - .raw(`CAST(${args.fn(args.pt.arguments[0])} as FLOAT)${args.colAlias}`) - .wrap('(', ')'); + FLOAT: async (args: MapFnArgs) => { + return { + builder: args.knex + .raw( + `CAST(${(await args.fn(args.pt.arguments[0])).builder} as FLOAT)${ + args.colAlias + }` + ) + .wrap('(', ')'), + }; }, DATEADD: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { const dateIN = (await fn(pt.arguments[1])).builder; - return knex.raw( - `CASE - WHEN ${fn(pt.arguments[0])} LIKE '%:%' THEN - FORMAT(DATEADD(${String(fn(pt.arguments[2])).replace(/["']/g, '')}, - ${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])}, ${fn( - pt.arguments[0] - )}), 'yyyy-MM-dd HH:mm') + return { + builder: knex.raw( + `CASE + WHEN ${(await fn(pt.arguments[0])).builder} LIKE '%:%' THEN + FORMAT(DATEADD(${String((await fn(pt.arguments[2])).builder).replace( + /["']/g, + '' + )}, + ${dateIN > 0 ? '+' : ''}${(await fn(pt.arguments[1])).builder}, ${ + (await fn(pt.arguments[0])).builder + }), 'yyyy-MM-dd HH:mm') ELSE - FORMAT(DATEADD(${String(fn(pt.arguments[2])).replace(/["']/g, '')}, - ${dateIN > 0 ? '+' : ''}${fn(pt.arguments[1])}, ${fn( - pt.arguments[0] - )}), 'yyyy-MM-dd') + FORMAT(DATEADD(${String((await fn(pt.arguments[2])).builder).replace( + /["']/g, + '' + )}, + ${dateIN > 0 ? '+' : ''}${(await fn(pt.arguments[1])).builder}, ${fn( + pt.arguments[0] + )}), 'yyyy-MM-dd') END${colAlias}` - ); + ), + }; }, DATETIME_DIFF: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { - const datetime_expr1 = fn(pt.arguments[0]); - const datetime_expr2 = fn(pt.arguments[1]); + const datetime_expr1 = (await fn(pt.arguments[0])).builder; + const datetime_expr2 = (await fn(pt.arguments[1])).builder; const rawUnit = pt.arguments[2] ? (await fn(pt.arguments[2])).builder.bindings[0] : 'seconds'; const unit = convertUnits(rawUnit, 'mssql'); - return knex.raw( - `DATEDIFF(${unit}, ${datetime_expr2}, ${datetime_expr1}) ${colAlias}` - ); + return { + builder: knex.raw( + `DATEDIFF(${unit}, ${datetime_expr2}, ${datetime_expr1}) ${colAlias}` + ), + }; }, WEEKDAY: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { // DATEPART(WEEKDAY, DATE): sunday = 1, monday = 2, ..., saturday = 7 // WEEKDAY() returns an index from 0 to 6 for Monday to Sunday - return knex.raw( - `(DATEPART(WEEKDAY, ${ - pt.arguments[0].type === 'Literal' - ? `'${dayjs((await fn(pt.arguments[0])).builder).format( - 'YYYY-MM-DD' - )}'` - : fn(pt.arguments[0]) - }) - 2 - ${getWeekdayByText( - pt?.arguments[1]?.value - )} % 7 + 7) % 7 ${colAlias}` - ); + return { + builder: knex.raw( + `(DATEPART(WEEKDAY, ${ + pt.arguments[0].type === 'Literal' + ? `'${dayjs((await fn(pt.arguments[0])).builder).format( + 'YYYY-MM-DD' + )}'` + : fn(pt.arguments[0]) + }) - 2 - ${getWeekdayByText( + pt?.arguments[1]?.value + )} % 7 + 7) % 7 ${colAlias}` + ), + }; }, AND: async (args: MapFnArgs) => { - return args.knex.raw( - `CASE WHEN ${args.knex - .raw( - `${( - await Promise.all( - args.pt.arguments.map(async (ar) => - (await args.fn(ar, '', 'AND')).builder.toQuery() + return { + builder: args.knex.raw( + `CASE WHEN ${args.knex + .raw( + `${( + await Promise.all( + args.pt.arguments.map(async (ar) => + (await args.fn(ar, '', 'AND')).builder.toQuery() + ) ) - ) - ).join(' AND ')}` - ) - .wrap('(', ')') - .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` - ); + ).join(' AND ')}` + ) + .wrap('(', ')') + .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` + ), + }; }, OR: async (args: MapFnArgs) => { - return args.knex.raw( - `CASE WHEN ${args.knex - .raw( - `${( - await Promise.all( - args.pt.arguments.map(async (ar) => - (await args.fn(ar, '', 'OR')).builder.toQuery() + return { + builder: args.knex.raw( + `CASE WHEN ${args.knex + .raw( + `${( + await Promise.all( + args.pt.arguments.map(async (ar) => + (await args.fn(ar, '', 'OR')).builder.toQuery() + ) ) - ) - ).join(' OR ')}` - ) - .wrap('(', ')') - .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` - ); + ).join(' OR ')}` + ) + .wrap('(', ')') + .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` + ), + }; }, }; diff --git a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts index bfe91ccbf5..f3c219efe5 100644 --- a/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts +++ b/packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/sqlite.ts @@ -12,95 +12,109 @@ const sqlite3 = { ...commonFns, LEN: 'LENGTH', async CEILING(args) { - return args.knex.raw( - `round(${(await args.fn(args.pt.arguments[0])).builder} + 0.5)${ - args.colAlias - }` - ); + return { + builder: args.knex.raw( + `round(${(await args.fn(args.pt.arguments[0])).builder} + 0.5)${ + args.colAlias + }` + ), + }; }, async FLOOR(args) { - return args.knex.raw( - `round(${(await args.fn(args.pt.arguments[0])).builder} - 0.5)${ - args.colAlias - }` - ); + return { + builder: args.knex.raw( + `round(${(await args.fn(args.pt.arguments[0])).builder} - 0.5)${ + args.colAlias + }` + ), + }; }, MOD: async (args: MapFnArgs) => { - return ( - await args.fn({ - type: 'BinaryExpression', - operator: '%', - left: args.pt.arguments[0], - right: args.pt.arguments[1], - }) - ).builder; + return args.fn({ + type: 'BinaryExpression', + operator: '%', + left: args.pt.arguments[0], + right: args.pt.arguments[1], + }); }, async REPEAT(args: MapFnArgs) { - return args.knex.raw( - `replace(printf('%.' || ${ - (await args.fn(args.pt.arguments[1])).builder - } || 'c', '/'),'/',${(await args.fn(args.pt.arguments[0])).builder})${ - args.colAlias - }` - ); + return { + builder: args.knex.raw( + `replace(printf('%.' || ${ + (await args.fn(args.pt.arguments[1])).builder + } || 'c', '/'),'/',${(await args.fn(args.pt.arguments[0])).builder})${ + args.colAlias + }` + ), + }; }, NOW: 'DATE', SEARCH: 'INSTR', async INT(args: MapFnArgs) { - return args.knex.raw( - `CAST(${(await args.fn(args.pt.arguments[0])).builder} as INTEGER)${ - args.colAlias - }` - ); + return { + builder: args.knex.raw( + `CAST(${(await args.fn(args.pt.arguments[0])).builder} as INTEGER)${ + args.colAlias + }` + ), + }; }, LEFT: async (args: MapFnArgs) => { - return args.knex.raw( - `SUBSTR(${(await args.fn(args.pt.arguments[0])).builder},1,${ - (await args.fn(args.pt.arguments[1])).builder - })${args.colAlias}` - ); + return { + builder: args.knex.raw( + `SUBSTR(${(await args.fn(args.pt.arguments[0])).builder},1,${ + (await args.fn(args.pt.arguments[1])).builder + })${args.colAlias}` + ), + }; }, RIGHT: async (args: MapFnArgs) => { - return args.knex.raw( - `SUBSTR(${(await args.fn(args.pt.arguments[0])).builder},-(${ - (await args.fn(args.pt.arguments[1])).builder - }))${args.colAlias}` - ); + return { + builder: args.knex.raw( + `SUBSTR(${(await args.fn(args.pt.arguments[0])).builder},-(${ + (await args.fn(args.pt.arguments[1])).builder + }))${args.colAlias}` + ), + }; }, MID: 'SUBSTR', FLOAT: async (args: MapFnArgs) => { - return args.knex - .raw( - `CAST(${(await args.fn(args.pt.arguments[0])).builder} as FLOAT)${ - args.colAlias - }` - ) - .wrap('(', ')'); + return { + builder: args.knex + .raw( + `CAST(${(await args.fn(args.pt.arguments[0])).builder} as FLOAT)${ + args.colAlias + }` + ) + .wrap('(', ')'), + }; }, DATEADD: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { const dateIN = (await fn(pt.arguments[1])).builder; - return knex.raw( - `CASE + return { + builder: knex.raw( + `CASE WHEN ${(await fn(pt.arguments[0])).builder} LIKE '%:%' THEN STRFTIME('%Y-%m-%d %H:%M', DATETIME(DATETIME(${fn( pt.arguments[0] )}, 'localtime'), ${dateIN > 0 ? '+' : ''}${ - (await fn(pt.arguments[1])).builder - } || ' ${String((await fn(pt.arguments[2])).builder).replace( - /["']/g, - '' - )}')) + (await fn(pt.arguments[1])).builder + } || ' ${String((await fn(pt.arguments[2])).builder).replace( + /["']/g, + '' + )}')) ELSE DATE(DATETIME(${(await fn(pt.arguments[0])).builder}, 'localtime'), ${dateIN > 0 ? '+' : ''}${ - (await fn(pt.arguments[1])).builder - } || ' ${String((await fn(pt.arguments[2])).builder).replace( - /["']/g, - '' - )}') + (await fn(pt.arguments[1])).builder + } || ' ${String((await fn(pt.arguments[2])).builder).replace( + /["']/g, + '' + )}') END${colAlias}` - ); + ), + }; }, DATETIME_DIFF: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { let datetime_expr1 = (await fn(pt.arguments[0])).builder; @@ -174,54 +188,60 @@ const sqlite3 = { default: sql = ''; } - return knex.raw(`${sql} ${colAlias}`); + return { builder: knex.raw(`${sql} ${colAlias}`) }; }, WEEKDAY: async ({ fn, knex, pt, colAlias }: MapFnArgs) => { // strftime('%w', date) - day of week 0 - 6 with Sunday == 0 // WEEKDAY() returns an index from 0 to 6 for Monday to Sunday - return knex.raw( - `(strftime('%w', ${ - pt.arguments[0].type === 'Literal' - ? `'${dayjs((await fn(pt.arguments[0])).builder).format( - 'YYYY-MM-DD' - )}'` - : (await fn(pt.arguments[0])).builder - }) - 1 - ${getWeekdayByText( - pt?.arguments[1]?.value - )} % 7 + 7) % 7 ${colAlias}` - ); + return { + builder: knex.raw( + `(strftime('%w', ${ + pt.arguments[0].type === 'Literal' + ? `'${dayjs((await fn(pt.arguments[0])).builder).format( + 'YYYY-MM-DD' + )}'` + : (await fn(pt.arguments[0])).builder + }) - 1 - ${getWeekdayByText( + pt?.arguments[1]?.value + )} % 7 + 7) % 7 ${colAlias}` + ), + }; }, AND: async (args: MapFnArgs) => { - return args.knex.raw( - `CASE WHEN ${args.knex - .raw( - `${( - await Promise.all( - args.pt.arguments.map(async (ar) => - (await args.fn(ar, '', 'AND')).builder.toQuery() + return { + builder: args.knex.raw( + `CASE WHEN ${args.knex + .raw( + `${( + await Promise.all( + args.pt.arguments.map(async (ar) => + (await args.fn(ar, '', 'AND')).builder.toQuery() + ) ) - ) - ).join(' AND ')}` - ) - .wrap('(', ')') - .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` - ); + ).join(' AND ')}` + ) + .wrap('(', ')') + .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` + ), + }; }, OR: async (args: MapFnArgs) => { - return args.knex.raw( - `CASE WHEN ${args.knex - .raw( - `${( - await Promise.all( - args.pt.arguments.map(async (ar) => - (await args.fn(ar, '', 'OR')).builder.toQuery() + return { + builder: args.knex.raw( + `CASE WHEN ${args.knex + .raw( + `${( + await Promise.all( + args.pt.arguments.map(async (ar) => + (await args.fn(ar, '', 'OR')).builder.toQuery() + ) ) - ) - ).join(' OR ')}` - ) - .wrap('(', ')') - .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` - ); + ).join(' OR ')}` + ) + .wrap('(', ')') + .toQuery()} THEN 1 ELSE 0 END ${args.colAlias}` + ), + }; }, };