diff --git a/api/src/database/helpers/datetime.ts b/api/src/database/helpers/datetime.ts new file mode 100644 index 0000000000..eec90a6c81 --- /dev/null +++ b/api/src/database/helpers/datetime.ts @@ -0,0 +1,90 @@ +import { Knex } from 'knex'; + +interface IDateTimeHelper { + year(column: string): Knex.Raw; + month(column: string): Knex.Raw; + week(column: string): Knex.Raw; + day(column: string): Knex.Raw; + weekday(column: string): Knex.Raw; + hour(column: string): Knex.Raw; + minute(column: string): Knex.Raw; + second(column: string): Knex.Raw; +} + +class DateTimeHelper implements IDateTimeHelper { + protected knex: Knex; + + constructor(knex: Knex) { + this.knex = knex; + } + + year(column: string): Knex.Raw { + throw new Error(`Method "year" not implemented for dialect ${this.knex.client.constructor.name}`); + } + + month(column: string): Knex.Raw { + throw new Error(`Method "month" not implemented for dialect ${this.knex.client.constructor.name}`); + } + + week(column: string): Knex.Raw { + throw new Error(`Method "week" not implemented for dialect ${this.knex.client.constructor.name}`); + } + + day(column: string): Knex.Raw { + throw new Error(`Method "date" not implemented for dialect ${this.knex.client.constructor.name}`); + } + + weekday(column: string): Knex.Raw { + throw new Error(`Method "weekday" not implemented for dialect ${this.knex.client.constructor.name}`); + } + + hour(column: string): Knex.Raw { + throw new Error(`Method "hour" not implemented for dialect ${this.knex.client.constructor.name}`); + } + + minute(column: string): Knex.Raw { + throw new Error(`Method "minute" not implemented for dialect ${this.knex.client.constructor.name}`); + } + + second(column: string): Knex.Raw { + throw new Error(`Method "second" not implemented for dialect ${this.knex.client.constructor.name}`); + } +} + +export class DateTimeHelperPostgres extends DateTimeHelper { + constructor(knex: Knex) { + super(knex); + } + + year(column: string): Knex.Raw { + return this.knex.raw('EXTRACT(YEAR FROM ??) as ??', [column, `${column}_year`]); + } + + month(column: string): Knex.Raw { + return this.knex.raw('EXTRACT(MONTH FROM ??)', [column]); + } + + week(column: string): Knex.Raw { + return this.knex.raw('EXTRACT(WEEK FROM ??)', [column]); + } + + day(column: string): Knex.Raw { + return this.knex.raw('EXTRACT(DAY FROM ??)', [column]); + } + + weekday(column: string): Knex.Raw { + return this.knex.raw('EXTRACT(DOW FROM ??)', [column]); + } + + hour(column: string): Knex.Raw { + return this.knex.raw('EXTRACT(HOUR FROM ??)', [column]); + } + + minute(column: string): Knex.Raw { + return this.knex.raw('EXTRACT(MINUTE FROM ??)', [column]); + } + + second(column: string): Knex.Raw { + return this.knex.raw('EXTRACT(SECOND FROM ??)', [column]); + } +} diff --git a/api/src/database/helpers/index.ts b/api/src/database/helpers/index.ts new file mode 100644 index 0000000000..36457a1e56 --- /dev/null +++ b/api/src/database/helpers/index.ts @@ -0,0 +1,28 @@ +import { Knex } from 'knex'; + +import { DateTimeHelperPostgres } from './datetime'; + +export function knexTransforms(knex: Knex) { + switch (knex.client.constructor.name) { + // case 'Client_MySQL': + // constructor = require('./dialects/mysql').default; + // break; + case 'Client_PG': + return { + datetime: new DateTimeHelperPostgres(knex), + }; + // case 'Client_SQLite3': + // constructor = require('./dialects/sqlite').default; + // break; + // case 'Client_Oracledb': + // case 'Client_Oracle': + // constructor = require('./dialects/oracledb').default; + // break; + // case 'Client_MSSQL': + // constructor = require('./dialects/mssql').default; + // break; + + default: + throw Error('Unsupported driver used: ' + knex.client.constructor.name); + } +} diff --git a/api/src/utils/apply-query.ts b/api/src/utils/apply-query.ts index 0641315d81..6110f5d846 100644 --- a/api/src/utils/apply-query.ts +++ b/api/src/utils/apply-query.ts @@ -2,7 +2,7 @@ import { Knex } from 'knex'; import { clone, get, isPlainObject, set } from 'lodash'; import { customAlphabet } from 'nanoid'; import validate from 'uuid-validate'; -import { ForbiddenException, InvalidQueryException } from '../exceptions'; +import { InvalidQueryException } from '../exceptions'; import { Aggregate, Filter, Query, Relation, SchemaOverview } from '../types'; import { getRelationType } from './get-relation-type'; diff --git a/api/src/utils/sanitize-query.ts b/api/src/utils/sanitize-query.ts index 7b1e84447f..41f2942b46 100644 --- a/api/src/utils/sanitize-query.ts +++ b/api/src/utils/sanitize-query.ts @@ -1,4 +1,3 @@ -import camelcase from 'camelcase'; import { flatten, get, merge, set } from 'lodash'; import logger from '../logger'; import { Accountability, Aggregate, Filter, Meta, Query, Sort } from '../types';