@ff00ff/mammoth
Advanced tools
Comparing version 1.0.0-rc.4 to 1.0.0-rc.5
@@ -0,3 +1,4 @@ | ||
import { Token } from './tokens'; | ||
import { InternalExpression } from './expression'; | ||
import { Token } from './tokens'; | ||
import { TableDefinition } from './table'; | ||
export interface ColumnDefinition<DataType, IsNotNull extends boolean, HasDefault extends boolean> { | ||
@@ -9,3 +10,3 @@ notNull(): ColumnDefinition<DataType, true, HasDefault>; | ||
unique(): ColumnDefinition<DataType, IsNotNull, HasDefault>; | ||
references<T, ColumnName extends string>(table: T, columnName: ColumnName): ColumnDefinition<DataType, IsNotNull, HasDefault>; | ||
references<T extends TableDefinition<any>, ColumnName extends T extends TableDefinition<infer Columns> ? keyof Columns : never>(table: T, columnName: ColumnName): ColumnDefinition<DataType, IsNotNull, HasDefault>; | ||
} | ||
@@ -17,4 +18,4 @@ export declare const makeColumnDefinition: <DataType, IsNotNull extends boolean, HasDefault extends boolean>(dataType: string) => ColumnDefinition<DataType, IsNotNull, HasDefault>; | ||
/** @internal */ | ||
toTokens(): Token[]; | ||
toTokens(includeAlias?: boolean): Token[]; | ||
} | ||
export declare const makeColumn: <ColumnName, TableName, DataType, IsNotNull extends boolean, HasDefault extends boolean>(columnName: ColumnName, tableName: TableName, originalColumnName: string | undefined) => Column<ColumnName, TableName, DataType, IsNotNull, HasDefault, undefined>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.makeColumn = exports.makeColumnDefinition = void 0; | ||
const tokens_1 = require("./tokens"); | ||
const expression_1 = require("./expression"); | ||
const tokens_1 = require("./tokens"); | ||
// import type { Table } from './table'; | ||
const snake_case_1 = require("./naming/snake-case"); | ||
exports.makeColumnDefinition = (dataType) => { | ||
const makeColumnDefinition = (dataType) => { | ||
return { | ||
@@ -30,17 +30,29 @@ notNull() { | ||
}; | ||
exports.makeColumn = (columnName, tableName, originalColumnName) => { | ||
exports.makeColumnDefinition = makeColumnDefinition; | ||
const makeColumn = (columnName, tableName, originalColumnName) => { | ||
// TODO: either use some sort of AliasToken which we can later strip. Or pass some sort of option | ||
// to the token generation so we can choose if we want named or unnamed. | ||
const snakeCaseColumnName = snake_case_1.toSnakeCase(columnName); | ||
return { | ||
_columnBrand: undefined, | ||
...expression_1.makeExpression((aliasBehaviour) => { | ||
const snakeCaseColumnName = snake_case_1.toSnakeCase(columnName); | ||
if (aliasBehaviour === `INCLUDE`) { | ||
...expression_1.makeExpression(originalColumnName | ||
? [new tokens_1.StringToken(`${tableName}.${snake_case_1.toSnakeCase(originalColumnName)}`)] | ||
: [new tokens_1.StringToken(`${tableName}.${snakeCaseColumnName}`)]), | ||
as(alias) { | ||
return exports.makeColumn(alias, tableName, columnName); | ||
}, | ||
toTokens(includeAlias = false) { | ||
if (includeAlias) { | ||
const snakeCaseColumnName = snake_case_1.toSnakeCase(columnName); | ||
return originalColumnName | ||
? [new tokens_1.StringToken(`${tableName}.${snake_case_1.toSnakeCase(originalColumnName)} "${columnName}"`)] | ||
: [ | ||
snakeCaseColumnName === columnName | ||
? new tokens_1.StringToken(`${tableName}.${snakeCaseColumnName}`) | ||
: new tokens_1.StringToken(`${tableName}.${snakeCaseColumnName} "${columnName}"`), | ||
]; | ||
? [ | ||
new tokens_1.StringToken(`${tableName}.${snake_case_1.toSnakeCase(originalColumnName)}`), | ||
new tokens_1.AliasToken(columnName), | ||
] | ||
: snakeCaseColumnName === columnName | ||
? [new tokens_1.StringToken(`${tableName}.${snakeCaseColumnName}`)] | ||
: [ | ||
new tokens_1.StringToken(`${tableName}.${snakeCaseColumnName}`), | ||
new tokens_1.AliasToken(columnName), | ||
]; | ||
} | ||
@@ -50,17 +62,5 @@ return originalColumnName | ||
: [new tokens_1.StringToken(`${tableName}.${snakeCaseColumnName}`)]; | ||
}), | ||
as(alias) { | ||
return exports.makeColumn(alias, tableName, columnName); | ||
}, | ||
toTokens() { | ||
const snakeCaseColumnName = snake_case_1.toSnakeCase(columnName); | ||
return originalColumnName | ||
? [new tokens_1.StringToken(`${tableName}.${snake_case_1.toSnakeCase(originalColumnName)} "${columnName}"`)] | ||
: [ | ||
snakeCaseColumnName === columnName | ||
? new tokens_1.StringToken(`${tableName}.${snakeCaseColumnName}`) | ||
: new tokens_1.StringToken(`${tableName}.${snakeCaseColumnName} "${columnName}"`), | ||
]; | ||
}, | ||
}; | ||
}; | ||
exports.makeColumn = makeColumn; |
@@ -9,4 +9,4 @@ import { Token } from "./tokens"; | ||
/** @internal */ | ||
toTokens(): Token[]; | ||
toTokens(includeAlias?: boolean): Token[]; | ||
} | ||
export declare const makeCondition: (tokens: Token[]) => Condition; |
@@ -5,18 +5,26 @@ "use strict"; | ||
const tokens_1 = require("./tokens"); | ||
exports.makeCondition = (tokens) => { | ||
const makeCondition = (tokens) => { | ||
const toGroup = (c) => { | ||
const newTokens = c.toTokens(); | ||
// Anything above 3 means we need to start grouping this in ( and ). | ||
if (newTokens.length > 3) { | ||
return new tokens_1.GroupToken(newTokens); | ||
} | ||
return new tokens_1.CollectionToken(newTokens); | ||
}; | ||
return { | ||
or(condition) { | ||
return exports.makeCondition([...tokens, new tokens_1.StringToken(`OR`), ...condition.toTokens()]); | ||
return exports.makeCondition([...tokens, new tokens_1.StringToken(`OR`), toGroup(condition)]); | ||
}, | ||
and(condition) { | ||
return exports.makeCondition([...tokens, new tokens_1.StringToken(`AND`), ...condition.toTokens()]); | ||
return exports.makeCondition([...tokens, new tokens_1.StringToken(`AND`), toGroup(condition)]); | ||
}, | ||
andNotExists(condition) { | ||
return exports.makeCondition([...tokens, new tokens_1.StringToken(`AND NOT EXISTS`), ...condition.toTokens()]); | ||
return exports.makeCondition([...tokens, new tokens_1.StringToken(`AND NOT EXISTS`), toGroup(condition)]); | ||
}, | ||
andExists(condition) { | ||
return exports.makeCondition([...tokens, new tokens_1.StringToken(`AND EXISTS`), ...condition.toTokens()]); | ||
return exports.makeCondition([...tokens, new tokens_1.StringToken(`AND EXISTS`), toGroup(condition)]); | ||
}, | ||
not(condition) { | ||
return exports.makeCondition([...tokens, new tokens_1.StringToken(`NOT`), ...condition.toTokens()]); | ||
return exports.makeCondition([...tokens, new tokens_1.StringToken(`NOT`), toGroup(condition)]); | ||
}, | ||
@@ -28,1 +36,2 @@ toTokens() { | ||
}; | ||
exports.makeCondition = makeCondition; |
@@ -5,19 +5,37 @@ "use strict"; | ||
const column_1 = require("./column"); | ||
exports.dataType = (dataType) => column_1.makeColumnDefinition(dataType); | ||
exports.uuid = () => column_1.makeColumnDefinition(`uuid`); | ||
exports.text = () => column_1.makeColumnDefinition(`text`); | ||
exports.integer = () => column_1.makeColumnDefinition(`integer`); | ||
exports.timestampWithTimeZone = () => column_1.makeColumnDefinition(`timestamp with time zone`); | ||
exports.timestamptz = () => column_1.makeColumnDefinition(`timestamp with time zone`); | ||
exports.citext = () => column_1.makeColumnDefinition(`citext`); | ||
exports.caseInsensitiveText = () => column_1.makeColumnDefinition(`citext`); | ||
exports.decimal = () => column_1.makeColumnDefinition(`decimal`); | ||
exports.serial = () => column_1.makeColumnDefinition(`serial`); | ||
exports.bigserial = () => column_1.makeColumnDefinition(`bigserial`); | ||
exports.smallserial = () => column_1.makeColumnDefinition(`smallserial`); | ||
exports.json = () => column_1.makeColumnDefinition(`json`); | ||
exports.jsonb = () => column_1.makeColumnDefinition(`jsonb`); | ||
exports.timestampWithoutTimeZone = () => column_1.makeColumnDefinition(`timestamp without time zone`); | ||
exports.timestamp = () => column_1.makeColumnDefinition(`timestamp`); | ||
exports.date = () => column_1.makeColumnDefinition(`date`); | ||
exports.time = () => column_1.makeColumnDefinition(`time`); | ||
const dataType = (dataType) => column_1.makeColumnDefinition(dataType); | ||
exports.dataType = dataType; | ||
const uuid = () => column_1.makeColumnDefinition(`uuid`); | ||
exports.uuid = uuid; | ||
const text = () => column_1.makeColumnDefinition(`text`); | ||
exports.text = text; | ||
const integer = () => column_1.makeColumnDefinition(`integer`); | ||
exports.integer = integer; | ||
const timestampWithTimeZone = () => column_1.makeColumnDefinition(`timestamp with time zone`); | ||
exports.timestampWithTimeZone = timestampWithTimeZone; | ||
const timestamptz = () => column_1.makeColumnDefinition(`timestamp with time zone`); | ||
exports.timestamptz = timestamptz; | ||
const citext = () => column_1.makeColumnDefinition(`citext`); | ||
exports.citext = citext; | ||
const caseInsensitiveText = () => column_1.makeColumnDefinition(`citext`); | ||
exports.caseInsensitiveText = caseInsensitiveText; | ||
const decimal = () => column_1.makeColumnDefinition(`decimal`); | ||
exports.decimal = decimal; | ||
const serial = () => column_1.makeColumnDefinition(`serial`); | ||
exports.serial = serial; | ||
const bigserial = () => column_1.makeColumnDefinition(`bigserial`); | ||
exports.bigserial = bigserial; | ||
const smallserial = () => column_1.makeColumnDefinition(`smallserial`); | ||
exports.smallserial = smallserial; | ||
const json = () => column_1.makeColumnDefinition(`json`); | ||
exports.json = json; | ||
const jsonb = () => column_1.makeColumnDefinition(`jsonb`); | ||
exports.jsonb = jsonb; | ||
const timestampWithoutTimeZone = () => column_1.makeColumnDefinition(`timestamp without time zone`); | ||
exports.timestampWithoutTimeZone = timestampWithoutTimeZone; | ||
const timestamp = () => column_1.makeColumnDefinition(`timestamp`); | ||
exports.timestamp = timestamp; | ||
const date = () => column_1.makeColumnDefinition(`date`); | ||
exports.date = date; | ||
const time = () => column_1.makeColumnDefinition(`time`); | ||
exports.time = time; |
@@ -10,3 +10,3 @@ "use strict"; | ||
exports.internalColumnData = new Map(); | ||
exports.getTableData = (table) => { | ||
const getTableData = (table) => { | ||
const tableData = exports.internalTableData.get(table); | ||
@@ -18,3 +18,4 @@ if (!tableData) { | ||
}; | ||
exports.getColumnData = (column) => { | ||
exports.getTableData = getTableData; | ||
const getColumnData = (column) => { | ||
const columnData = exports.internalColumnData.get(column); | ||
@@ -26,1 +27,2 @@ if (!columnData) { | ||
}; | ||
exports.getColumnData = getColumnData; |
@@ -1,9 +0,15 @@ | ||
import { QueryExecutorFn } from "./types"; | ||
export declare const defineDb: (queryExecutor: QueryExecutorFn) => { | ||
select: import("./select").SelectFn; | ||
insertInto: <T extends unknown>(table: T, columnNames?: (T extends import("./table").Table<any, infer Columns> ? (keyof Columns)[] : never) | undefined) => import("./insert").InsertIntoResult<T>; | ||
deleteFrom: <T_1 extends unknown>(table: T_1) => import("./delete").DeleteQuery<T_1, number, T_1 extends import("./table").Table<any, infer Columns_1> ? Columns_1 : never>; | ||
import { Column, ColumnDefinition } from './column'; | ||
import { InsertIntoResult } from './insert'; | ||
import { SelectFn } from './select'; | ||
import { Table, TableDefinition } from './table'; | ||
import { QueryExecutorFn } from './types'; | ||
export declare const defineDb: <TableDefinitions extends { | ||
[key: string]: TableDefinition<any>; | ||
}>(tableDefinitions: TableDefinitions, queryExecutor: QueryExecutorFn) => { | ||
select: SelectFn; | ||
insertInto: <T extends unknown>(table: T, columnNames?: (T extends Table<any, infer Columns> ? (keyof Columns)[] : never) | undefined) => T extends TableDefinition<any> ? never : InsertIntoResult<T>; | ||
deleteFrom: <T_1 extends unknown>(table: T_1) => T_1 extends TableDefinition<any> ? never : import("./delete").DeleteQuery<T_1, number, T_1 extends Table<any, infer Columns_1> ? Columns_1 : never>; | ||
update: <T_2 extends unknown>(table: T_2) => { | ||
set(values: T_2 extends import("./table").Table<any, infer Columns_2> ? { [K in keyof Columns_2]?: (Columns_2[K] extends import("./column").Column<any, any, infer DataType, infer IsNotNull, any, any> ? IsNotNull extends true ? DataType | import("./expression").Expression<DataType, boolean> : DataType | import("./expression").Expression<DataType | undefined, boolean> | undefined : never) | undefined; } : never): import("./update").UpdateQuery<T_2, number, T_2 extends import("./table").Table<any, infer Columns_3> ? Columns_3 : never>; | ||
set(values: T_2 extends Table<any, infer Columns_2> ? { [K in keyof Columns_2]?: (Columns_2[K] extends Column<any, any, infer DataType, infer IsNotNull, any, any> ? IsNotNull extends true ? DataType | import("./expression").Expression<DataType, boolean> : DataType | import("./expression").Expression<DataType | undefined, boolean> | undefined : never) | undefined; } : never): import("./update").UpdateQuery<T_2, number, T_2 extends Table<any, infer Columns_3> ? Columns_3 : never>; | ||
}; | ||
}; | ||
} & { [TableName in keyof TableDefinitions]: TableDefinitions[TableName] extends TableDefinition<infer ColumnDefinitions> ? Table<TableName, { [K_1 in keyof ColumnDefinitions]: Column<K_1, TableName, ColumnDefinitions[K_1] extends ColumnDefinition<infer DataType_1, any, any> ? DataType_1 : never, ColumnDefinitions[K_1] extends ColumnDefinition<any, infer IsNotNull_1, any> ? IsNotNull_1 : never, ColumnDefinitions[K_1] extends ColumnDefinition<any, any, infer HasDefault> ? HasDefault : never, undefined>; }> : never; }; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.defineDb = void 0; | ||
const delete_1 = require("./delete"); | ||
const insert_1 = require("./insert"); | ||
const select_1 = require("./select"); | ||
const table_1 = require("./table"); | ||
const delete_1 = require("./delete"); | ||
const update_1 = require("./update"); | ||
exports.defineDb = (queryExecutor) => { | ||
const snake_case_1 = require("./naming/snake-case"); | ||
const createTables = (tableDefinitions) => { | ||
return Object.keys(tableDefinitions).reduce((tables, key) => { | ||
const tableDefinition = tableDefinitions[key]; | ||
tables[key] = table_1.makeTable(snake_case_1.toSnakeCase(key), undefined, tableDefinition); | ||
return tables; | ||
}, {}); | ||
}; | ||
const defineDb = (tableDefinitions, queryExecutor) => { | ||
return { | ||
@@ -14,3 +23,5 @@ select: select_1.makeSelect(queryExecutor), | ||
update: update_1.makeUpdate(queryExecutor), | ||
...createTables(tableDefinitions), | ||
}; | ||
}; | ||
exports.defineDb = defineDb; |
import { Token } from './tokens'; | ||
import type { GetReturning, QueryExecutorFn, ResultType } from './types'; | ||
import type { Table, TableDefinition } from './table'; | ||
import type { Condition } from './condition'; | ||
import { Query } from './query'; | ||
import type { ResultSet } from './result-set'; | ||
import type { Table } from './table'; | ||
export declare const makeDeleteFrom: (queryExecutor: QueryExecutorFn) => <T extends unknown>(table: T) => DeleteQuery<T, number, T extends Table<any, infer Columns> ? Columns : never>; | ||
export declare const makeDeleteFrom: (queryExecutor: QueryExecutorFn) => <T extends unknown>(table: T) => T extends TableDefinition<any> ? never : DeleteQuery<T, number, T extends Table<any, infer Columns> ? Columns : never>; | ||
export declare class DeleteQuery<T extends Table<any, any>, Returning = number, TableColumns = T extends Table<any, infer Columns> ? Columns : never> extends Query<Returning> { | ||
@@ -9,0 +9,0 @@ private readonly queryExecutor; |
@@ -7,3 +7,3 @@ "use strict"; | ||
const query_1 = require("./query"); | ||
exports.makeDeleteFrom = (queryExecutor) => (table) => { | ||
const makeDeleteFrom = (queryExecutor) => (table) => { | ||
const tableData = data_1.getTableData(table); | ||
@@ -15,2 +15,3 @@ return new DeleteQuery(queryExecutor, table, 'AFFECTED_COUNT', [ | ||
}; | ||
exports.makeDeleteFrom = makeDeleteFrom; | ||
// https://www.postgresql.org/docs/12/sql-delete.html | ||
@@ -29,5 +30,3 @@ class DeleteQuery extends query_1.Query { | ||
.then((result) => onFulfilled | ||
? onFulfilled(this.resultType === `AFFECTED_COUNT` | ||
? result.affectedRowsCount | ||
: result.rows) | ||
? onFulfilled(this.resultType === `AFFECTED_COUNT` ? result.affectedCount : result.rows) | ||
: result) | ||
@@ -34,0 +33,0 @@ .catch(onRejected); |
@@ -15,2 +15,3 @@ import { Condition } from "./condition"; | ||
in(array: DataType[] | Expression<DataType, IsNotNull> | Query<any>): Condition; | ||
notIn(value: DataType[] | Expression<DataType, IsNotNull> | Query<any>): Condition; | ||
plus(value: DataType | Expression<DataType, IsNotNull>): Expression<DataType, IsNotNull>; | ||
@@ -22,11 +23,6 @@ minus(value: DataType | Expression<DataType, IsNotNull>): Expression<DataType, IsNotNull>; | ||
concat(value: DataType | Expression<DataType, IsNotNull>): Expression<DataType, IsNotNull>; | ||
between(a: DataType): { | ||
and(b: DataType): Condition; | ||
}; | ||
betweenSymmetric(a: DataType): { | ||
and(b: DataType): Condition; | ||
}; | ||
between(a: DataType, b: DataType): Condition; | ||
betweenSymmetric(a: DataType, b: DataType): Condition; | ||
isDistinctFrom(a: DataType): Condition; | ||
isNotDistinctFrom(a: DataType): Condition; | ||
notIn(value: DataType[] | Expression<DataType, IsNotNull>): Condition; | ||
like(value: DataType): Condition; | ||
@@ -40,6 +36,7 @@ ilike(value: DataType): Condition; | ||
lte(value: DataType | Expression<DataType, IsNotNull>): Condition; | ||
toTokens(): Token[]; | ||
/** @internal */ | ||
toTokens(includeAlias?: boolean): Token[]; | ||
} | ||
export declare type Expression<DataType, IsNotNull extends boolean> = NamedExpression<'?column?', DataType, IsNotNull>; | ||
export declare const makeNamedExpression: <Name extends string, DataType, IsNotNull extends boolean>(tokenFactory: (aliasBehaviour: 'INCLUDE' | 'EXCLUDE') => Token[]) => NamedExpression<Name, DataType, IsNotNull>; | ||
export declare const makeExpression: <DataType>(tokenFactory: (aliasBehaviour: 'INCLUDE' | 'EXCLUDE') => Token[]) => Expression<DataType, true>; | ||
export declare const makeNamedExpression: <Name extends string, DataType, IsNotNull extends boolean>(tokens: Token[]) => NamedExpression<Name, DataType, IsNotNull>; | ||
export declare const makeExpression: <DataType>(tokens: Token[]) => Expression<DataType, true>; |
@@ -7,4 +7,5 @@ "use strict"; | ||
const query_1 = require("./query"); | ||
exports.makeNamedExpression = (tokenFactory) => exports.makeExpression(tokenFactory); | ||
exports.makeExpression = (tokenFactory) => { | ||
const makeNamedExpression = (tokens) => exports.makeExpression(tokens); | ||
exports.makeNamedExpression = makeNamedExpression; | ||
const makeExpression = (tokens) => { | ||
// | ||
@@ -22,41 +23,24 @@ const getDataTypeTokens = (value) => { | ||
as(name) { | ||
const tokens = tokenFactory('INCLUDE'); | ||
if (tokens.length > 1) { | ||
return exports.makeExpression((aliasBehaviour) => { | ||
if (aliasBehaviour === `INCLUDE`) { | ||
return [new tokens_1.GroupToken(tokens), new tokens_1.StringToken(`"${name}"`)]; | ||
} | ||
return [...tokens]; | ||
}); | ||
if (tokens.length > 2) { | ||
return exports.makeExpression([new tokens_1.GroupToken(tokens), new tokens_1.StringToken(`"${name}"`)]); | ||
} | ||
return exports.makeExpression((aliasBehaviour) => { | ||
if (aliasBehaviour === `INCLUDE`) { | ||
return [...tokens, new tokens_1.StringToken(`"${name}"`)]; | ||
} | ||
return [...tokens]; | ||
}); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`"${name}"`)]); | ||
}, | ||
isNull() { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`IS NULL`)]); | ||
}, | ||
isNotNull() { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`IS NOT NULL`)]); | ||
}, | ||
asc() { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return exports.makeExpression(() => [...tokens, new tokens_1.StringToken(`ASC`)]); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`ASC`)]); | ||
}, | ||
desc() { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return exports.makeExpression(() => [...tokens, new tokens_1.StringToken(`DESC`)]); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`DESC`)]); | ||
}, | ||
nullsFirst() { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return exports.makeExpression(() => [...tokens, new tokens_1.StringToken(`NULLS FIRST`)]); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`NULLS FIRST`)]); | ||
}, | ||
nullsLast() { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return exports.makeExpression(() => [...tokens, new tokens_1.StringToken(`NULLS LAST`)]); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`NULLS LAST`)]); | ||
}, | ||
@@ -67,3 +51,2 @@ // IN ($1, $2, $3) | ||
in(array) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
if (array && ('toTokens' in array || array instanceof query_1.Query)) { | ||
@@ -82,60 +65,60 @@ return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`IN`), new tokens_1.GroupToken(array.toTokens())]); | ||
}, | ||
notIn(array) { | ||
if (array && ('toTokens' in array || array instanceof query_1.Query)) { | ||
return condition_1.makeCondition([ | ||
...tokens, | ||
new tokens_1.StringToken(`NOT IN`), | ||
new tokens_1.GroupToken(array.toTokens()), | ||
]); | ||
} | ||
else { | ||
return condition_1.makeCondition([ | ||
...tokens, | ||
new tokens_1.StringToken(`NOT IN`), | ||
new tokens_1.GroupToken([ | ||
new tokens_1.SeparatorToken(',', array.map((item) => new tokens_1.ParameterToken(item))), | ||
]), | ||
]); | ||
} | ||
}, | ||
plus(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return exports.makeExpression(() => [...tokens, new tokens_1.StringToken(`+`), ...getDataTypeTokens(value)]); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`+`), ...getDataTypeTokens(value)]); | ||
}, | ||
minus(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return exports.makeExpression(() => [...tokens, new tokens_1.StringToken(`-`), ...getDataTypeTokens(value)]); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`-`), ...getDataTypeTokens(value)]); | ||
}, | ||
multiply(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return exports.makeExpression(() => [...tokens, new tokens_1.StringToken(`*`), ...getDataTypeTokens(value)]); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`*`), ...getDataTypeTokens(value)]); | ||
}, | ||
divide(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return exports.makeExpression(() => [...tokens, new tokens_1.StringToken(`/`), ...getDataTypeTokens(value)]); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`/`), ...getDataTypeTokens(value)]); | ||
}, | ||
modulo(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return exports.makeExpression(() => [...tokens, new tokens_1.StringToken(`%`), ...getDataTypeTokens(value)]); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`%`), ...getDataTypeTokens(value)]); | ||
}, | ||
concat(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return exports.makeExpression(() => [...tokens, new tokens_1.StringToken(`||`), ...getDataTypeTokens(value)]); | ||
return exports.makeExpression([...tokens, new tokens_1.StringToken(`||`), ...getDataTypeTokens(value)]); | ||
}, | ||
between(a) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return { | ||
and(b) { | ||
return condition_1.makeCondition([ | ||
...tokens, | ||
new tokens_1.StringToken(`BETWEEN`), | ||
new tokens_1.ParameterToken(a), | ||
new tokens_1.StringToken(`AND`), | ||
new tokens_1.ParameterToken(b), | ||
]); | ||
}, | ||
}; | ||
between(a, b) { | ||
return condition_1.makeCondition([ | ||
...tokens, | ||
new tokens_1.StringToken(`BETWEEN`), | ||
new tokens_1.ParameterToken(a), | ||
new tokens_1.StringToken(`AND`), | ||
new tokens_1.ParameterToken(b), | ||
]); | ||
}, | ||
betweenSymmetric(a) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return { | ||
and(b) { | ||
return condition_1.makeCondition([ | ||
...tokens, | ||
new tokens_1.StringToken(`BETWEEN SYMMETRIC`), | ||
new tokens_1.ParameterToken(a), | ||
new tokens_1.StringToken(`AND`), | ||
new tokens_1.ParameterToken(b), | ||
]); | ||
}, | ||
}; | ||
betweenSymmetric(a, b) { | ||
return condition_1.makeCondition([ | ||
...tokens, | ||
new tokens_1.StringToken(`BETWEEN SYMMETRIC`), | ||
new tokens_1.ParameterToken(a), | ||
new tokens_1.StringToken(`AND`), | ||
new tokens_1.ParameterToken(b), | ||
]); | ||
}, | ||
isDistinctFrom(a) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`IS DISTINCT FROM`), new tokens_1.ParameterToken(a)]); | ||
}, | ||
isNotDistinctFrom(a) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([ | ||
@@ -147,53 +130,27 @@ ...tokens, | ||
}, | ||
notIn(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
if ('toTokens' in value) { | ||
return condition_1.makeCondition([ | ||
...tokens, | ||
new tokens_1.StringToken(`NOT IN`), | ||
new tokens_1.GroupToken(value.toTokens()), | ||
]); | ||
} | ||
else { | ||
return condition_1.makeCondition([ | ||
...tokens, | ||
new tokens_1.StringToken(`NOT IN`), | ||
new tokens_1.GroupToken(value.map((item) => new tokens_1.ParameterToken(item))), | ||
]); | ||
} | ||
}, | ||
like(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`LIKE`), new tokens_1.ParameterToken(value)]); | ||
}, | ||
ilike(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`ILIKE`), new tokens_1.ParameterToken(value)]); | ||
}, | ||
eq(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`=`), ...getDataTypeTokens(value)]); | ||
}, | ||
ne(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`<>`), ...getDataTypeTokens(value)]); | ||
}, | ||
gt(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`>`), ...getDataTypeTokens(value)]); | ||
}, | ||
gte(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`>=`), ...getDataTypeTokens(value)]); | ||
}, | ||
lt(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`<`), ...getDataTypeTokens(value)]); | ||
}, | ||
lte(value) { | ||
const tokens = tokenFactory('EXCLUDE'); | ||
return condition_1.makeCondition([...tokens, new tokens_1.StringToken(`<=`), ...getDataTypeTokens(value)]); | ||
}, | ||
toTokens() { | ||
const tokens = tokenFactory('INCLUDE'); | ||
return tokens; | ||
@@ -203,1 +160,2 @@ }, | ||
}; | ||
exports.makeExpression = makeExpression; |
import { Token } from './tokens'; | ||
import { GetReturning, PickByValue, QueryExecutorFn, ResultType } from './types'; | ||
import { SelectFn } from './select'; | ||
import { Table, TableDefinition } from './table'; | ||
import { Column } from './column'; | ||
@@ -10,3 +11,2 @@ import { Condition } from './condition'; | ||
import { ResultSet } from './result-set'; | ||
import { Table } from './table'; | ||
import { UpdateQuery } from './update'; | ||
@@ -58,6 +58,6 @@ export declare class InsertQuery<T extends Table<any, any>, Returning = number, TableColumns = T extends Table<any, infer Columns> ? Columns : never> extends Query<Returning> { | ||
[K in keyof PickByValue<{ | ||
[K in keyof Columns]: Columns[K] extends Column<any, any, any, infer IsNotNull, infer HasDefault, any> ? HasDefault extends true ? false : IsNotNull : never; | ||
[K in keyof Columns]: Columns[K] extends Column<any, any, any, boolean, infer HasDefault, any> ? HasDefault extends true ? false : false : never; | ||
}, false>]?: Columns[K] extends Column<any, any, infer DataType, any, any, any> ? DataType | undefined : never; | ||
} : never): InsertQuery<T, number>; | ||
} | ||
export declare const makeInsertInto: (queryExecutor: QueryExecutorFn) => <T extends unknown>(table: T, columnNames?: (T extends Table<any, infer Columns> ? (keyof Columns)[] : never) | undefined) => InsertIntoResult<T>; | ||
export declare const makeInsertInto: (queryExecutor: QueryExecutorFn) => <T extends unknown>(table: T, columnNames?: (T extends Table<any, infer Columns> ? (keyof Columns)[] : never) | undefined) => T extends TableDefinition<any> ? never : InsertIntoResult<T>; |
@@ -23,3 +23,3 @@ "use strict"; | ||
.then((result) => onFulfilled | ||
? onFulfilled(this.resultType === `AFFECTED_COUNT` ? result.affectedRowsCount : result.rows) | ||
? onFulfilled(this.resultType === `AFFECTED_COUNT` ? result.affectedCount : result.rows) | ||
: result) | ||
@@ -156,3 +156,3 @@ .catch(onRejected); | ||
exports.InsertQuery = InsertQuery; | ||
exports.makeInsertInto = (queryExecutor) => (table, columnNames) => { | ||
const makeInsertInto = (queryExecutor) => (table, columnNames) => { | ||
const insertTableData = data_1.getTableData(table); | ||
@@ -259,1 +259,2 @@ return { | ||
}; | ||
exports.makeInsertInto = makeInsertInto; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.toSnakeCase = void 0; | ||
exports.toSnakeCase = (string) => string | ||
const toSnakeCase = (string) => string | ||
.replace(/\W+/g, ' ') | ||
@@ -9,1 +9,2 @@ .split(/ |\B(?=[A-Z])/) | ||
.join('_'); | ||
exports.toSnakeCase = toSnakeCase; |
@@ -5,3 +5,3 @@ import { Token } from "./tokens"; | ||
/** @internal */ | ||
abstract toTokens(): Token[]; | ||
abstract toTokens(includeAlias?: boolean): Token[]; | ||
} |
import { Token } from './tokens'; | ||
import { Expression, NamedExpression } from './expression'; | ||
import { Table, TableDefinition } from './table'; | ||
import { Column } from './column'; | ||
@@ -8,3 +9,2 @@ import { Condition } from './condition'; | ||
import { ResultSet } from './result-set'; | ||
import { Table } from './table'; | ||
declare type ToJoinType<JoinType, NewJoinType extends 'left-join' | 'left-side-of-right-join' | 'full-join'> = Extract<JoinType, 'left-side-of-right-join'> extends never ? NewJoinType : JoinType; | ||
@@ -33,3 +33,3 @@ declare type GetTableName<T extends Table<any, any>> = T extends Table<infer A, object> ? A : never; | ||
then(onFulfilled?: ((value: ResultSet<SelectQuery<Columns>, false>[]) => any | PromiseLike<any>) | undefined | null, onRejected?: ((reason: any) => void | PromiseLike<void>) | undefined | null): Promise<any>; | ||
from<T extends Table<any, any>>(fromItem: T): SelectQuery<Columns>; | ||
from<T extends Table<any, any>>(fromItem: T): T extends TableDefinition<any> ? never : SelectQuery<Columns>; | ||
join(table: Table<any, any>): SelectQuery<Columns>; | ||
@@ -36,0 +36,0 @@ innerJoin(table: Table<any, any>): SelectQuery<Columns>; |
@@ -227,3 +227,3 @@ "use strict"; | ||
exports.SelectQuery = SelectQuery; | ||
exports.makeSelect = (queryExecutor, initialTokens) => (...columns) => { | ||
const makeSelect = (queryExecutor, initialTokens) => (...columns) => { | ||
return new SelectQuery(queryExecutor, [ | ||
@@ -233,14 +233,10 @@ ...(initialTokens || []), | ||
new tokens_1.SeparatorToken(`,`, columns.map((column) => { | ||
const tokens = column.toTokens(); | ||
// TODO: this is just in case we select a query e.g. select(foo.id, select(foo.value).from(foo)).from(foo) | ||
// as the subquery needs a group around it. If this has any weird side effects of adding a | ||
// group around an expression which is not neccesary or even breaking we should consider | ||
// letting the group happen in user land instead OR we could start inspecting the tokens but | ||
// rather not start doing that. | ||
if (tokens.length > 1) { | ||
const tokens = column.toTokens(true); | ||
if (column instanceof query_1.Query) { | ||
return new tokens_1.GroupToken(tokens); | ||
} | ||
return tokens[0]; | ||
return new tokens_1.CollectionToken(tokens); | ||
})), | ||
]); | ||
}; | ||
exports.makeSelect = makeSelect; |
@@ -1,3 +0,4 @@ | ||
import { Condition } from "./condition"; | ||
import { Expression, NamedExpression } from "./expression"; | ||
import { Condition } from './condition'; | ||
import { Expression, NamedExpression } from './expression'; | ||
export declare const any: <T>(array: T[]) => Expression<T, true>; | ||
export declare const now: () => Expression<Date, true>; | ||
@@ -9,2 +10,5 @@ export declare const count: (expression?: Expression<any, any> | undefined) => NamedExpression<'count', string, true>; | ||
export declare const sum: <DataType, IsNotNull extends boolean>(expression: Expression<DataType, IsNotNull>) => NamedExpression<"sum", DataType, IsNotNull>; | ||
export declare const not: (condition: Condition) => Condition; | ||
export declare const and: (condition: Condition) => Condition; | ||
export declare const or: (condition: Condition) => Condition; | ||
export declare const group: (condition: Condition) => Condition; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.group = exports.sum = exports.avg = exports.max = exports.min = exports.count = exports.now = void 0; | ||
exports.group = exports.or = exports.and = exports.not = exports.sum = exports.avg = exports.max = exports.min = exports.count = exports.now = exports.any = void 0; | ||
const condition_1 = require("./condition"); | ||
const expression_1 = require("./expression"); | ||
const tokens_1 = require("./tokens"); | ||
exports.now = () => expression_1.makeExpression(() => [new tokens_1.StringToken(`NOW()`)]); | ||
exports.count = (expression) => expression | ||
? expression_1.makeNamedExpression(() => [new tokens_1.StringToken(`COUNT`), new tokens_1.GroupToken(expression.toTokens())]) | ||
: expression_1.makeNamedExpression(() => [new tokens_1.StringToken(`COUNT(*)`)]); | ||
exports.min = (expression) => expression_1.makeNamedExpression(() => [ | ||
const any = (array) => expression_1.makeExpression([new tokens_1.StringToken(`ANY`), new tokens_1.GroupToken([new tokens_1.ParameterToken(array)])]); | ||
exports.any = any; | ||
const now = () => expression_1.makeExpression([new tokens_1.StringToken(`NOW()`)]); | ||
exports.now = now; | ||
const count = (expression) => { | ||
if (!expression) { | ||
return expression_1.makeNamedExpression([new tokens_1.StringToken(`COUNT(*)`)]); | ||
} | ||
const tokens = expression.toTokens(false); | ||
return expression_1.makeNamedExpression([new tokens_1.StringToken(`COUNT`), new tokens_1.GroupToken(tokens)]); | ||
}; | ||
exports.count = count; | ||
const min = (expression) => expression_1.makeNamedExpression([ | ||
new tokens_1.StringToken(`MIN`), | ||
new tokens_1.GroupToken(expression.toTokens()), | ||
]); | ||
exports.max = (expression) => expression_1.makeNamedExpression(() => [ | ||
exports.min = min; | ||
const max = (expression) => expression_1.makeNamedExpression([ | ||
new tokens_1.StringToken(`MAX`), | ||
new tokens_1.GroupToken(expression.toTokens()), | ||
]); | ||
exports.avg = (expression) => expression_1.makeNamedExpression(() => [ | ||
exports.max = max; | ||
const avg = (expression) => expression_1.makeNamedExpression([ | ||
new tokens_1.StringToken(`AVG`), | ||
new tokens_1.GroupToken(expression.toTokens()), | ||
]); | ||
exports.sum = (expression) => expression_1.makeNamedExpression(() => [ | ||
exports.avg = avg; | ||
const sum = (expression) => expression_1.makeNamedExpression([ | ||
new tokens_1.StringToken(`SUM`), | ||
new tokens_1.GroupToken(expression.toTokens()), | ||
]); | ||
exports.group = (condition) => condition_1.makeCondition([new tokens_1.GroupToken(condition.toTokens())]); | ||
exports.sum = sum; | ||
const not = (condition) => condition_1.makeCondition([new tokens_1.StringToken(`NOT`), new tokens_1.GroupToken(condition.toTokens())]); | ||
exports.not = not; | ||
const and = (condition) => condition_1.makeCondition([new tokens_1.StringToken(`AND`), new tokens_1.GroupToken(condition.toTokens())]); | ||
exports.and = and; | ||
const or = (condition) => condition_1.makeCondition([new tokens_1.StringToken(`OR`), new tokens_1.GroupToken(condition.toTokens())]); | ||
exports.or = or; | ||
const group = (condition) => condition_1.makeCondition([new tokens_1.GroupToken(condition.toTokens())]); | ||
exports.group = group; |
import { Column, ColumnDefinition } from './column'; | ||
export declare type Table<TableName, Columns> = InternalTable<TableName, Columns> & Columns; | ||
export declare class TableDefinition<Columns> { | ||
private _tableDefinitionBrand; | ||
} | ||
export declare type Table<TableName, Columns> = Columns & InternalTable<TableName, Columns>; | ||
interface InternalTable<TableName, Columns> { | ||
@@ -8,5 +11,10 @@ as<T>(alias: T): Table<T, { | ||
} | ||
export declare const defineTable: <T extends { | ||
export declare const makeTable: <TableName extends string, TableDefinition_1 extends { | ||
[column: string]: ColumnDefinition<any, any, any>; | ||
}, TableName extends string>(tableName: TableName, tableDefinition: T) => Table<TableName, { [K in keyof T]: Column<K, TableName, T[K] extends ColumnDefinition<infer DataType, any, any> ? DataType : never, T[K] extends ColumnDefinition<any, infer IsNotNull, any> ? IsNotNull : never, T[K] extends ColumnDefinition<any, any, infer HasDefault> ? HasDefault : never, undefined>; }>; | ||
}>(tableName: TableName, originalTableName: string | undefined, tableDefinition: TableDefinition_1) => { [K in keyof TableDefinition_1]: Column<K, TableName, TableDefinition_1[K] extends ColumnDefinition<infer DataType, any, any> ? DataType : never, TableDefinition_1[K] extends ColumnDefinition<any, infer IsNotNull, any> ? IsNotNull : never, TableDefinition_1[K] extends ColumnDefinition<any, any, infer HasDefault> ? HasDefault : never, undefined>; } & { | ||
as<T extends string>(alias: T): any; | ||
}; | ||
export declare const defineTable: <Columns extends { | ||
[column: string]: ColumnDefinition<any, any, any>; | ||
}>(tableDefinition: Columns) => TableDefinition<Columns>; | ||
export {}; |
"use strict"; | ||
// type InternalTab<TableDefinitionName> = Nominal<TableDefinitionName>; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.defineTable = void 0; | ||
exports.defineTable = exports.makeTable = exports.TableDefinition = void 0; | ||
const column_1 = require("./column"); | ||
const data_1 = require("./data"); | ||
const snake_case_1 = require("./naming/snake-case"); | ||
class TableDefinition { | ||
} | ||
exports.TableDefinition = TableDefinition; | ||
const makeTable = (tableName, originalTableName, tableDefinition) => { | ||
@@ -21,3 +24,3 @@ const columnNames = Object.keys(tableDefinition); | ||
as(alias) { | ||
return makeTable(alias, tableName, tableDefinition); | ||
return exports.makeTable(alias, tableName, tableDefinition); | ||
}, | ||
@@ -31,4 +34,6 @@ }; | ||
}; | ||
exports.defineTable = (tableName, tableDefinition) => { | ||
return makeTable(tableName, undefined, tableDefinition); | ||
exports.makeTable = makeTable; | ||
const defineTable = (tableDefinition) => { | ||
return tableDefinition; | ||
}; | ||
exports.defineTable = defineTable; |
@@ -0,1 +1,2 @@ | ||
export * from './alias-token'; | ||
export * from './collection-token'; | ||
@@ -2,0 +3,0 @@ export * from './empty-token'; |
@@ -13,2 +13,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
__exportStar(require("./alias-token"), exports); | ||
__exportStar(require("./collection-token"), exports); | ||
@@ -15,0 +16,0 @@ __exportStar(require("./empty-token"), exports); |
@@ -7,3 +7,3 @@ "use strict"; | ||
exports.Token = Token; | ||
exports.createQueryState = (tokens, currentParameterIndex = 0) => { | ||
const createQueryState = (tokens, currentParameterIndex = 0) => { | ||
const initialState = { | ||
@@ -15,1 +15,2 @@ text: [], | ||
}; | ||
exports.createQueryState = createQueryState; |
@@ -13,3 +13,3 @@ export declare type ResultType = 'ROWS' | 'AFFECTED_COUNT'; | ||
rows: any[]; | ||
affectedRowsCount: number; | ||
affectedCount: number; | ||
}>; |
@@ -20,3 +20,3 @@ "use strict"; | ||
.then((result) => onFulfilled | ||
? onFulfilled(this.resultType === `AFFECTED_COUNT` ? result.affectedRowsCount : result.rows) | ||
? onFulfilled(this.resultType === `AFFECTED_COUNT` ? result.affectedCount : result.rows) | ||
: result) | ||
@@ -68,3 +68,3 @@ .catch(onRejected); | ||
exports.UpdateQuery = UpdateQuery; | ||
exports.makeUpdate = (queryExecutor) => (table) => { | ||
const makeUpdate = (queryExecutor) => (table) => { | ||
// | ||
@@ -94,1 +94,2 @@ return { | ||
}; | ||
exports.makeUpdate = makeUpdate; |
{ | ||
"name": "@ff00ff/mammoth", | ||
"license": "MIT", | ||
"version": "1.0.0-rc.4", | ||
"version": "1.0.0-rc.5", | ||
"main": "./.build/index.js", | ||
@@ -26,3 +26,3 @@ "types": "./.build/index.d.ts", | ||
"prettier": "^2.1.2", | ||
"ts-jest": "^26.4.0", | ||
"ts-jest": "^26.4.1", | ||
"typescript": "^4.0.3" | ||
@@ -29,0 +29,0 @@ }, |
@@ -1,6 +0,4 @@ | ||
> This is `mammoth@next` which just had a major revamp. I'm about to publish a blog post with some more info. This will move to master soon. | ||
![Mammoth](https://s3-eu-west-1.amazonaws.com/mammoth-static.ff00ff.nl/mammoth-logo.png) | ||
# Mammoth: A type-safe Postgres query builder pur sang for TypeScript. | ||
# Mammoth: A type-safe Postgres query builder pur sang for TypeScript | ||
@@ -12,3 +10,3 @@ [![Build Status](https://img.shields.io/endpoint.svg?url=https%3A%2F%2Factions-badge.atrox.dev%2Fff00ff%2Fmammoth%2Fbadge%3Fref%3Dmaster&style=flat)](https://actions-badge.atrox.dev/ff00ff/mammoth/goto?ref=master) | ||
``` | ||
npm i @ff00ff/mammoth@1.0.0-rc.1 | ||
npm i @ff00ff/mammoth@1.0.0-rc.4 | ||
``` | ||
@@ -123,3 +121,3 @@ | ||
To | ||
You have to define all the tables to make sure Mammoth understands the type information. This should be close to the CREATE TABLE syntax. | ||
@@ -199,2 +197,4 @@ ```ts | ||
This is a list of all the data types and it's companioning data type function. | ||
| Function | SQL data type | | ||
@@ -201,0 +201,0 @@ | -------------------------- | --------------------------- | |
113926
59
1863