import {SortFourTables} from './sort_four_tables' import {FilterFourTables} from './filter_four_tables' import {GroupFourTables} from './group_four_tables' import {EnforceNonEmptyRecord, ValueOrNestedValueRecord, ValueRecord} from '../../record' import {Value} from '../../value' import {Subtable} from '../subtable' import {Table} from '../one/table' import { averageColumn, countRows, maximizeColumn, minimizeColumn, SelectScalar, sumColumn } from '../selection/select_scalar' import {mapTable, mapTableWithSubquery, SelectRows} from '../selection/select_rows' import {getColumn, SelectVector} from '../selection/select_vector' import {AggregatableTable} from '../aggregatable_table' import { addAscendingOrder, addDescendingOrder, addParameterizedFilter, addParameterlessFilter, joinTable, SelectStatement } from '../../statements/select_statement' import {groupTablesBy} from '../../statements/group_select_statement' import {JoinFifthTable} from '../five/join_fifth_table' import {aggregateTables, SelectGuaranteedSingleRow} from '../selection/select_guaranteed_single_row' import {selectSetsOfRows, SelectSetsOfRows} from '../selection/select_sets_of_rows' export class JoinFourthTable { constructor( private readonly statement: SelectStatement) {} filter(predicate: (first: T1, second: T2, third: T3, fourth: T4) => boolean): FilterFourTables filter

(provided: P, predicate: (parameters: P, first: T1, second: T2, third: T3, fourth: T4) => boolean): FilterFourTables filter

(predicateOrProvided: ((first: T1, second: T2, third: T3, fourth: T4) => boolean)|P, predicate?: (parameters: P, first: T1, second: T2, third: T3, fourth: T4) => boolean): FilterFourTables { return new FilterFourTables( typeof predicateOrProvided === 'function' ? addParameterlessFilter(this.statement, predicateOrProvided) : addParameterizedFilter(this.statement, predicate!, predicateOrProvided), ) } sortBy(sortBy: (first: T1, second: T2, third: T3, fourth: T4) => Value): SortFourTables { return new SortFourTables( addAscendingOrder(this.statement, sortBy)) } sortDescendinglyBy(sortBy: (first: T1, second: T2, third: T3, fourth: T4) => Value): SortFourTables { return new SortFourTables( addDescendingOrder(this.statement, sortBy)) } join(otherTable: Table, left: (firstTable: T1, secondTable: T2, thirdTable: T3, fourthTable: T4) => K, right: (thirdTable: U) => K): JoinFifthTable { return new JoinFifthTable( joinTable(this.statement, otherTable, left, right)) } select(firstName: string, secondName: string, thirdName: string, fourthName: string): SelectSetsOfRows<{ [first in K]: T1 } & { [second in K]: T2 } & { [third in K]: T3 } & { [fourth in K]: T4 } > { return selectSetsOfRows( this.statement, [ firstName, secondName, thirdName, fourthName ]) } map(f: (first: T1, second: T2, third: T3, fourth: T4) => EnforceNonEmptyRecord & U): SelectRows map(tableInSubquery: Table, f: (s: Subtable, first: T1, second: T2, third: T3, fourth: T4) => EnforceNonEmptyRecord & U): SelectRows map(fOrTableInSubquery: ((first: T1, second: T2, third: T3, fourth: T4) => EnforceNonEmptyRecord & U)|Table, f?: (s: Subtable, first: T1, second: T2, third: T3, fourth: T4) => EnforceNonEmptyRecord & U): SelectRows{ return typeof fOrTableInSubquery === 'function' ? mapTable(this.statement, fOrTableInSubquery) : mapTableWithSubquery(this.statement, f!, fOrTableInSubquery) } get(f: (first: T1, second: T2, third: T3, fourth: T4) => U): SelectVector { return getColumn(this.statement, f) } count(): SelectScalar { return countRows(this.statement) } max(f: (first: T1, second: T2, third: T3, fourth: T4) => V): SelectScalar { return maximizeColumn(this.statement, f) } min(f: (first: T1, second: T2, third: T3, fourth: T4) => V): SelectScalar { return minimizeColumn(this.statement, f) } sum(f: (first: T1, second: T2, third: T3, fourth: T4) => V): SelectScalar { return sumColumn(this.statement, f) } average(f: (first: T1, second: T2, third: T3, fourth: T4) => V): SelectScalar { return averageColumn(this.statement, f) } aggregate( aggregation: (first: AggregatableTable, second: AggregatableTable, third: AggregatableTable, fourth: AggregatableTable, count: () => number) => EnforceNonEmptyRecord & A): SelectGuaranteedSingleRow { return aggregateTables(this.statement, aggregation) } groupBy(getKey: (first: T1, second: T2, third: T3, fourth: T4) => EnforceNonEmptyRecord & K) : GroupFourTables{ return new GroupFourTables(groupTablesBy(this.statement, getKey)) } }