Add fields support for date functions

This commit is contained in:
rijkvanzanten
2021-06-16 16:35:27 -04:00
parent d52f27339c
commit 81ba81a276
6 changed files with 93 additions and 31 deletions

View File

@@ -1,12 +1,12 @@
import { Knex } from 'knex';
export interface IBaseHelper {
year(table: string, column: string): Knex.Raw;
month(table: string, column: string): Knex.Raw;
week(table: string, column: string): Knex.Raw;
day(table: string, column: string): Knex.Raw;
weekday(table: string, column: string): Knex.Raw;
hour(table: string, column: string): Knex.Raw;
minute(table: string, column: string): Knex.Raw;
second(table: string, column: string): Knex.Raw;
export interface HelperFn {
year(table: string, column: string, alias?: string): Knex.Raw;
month(table: string, column: string, alias?: string): Knex.Raw;
week(table: string, column: string, alias?: string): Knex.Raw;
day(table: string, column: string, alias?: string): Knex.Raw;
weekday(table: string, column: string, alias?: string): Knex.Raw;
hour(table: string, column: string, alias?: string): Knex.Raw;
minute(table: string, column: string, alias?: string): Knex.Raw;
second(table: string, column: string, alias?: string): Knex.Raw;
}

View File

@@ -1,42 +1,74 @@
import { Knex } from 'knex';
import { IBaseHelper } from '../base';
import { HelperFn } from '../base';
export class HelperPostgres implements IBaseHelper {
export class HelperPostgres implements HelperFn {
private knex: Knex;
constructor(knex: Knex) {
this.knex = knex;
}
year(table: string, column: string): Knex.Raw {
return this.knex.raw('EXTRACT(YEAR FROM ??.??) as ??', [table, column, `${column}_year`]);
year(table: string, column: string, alias?: string): Knex.Raw {
if (alias) {
return this.knex.raw('EXTRACT(YEAR FROM ??.??) as ??', [table, column, alias]);
}
return this.knex.raw('EXTRACT(YEAR FROM ??.??)', [table, column]);
}
month(table: string, column: string): Knex.Raw {
return this.knex.raw('EXTRACT(MONTH FROM ??)', [column]);
month(table: string, column: string, alias?: string): Knex.Raw {
if (alias) {
return this.knex.raw('EXTRACT(MONTH FROM ??.??) as ??', [table, column, alias]);
}
return this.knex.raw('EXTRACT(MONTH FROM ??.??)', [table, column]);
}
week(table: string, column: string): Knex.Raw {
return this.knex.raw('EXTRACT(WEEK FROM ??)', [column]);
week(table: string, column: string, alias?: string): Knex.Raw {
if (alias) {
return this.knex.raw('EXTRACT(WEEK FROM ??.??) as ??', [table, column, alias]);
}
return this.knex.raw('EXTRACT(WEEK FROM ??.??)', [table, column]);
}
day(table: string, column: string): Knex.Raw {
return this.knex.raw('EXTRACT(DAY FROM ??)', [column]);
day(table: string, column: string, alias?: string): Knex.Raw {
if (alias) {
return this.knex.raw('EXTRACT(DAY FROM ??.??) as ??', [table, column, alias]);
}
return this.knex.raw('EXTRACT(DAY FROM ??.??)', [table, column]);
}
weekday(table: string, column: string): Knex.Raw {
return this.knex.raw('EXTRACT(DOW FROM ??)', [column]);
weekday(table: string, column: string, alias?: string): Knex.Raw {
if (alias) {
return this.knex.raw('EXTRACT(DOW FROM ??.??) as ??', [table, column, alias]);
}
return this.knex.raw('EXTRACT(DOW FROM ??.??)', [table, column]);
}
hour(table: string, column: string): Knex.Raw {
return this.knex.raw('EXTRACT(HOUR FROM ??)', [column]);
hour(table: string, column: string, alias?: string): Knex.Raw {
if (alias) {
return this.knex.raw('EXTRACT(HOUR FROM ??.??) as ??', [table, column, alias]);
}
return this.knex.raw('EXTRACT(HOUR FROM ??.??)', [table, column]);
}
minute(table: string, column: string): Knex.Raw {
return this.knex.raw('EXTRACT(MINUTE FROM ??)', [column]);
minute(table: string, column: string, alias?: string): Knex.Raw {
if (alias) {
return this.knex.raw('EXTRACT(MINUTE FROM ??.??) as ??', [table, column, alias]);
}
return this.knex.raw('EXTRACT(MINUTE FROM ??.??)', [table, column]);
}
second(table: string, column: string): Knex.Raw {
return this.knex.raw('EXTRACT(SECOND FROM ??)', [column]);
second(table: string, column: string, alias?: string): Knex.Raw {
if (alias) {
return this.knex.raw('EXTRACT(SECOND FROM ??.??) as ??', [table, column, alias]);
}
return this.knex.raw('EXTRACT(SECOND FROM ??.??)', [table, column]);
}
}

View File

@@ -3,6 +3,7 @@ import { clone, cloneDeep, pick, uniq } from 'lodash';
import { PayloadService } from '../services/payload';
import { Item, Query, SchemaOverview } from '../types';
import { AST, FieldNode, NestedCollectionNode } from '../types/ast';
import { applyFunctionToColumnName } from '../utils/apply-function-to-column-name';
import applyQuery from '../utils/apply-query';
import { getColumn } from '../utils/get-column';
import { stripFunction } from '../utils/strip-function';
@@ -419,7 +420,9 @@ function removeTemporaryFields(
);
}
item = fields.length > 0 ? pick(rawItem, fields) : rawItem[primaryKeyField];
const fieldsWithFunctionsApplied = fields.map((field) => applyFunctionToColumnName(field));
item = fields.length > 0 ? pick(rawItem, fieldsWithFunctionsApplied) : rawItem[primaryKeyField];
items.push(item);
}

View File

@@ -0,0 +1,22 @@
import { REGEX_BETWEEN_PARENS } from '../constants';
/**
* Takes in a column name, and transforms the original name with the generated column name based on
* the applied function.
*
* @example
*
* ```js
* applyFunctionToColumnName('year(date_created)');
* // => "date_created_year"
* ```
*/
export function applyFunctionToColumnName(column: string): string {
if (column.includes('(') && column.includes(')')) {
const functionName = column.split('(')[0];
const columnName = column.match(REGEX_BETWEEN_PARENS)![1];
return `${columnName}_${functionName}`;
} else {
return column;
}
}

View File

@@ -1,6 +1,7 @@
import { Knex } from 'knex';
import { FunctionsHelper } from '../database/functions';
import { REGEX_BETWEEN_PARENS } from '../constants';
import { applyFunctionToColumnName } from './apply-function-to-column-name';
/**
* Return column prefixed by table. If column includes functions (like `year(date_created)`, the
@@ -9,9 +10,10 @@ import { REGEX_BETWEEN_PARENS } from '../constants';
* @param knex Current knex / transaction instance
* @param collection Collection or alias in which column resides
* @param field name of the column
* @param alias Whether or not to add a SQL AS statement
* @returns Knex raw instance
*/
export function getColumn(knex: Knex, table: string, column: string): Knex.Raw {
export function getColumn(knex: Knex, table: string, column: string, alias = true): Knex.Raw {
const fn = FunctionsHelper(knex);
if (column.includes('(') && column.includes(')')) {
@@ -19,7 +21,11 @@ export function getColumn(knex: Knex, table: string, column: string): Knex.Raw {
const columnName = column.match(REGEX_BETWEEN_PARENS)![1];
if (functionName in fn) {
return fn[functionName as keyof typeof fn](table, columnName);
return fn[functionName as keyof typeof fn](
table,
columnName,
alias ? applyFunctionToColumnName(column) : undefined
);
} else {
throw new Error(`Invalid function specified "${functionName}"`);
}

View File

@@ -5,7 +5,6 @@ import { REGEX_BETWEEN_PARENS } from '../constants';
*/
export function stripFunction(field: string): string {
if (field.includes('(') && field.includes(')')) {
console.log(field.match(REGEX_BETWEEN_PARENS));
return field.match(REGEX_BETWEEN_PARENS)![1].trim();
} else {
return field;