kysely-mapper
Advanced tools
Comparing version 0.2.3 to 0.2.4
@@ -5,4 +5,6 @@ /** | ||
*/ | ||
import { ComparisonOperatorExpression, Expression, ExtractTypeFromStringReference, Kysely, OperandValueExpressionOrList, ReferenceExpression, SelectType, WhereExpressionFactory, WhereInterface } from 'kysely'; | ||
import { ComparisonOperatorExpression, Expression, ExtractTypeFromStringReference, Kysely, OperandValueExpressionOrList, ReferenceExpression, SelectType, Selectable, WhereExpressionFactory, WhereInterface } from 'kysely'; | ||
import { KeyTuple, SelectableColumnTuple } from './type-utils'; | ||
type AnyWhereInterface = WhereInterface<any, any>; | ||
type KeyColumnType<DB, TB extends keyof DB, K extends keyof Selectable<DB[TB]> & string> = NonNullable<Selectable<DB[TB]>[K]>; | ||
/** | ||
@@ -12,12 +14,4 @@ * Type of the query filter object, which can be passed as an argument | ||
*/ | ||
export type QueryFilter<DB, TB extends keyof DB & string, RE extends ReferenceExpression<DB, TB>, QB1 extends AnyWhereInterface, QB2 extends AnyWhereInterface> = BinaryOperationFilter<DB, TB, RE> | FieldMatchingFilter<DB, TB, RE> | QueryModifier<QB1, QB2> | WhereExpressionFactory<DB, TB> | Expression<any>; | ||
export type QueryFilter<DB, TB extends keyof DB & string, KeyColumns extends SelectableColumnTuple<DB[TB]> | [], RE extends ReferenceExpression<DB, TB>> = (KeyColumns extends [string] ? KeyColumnType<DB, TB, KeyColumns[0]> : never) | (KeyColumns extends [] ? never : Readonly<KeyTuple<DB[TB], KeyColumns>>) | FieldMatchingFilter<DB, TB, RE> | WhereExpressionFactory<DB, TB> | Expression<any>; | ||
/** | ||
* A filter that is a binary operation, such as `eq` or `gt`. | ||
*/ | ||
export type BinaryOperationFilter<DB, TB extends keyof DB & string, RE extends ReferenceExpression<DB, TB>> = [ | ||
lhs: RE, | ||
op: ComparisonOperatorExpression, | ||
rhs: OperandValueExpressionOrList<DB, TB, RE> | ||
]; | ||
/** | ||
* A filter that matches columns against the fields of an object. | ||
@@ -29,19 +23,14 @@ */ | ||
/** | ||
* A filter that is a function that takes a query builder and returns | ||
* a caller-modified query builder. | ||
*/ | ||
export declare class QueryModifier<QB1 extends AnyWhereInterface, QB2 extends AnyWhereInterface> { | ||
readonly modifier: (qb: QB1) => QB2; | ||
constructor(modifier: (qb: QB1) => QB2); | ||
} | ||
/** | ||
* Returns a query builder that constrains the provided query builder | ||
* according to the provided query filter. | ||
* according to the provided query filter or binary operation. | ||
* @param base The Kysely mapper that is used to create references. | ||
* @param qb The query builder to constrain. | ||
* @param filter The query filter. | ||
* @returns A query builder constrained for the provided query filter. | ||
* @param filterOrLHS The query filter or left-hand side of a binary operation. | ||
* @param op The operator of a binary operation. | ||
* @param rhs The right-hand side of a binary operation. | ||
* @returns A query builder constrained for the provided query filter | ||
* or binary operation. | ||
*/ | ||
export declare function applyQueryFilter<DB, TB extends keyof DB & string, QB1 extends AnyWhereInterface, QB2 extends AnyWhereInterface, RE extends ReferenceExpression<DB, TB>>(db: Kysely<DB>, qb: QB1, filter: QueryFilter<DB, TB, RE, QB1, QB2>): QB2; | ||
export declare function applyQueryFilter<DB, TB extends keyof DB & string, KeyColumns extends SelectableColumnTuple<DB[TB]> | [], QB extends AnyWhereInterface, RE extends ReferenceExpression<DB, TB>>(db: Kysely<DB>, qb: QB, keyColumns: KeyColumns, filterOrLHS: QueryFilter<DB, TB, KeyColumns, RE> | RE, op?: ComparisonOperatorExpression, rhs?: OperandValueExpressionOrList<DB, TB, RE>): QB; | ||
export {}; | ||
//# sourceMappingURL=query-filter.d.ts.map |
@@ -7,22 +7,41 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.applyQueryFilter = exports.QueryModifier = void 0; | ||
exports.applyQueryFilter = void 0; | ||
/** | ||
* A filter that is a function that takes a query builder and returns | ||
* a caller-modified query builder. | ||
*/ | ||
class QueryModifier { | ||
constructor(modifier) { | ||
this.modifier = modifier; | ||
} | ||
} | ||
exports.QueryModifier = QueryModifier; | ||
/** | ||
* Returns a query builder that constrains the provided query builder | ||
* according to the provided query filter. | ||
* according to the provided query filter or binary operation. | ||
* @param base The Kysely mapper that is used to create references. | ||
* @param qb The query builder to constrain. | ||
* @param filter The query filter. | ||
* @returns A query builder constrained for the provided query filter. | ||
* @param filterOrLHS The query filter or left-hand side of a binary operation. | ||
* @param op The operator of a binary operation. | ||
* @param rhs The right-hand side of a binary operation. | ||
* @returns A query builder constrained for the provided query filter | ||
* or binary operation. | ||
*/ | ||
function applyQueryFilter(db, qb, filter) { | ||
function applyQueryFilter(db, qb, keyColumns, filterOrLHS, op, rhs) { | ||
// Process a binary operation. | ||
if (op !== undefined) { | ||
return qb.where(filterOrLHS, op, rhs); | ||
} | ||
const filter = filterOrLHS; | ||
if (typeof filter === 'object') { | ||
// Process a key tuple filter. | ||
if (Array.isArray(filter)) { | ||
keyColumns.forEach((column, i) => { | ||
qb = qb.where(db.dynamic.ref(column), '=', filter[i]); | ||
}); | ||
return qb; | ||
} | ||
// Process a query expression filter. Check for expressions | ||
// first because they could potentially be plain objects. | ||
if ('expressionType' in filter) { | ||
return qb.where(filter); | ||
} | ||
// Process a field matching filter. `{}` matches all rows. | ||
if (filter.constructor === Object) { | ||
for (const [column, value] of Object.entries(filter)) { | ||
qb = qb.where(db.dynamic.ref(column), '=', value); | ||
} | ||
return qb; | ||
} | ||
} | ||
// Process a where expression factory. | ||
@@ -32,23 +51,6 @@ if (typeof filter === 'function') { | ||
} | ||
// Process a query expression filter. Check for expressions | ||
// first because they could potentially be plain objects. | ||
if ('expressionType' in filter) { | ||
return qb.where(filter); | ||
// Process a single key filter, expressed as a primitive value. | ||
if (keyColumns.length === 1) { | ||
return qb.where(db.dynamic.ref(keyColumns[0]), '=', filter); | ||
} | ||
// TODO: delete this | ||
// Process a query modifier filter. | ||
if (filter instanceof QueryModifier) { | ||
return filter.modifier(qb); | ||
} | ||
// Process a field matching filter. `{}` matches all rows. | ||
if (filter.constructor === Object) { | ||
for (const [column, value] of Object.entries(filter)) { | ||
qb = qb.where(db.dynamic.ref(column), '=', value); | ||
} | ||
return qb; | ||
} | ||
// Process a binary operation filter. | ||
if (Array.isArray(filter)) { | ||
return qb.where(...filter); | ||
} | ||
throw Error('Unrecognized query filter'); | ||
@@ -55,0 +57,0 @@ } |
@@ -6,14 +6,8 @@ /** | ||
/** | ||
* Converts a key of object O to a string of the form `${K} as ${string}`, | ||
* where K is the key. | ||
* @typeparam O Object whose keys are to be converted to strings. | ||
* @typeparam K Key of O. | ||
*/ | ||
/** | ||
* Type of the primary key tuple whose column names are given by `KA` and are | ||
* Type of the key tuple whose column names are given by `KA` and are | ||
* found in the table interface `T`. Supports up to 4 columns. | ||
* @typeparam T Table interface. | ||
* @typeparam KA Array of the primary key column names. | ||
* @typeparam KA Array of the key column names. | ||
*/ | ||
export type KeyTuple<T, KA extends (keyof Selectable<T> & string)[]> = Selectable<T>[KA[3]] extends string ? [ | ||
export type KeyTuple<T, KA extends (keyof Selectable<T> & string)[]> = KA[3] extends string ? [ | ||
Selectable<T>[KA[0]], | ||
@@ -23,11 +17,4 @@ Selectable<T>[KA[1]], | ||
Selectable<T>[KA[3]] | ||
] : Selectable<T>[KA[2]] extends string ? [Selectable<T>[KA[0]], Selectable<T>[KA[1]], Selectable<T>[KA[2]]] : Selectable<T>[KA[1]] extends string ? [Selectable<T>[KA[0]], Selectable<T>[KA[1]]] : [Selectable<T>[KA[0]]]; | ||
] : KA[2] extends string ? [Selectable<T>[KA[0]], Selectable<T>[KA[1]], Selectable<T>[KA[2]]] : KA[1] extends string ? [Selectable<T>[KA[0]], Selectable<T>[KA[1]]] : [Selectable<T>[KA[0]]]; | ||
/** | ||
* Evaluates to the subset of a the given object having the keys in | ||
* the provided string array of key names. | ||
*/ | ||
export type ObjectWithKeys<O, KeyArray extends string[]> = { | ||
[K in KeyArray[number]]: K extends keyof O ? O[K] : never; | ||
}; | ||
/** | ||
* Evalutes to the type of the query builder output. | ||
@@ -34,0 +21,0 @@ */ |
@@ -1,3 +0,3 @@ | ||
import { Insertable, Selectable, Updateable } from 'kysely'; | ||
import { ObjectWithKeys, SelectedRow, SelectionColumn } from '../lib/type-utils'; | ||
import { Insertable, Selectable, Selection, Updateable } from 'kysely'; | ||
import { SelectableColumnTuple, SelectedRow, SelectionColumn } from '../lib/type-utils'; | ||
/** | ||
@@ -7,9 +7,14 @@ * Options governing TableMapper behavior. | ||
* @typeparam TB Name of the table. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `[]`, indicating no key columns. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam SelectedObject Type of objects returned by select queries. | ||
* @typeparam InsertedObject Type of objects inserted into the table. | ||
* @typeparam UpdatingObject Type of objects used to update rows of the table. | ||
* @typeparam ReturnCount Type of count query results. | ||
* @typeparam ReturnColumns Columns to return from the table on insert or | ||
* update, except when explicitly requesting no columns. `['*']` returns | ||
* all columns; `[]` returns none and is the default. | ||
* @typeparam ReturnCount Type of count query results. | ||
* all columns; `[]` returns none and is the default. May specify aliases. | ||
* Defaults to `KeyColumns`. | ||
* @typeparam InsertReturnsSelectedObject Whether insert queries return | ||
@@ -23,3 +28,10 @@ * `SelectedObject` or `DefaultReturnObject`. | ||
*/ | ||
export interface TableMapperOptions<DB, TB extends keyof DB & string, SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], SelectedObject extends object = SelectedRow<DB, TB, SelectedColumns extends ['*'] ? never : SelectedColumns[number], SelectedColumns>, InsertedObject extends object = Insertable<DB[TB]>, UpdatingObject extends object = Partial<Insertable<DB[TB]>>, ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'] = [], ReturnCount = bigint, InsertReturnsSelectedObject extends boolean = false, UpdateReturnsSelectedObjectWhenProvided extends boolean = false, DefaultReturnObject extends object = ReturnColumns extends ['*'] ? Selectable<DB[TB]> : ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>> { | ||
export interface TableMapperOptions<DB, TB extends keyof DB & string, KeyColumns extends SelectableColumnTuple<DB[TB]> | [] = [], SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], SelectedObject extends object = SelectedRow<DB, TB, SelectedColumns extends ['*'] ? never : SelectedColumns[number], SelectedColumns>, InsertedObject extends object = Insertable<DB[TB]>, UpdatingObject extends object = Partial<Insertable<DB[TB]>>, ReturnCount = bigint, ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'] = KeyColumns, InsertReturnsSelectedObject extends boolean = false, UpdateReturnsSelectedObjectWhenProvided extends boolean = false, DefaultReturnObject extends object = ReturnColumns extends ['*'] ? Selectable<DB[TB]> : Selection<DB, TB, ReturnColumns[number]>> { | ||
/** Tuple of the columns that make up the table's key. May be `[]`. */ | ||
readonly keyColumns?: KeyColumns; | ||
/** | ||
* Columns to return from selection queries. `[*]` selects all columns. | ||
* May contain aliases. | ||
*/ | ||
readonly selectedColumns?: SelectedColumns; | ||
/** Transformation to apply to inserted objects before insertion. */ | ||
@@ -36,4 +48,2 @@ readonly insertTransform?: (obj: InsertedObject) => Insertable<DB[TB]>; | ||
readonly updateReturnsSelectedObjectWhenProvided?: UpdateReturnsSelectedObjectWhenProvided; | ||
/** Columns to return from selection queries. */ | ||
readonly selectedColumns?: SelectedColumns; | ||
/** Transformation to apply to selected objects. */ | ||
@@ -44,8 +54,9 @@ readonly selectTransform?: (row: SelectedRow<DB, TB, SelectedColumns extends ['*'] ? never : SelectedColumns[number], SelectedColumns>) => SelectedObject; | ||
* requesting no columns. `['*']` returns all columns; `[]` returns none. | ||
* May contain aliases. | ||
*/ | ||
readonly returnColumns?: ReturnColumns; | ||
/** Transformation to apply to column values returned from inserts. */ | ||
readonly insertReturnTransform?: (source: InsertedObject, returns: ReturnColumns extends [] ? never : ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject; | ||
readonly insertReturnTransform?: (source: InsertedObject, returns: ReturnColumns extends [] ? never : Selection<DB, TB, ReturnColumns[number]>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject; | ||
/** Transformation to apply to column values returned from updates. */ | ||
readonly updateReturnTransform?: (source: UpdatingObject, returns: ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject; | ||
readonly updateReturnTransform?: (source: UpdatingObject, returns: Selection<DB, TB, ReturnColumns[number]>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject; | ||
/** Transformation to apply to bigint count results. */ | ||
@@ -52,0 +63,0 @@ readonly countTransform?: (count: bigint) => ReturnCount; |
@@ -1,4 +0,4 @@ | ||
import { Kysely, Insertable, ReferenceExpression, Selectable, InsertQueryBuilder, InsertResult, SelectQueryBuilder, Selection, DeleteQueryBuilder, DeleteResult, UpdateResult, UpdateQueryBuilder } from 'kysely'; | ||
import { Kysely, Insertable, ReferenceExpression, Selectable, InsertQueryBuilder, InsertResult, SelectQueryBuilder, Selection, DeleteQueryBuilder, DeleteResult, UpdateResult, UpdateQueryBuilder, ComparisonOperatorExpression, OperandValueExpressionOrList } from 'kysely'; | ||
import { QueryFilter } from '../lib/query-filter'; | ||
import { ObjectWithKeys, SelectedRow, SelectionColumn } from '../lib/type-utils'; | ||
import { SelectableColumnTuple, SelectedRow, SelectionColumn } from '../lib/type-utils'; | ||
import { TableMapperOptions } from './table-mapper-options'; | ||
@@ -14,2 +14,6 @@ import { MappingDeleteQuery } from '../queries/delete-query'; | ||
* @typeparam TB Name of the table. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `[]`, indicating no key columns. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam SelectedObject Type of objects returned by select queries. | ||
@@ -21,3 +25,4 @@ * @typeparam InsertedObject Type of objects inserted into the table. | ||
* update, except when explicitly requesting no columns. `['*']` returns | ||
* all columns; `[]` returns none and is the default. | ||
* all columns; `[]` returns none and is the default. May specify aliases. | ||
* Defaults to `KeyColumns`. | ||
* @typeparam InsertReturnsSelectedObject Whether insert queries return | ||
@@ -31,11 +36,13 @@ * `SelectedObject` or `DefaultReturnObject`. | ||
*/ | ||
export declare class TableMapper<DB, TB extends keyof DB & string, SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], SelectedObject extends object = SelectedRow<DB, TB, SelectedColumns extends ['*'] ? never : SelectedColumns[number], SelectedColumns>, InsertedObject extends object = Insertable<DB[TB]>, UpdatingObject extends object = Partial<Insertable<DB[TB]>>, ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'] = [], ReturnCount = bigint, InsertReturnsSelectedObject extends boolean = false, UpdateReturnsSelectedObjectWhenProvided extends boolean = false, DefaultReturnObject extends object = ReturnColumns extends ['*'] ? Selectable<DB[TB]> : ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>> { | ||
export declare class TableMapper<DB, TB extends keyof DB & string, KeyColumns extends SelectableColumnTuple<DB[TB]> | [] = [], SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], SelectedObject extends object = SelectedRow<DB, TB, SelectedColumns extends ['*'] ? never : SelectedColumns[number], SelectedColumns>, InsertedObject extends object = Insertable<DB[TB]>, UpdatingObject extends object = Partial<Insertable<DB[TB]>>, ReturnCount = bigint, ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'] = KeyColumns, InsertReturnsSelectedObject extends boolean = false, UpdateReturnsSelectedObjectWhenProvided extends boolean = false, DefaultReturnObject extends object = ReturnColumns extends ['*'] ? Selectable<DB[TB]> : Selection<DB, TB, ReturnColumns[number]>> { | ||
#private; | ||
readonly db: Kysely<DB>; | ||
readonly tableName: TB; | ||
readonly options: TableMapperOptions<DB, TB, SelectedColumns, SelectedObject, InsertedObject, UpdatingObject, ReturnColumns, ReturnCount, InsertReturnsSelectedObject, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>; | ||
readonly options: TableMapperOptions<DB, TB, KeyColumns, SelectedColumns, SelectedObject, InsertedObject, UpdatingObject, ReturnCount, ReturnColumns, InsertReturnsSelectedObject, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>; | ||
/** Columns that compose the table's primary key. */ | ||
protected readonly keyColumns: KeyColumns; | ||
/** Columns to return from selection queries. `[]` => all columns. */ | ||
protected readonly selectedColumns: SelectionColumn<DB, TB>[]; | ||
/** Columns to return from the table on insert or update. */ | ||
protected returnColumns: (keyof Selectable<DB[TB]> & string)[] | ['*']; | ||
protected returnColumns: SelectionColumn<DB, TB>[] | ['*']; | ||
/** Transforms query counts into `ReturnCount`. */ | ||
@@ -50,3 +57,3 @@ protected countTransform: (count: bigint) => ReturnCount; | ||
*/ | ||
constructor(db: Kysely<DB>, tableName: TB, options?: TableMapperOptions<DB, TB, SelectedColumns, SelectedObject, InsertedObject, UpdatingObject, ReturnColumns, ReturnCount, InsertReturnsSelectedObject, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>); | ||
constructor(db: Kysely<DB>, tableName: TB, options?: TableMapperOptions<DB, TB, KeyColumns, SelectedColumns, SelectedObject, InsertedObject, UpdatingObject, ReturnCount, ReturnColumns, InsertReturnsSelectedObject, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>); | ||
/** | ||
@@ -70,7 +77,10 @@ * Creates and returns a parameterized mapping query, which can be repeatedly | ||
/** | ||
* Returns a mapping query for deleting rows from the table. | ||
* @param filter Optional filter for selecting rows to delete. | ||
* Returns a mapping query for deleting the rows of the table that match | ||
* the provided filter or Kysely binary operation. | ||
* @param filter Optional filter to apply to the query or the left-hand-side | ||
* of a Kysely binary operation. | ||
* @returns A mapping query for deleting rows. | ||
*/ | ||
delete<RE extends ReferenceExpression<DB, TB>, QB extends DeleteQueryBuilder<DB, TB, DeleteResult>>(filter?: QueryFilter<DB, TB, RE, DeleteQueryBuilder<DB, any, DeleteResult>, QB>): MappingDeleteQuery<DB, TB, DeleteQueryBuilder<DB, TB, DeleteResult>, ReturnCount>; | ||
delete<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: ComparisonOperatorExpression, rhs: OperandValueExpressionOrList<DB, TB, RE>): MappingDeleteQuery<DB, TB, DeleteQueryBuilder<DB, TB, DeleteResult>, ReturnCount>; | ||
delete<RE extends ReferenceExpression<DB, TB>>(filter?: QueryFilter<DB, TB, KeyColumns, RE>): MappingDeleteQuery<DB, TB, DeleteQueryBuilder<DB, TB, DeleteResult>, ReturnCount>; | ||
/** | ||
@@ -89,14 +99,18 @@ * Returns a query for inserting rows into the table. | ||
* Returns a mapping query for selecting rows of the table that match | ||
* the provided filter. | ||
* @param filter Optional filter to apply to the query. | ||
* the provided filter or Kysely binary operation. | ||
* @param filter Optional filter to apply to the query or the left-hand-side | ||
* of a Kysely binary operation. | ||
* @returns A mapping query for retrieving rows as objects. | ||
*/ | ||
select<RE extends ReferenceExpression<DB, TB>, QB extends SelectQueryBuilder<DB, TB, object>>(filter?: QueryFilter<DB, TB, RE, SelectQueryBuilder<DB, TB, object>, QB>): MappingSelectQuery<DB, TB, SelectedColumns, SelectedObject, SelectQueryBuilder<DB, TB, object>>; | ||
select<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: ComparisonOperatorExpression, rhs: OperandValueExpressionOrList<DB, TB, RE>): MappingSelectQuery<DB, TB, SelectedColumns, SelectedObject, SelectQueryBuilder<DB, TB, object>>; | ||
select<RE extends ReferenceExpression<DB, TB>>(filter?: QueryFilter<DB, TB, KeyColumns, RE>): MappingSelectQuery<DB, TB, SelectedColumns, SelectedObject, SelectQueryBuilder<DB, TB, object>>; | ||
/** | ||
* Returns a mapping query for updating rows of the table that match | ||
* the provided filter. | ||
* @param filter Optional filter to apply to the query. | ||
* the provided filter or Kysely binary operation. | ||
* @param filter Optional filter to apply to the query or the left-hand-side | ||
* of a Kysely binary operation. | ||
* @returns A mapping query for updating table rows. | ||
*/ | ||
update<RE extends ReferenceExpression<DB, TB>, QB extends UpdateQueryBuilder<DB, TB, TB, UpdateResult>>(filter?: QueryFilter<DB, TB, RE, UpdateQueryBuilder<DB, TB, TB, UpdateResult>, QB>): MappingUpdateQuery<DB, TB, UpdateQueryBuilder<DB, TB, TB, UpdateResult>, UpdatingObject, SelectedObject, ReturnColumns, ReturnCount, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>; | ||
update<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: ComparisonOperatorExpression, rhs: OperandValueExpressionOrList<DB, TB, RE>): MappingUpdateQuery<DB, TB, UpdateQueryBuilder<DB, TB, TB, UpdateResult>, UpdatingObject, SelectedObject, ReturnColumns, ReturnCount, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>; | ||
update<RE extends ReferenceExpression<DB, TB>>(filter?: QueryFilter<DB, TB, KeyColumns, RE>): MappingUpdateQuery<DB, TB, UpdateQueryBuilder<DB, TB, TB, UpdateResult>, UpdatingObject, SelectedObject, ReturnColumns, ReturnCount, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>; | ||
/** | ||
@@ -103,0 +117,0 @@ * Returns a query builder for deleting rows from the table, caching the |
@@ -21,3 +21,2 @@ "use strict"; | ||
const update_query_1 = require("../queries/update-query"); | ||
// TODO: change [binary op] notation to three parameters | ||
/** | ||
@@ -27,2 +26,6 @@ * A mapper providing access to a single table. | ||
* @typeparam TB Name of the table. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `[]`, indicating no key columns. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam SelectedObject Type of objects returned by select queries. | ||
@@ -34,3 +37,4 @@ * @typeparam InsertedObject Type of objects inserted into the table. | ||
* update, except when explicitly requesting no columns. `['*']` returns | ||
* all columns; `[]` returns none and is the default. | ||
* all columns; `[]` returns none and is the default. May specify aliases. | ||
* Defaults to `KeyColumns`. | ||
* @typeparam InsertReturnsSelectedObject Whether insert queries return | ||
@@ -53,3 +57,3 @@ * `SelectedObject` or `DefaultReturnObject`. | ||
constructor(db, tableName, options = {}) { | ||
var _a; | ||
var _a, _b; | ||
this.db = db; | ||
@@ -63,4 +67,6 @@ this.tableName = tableName; | ||
/** Transforms query counts into `ReturnCount`. */ | ||
// TODO: readonly? | ||
this.countTransform = (count) => count; | ||
this.returnColumns = (_a = options.returnColumns) !== null && _a !== void 0 ? _a : []; | ||
this.keyColumns = (_a = options.keyColumns) !== null && _a !== void 0 ? _a : []; | ||
this.returnColumns = (_b = options.returnColumns) !== null && _b !== void 0 ? _b : this.keyColumns; | ||
this.selectedColumns = | ||
@@ -76,48 +82,6 @@ options.selectedColumns === undefined | ||
} | ||
/** | ||
* Creates and returns a parameterized mapping query, which can be repeatedly | ||
* executed with different parameter values, but which only ever compiles | ||
* the underlying Kysely query once (on the first execution). | ||
* @paramtype P Record characterizing the available parameter names and types. | ||
* @param factory Function that receives an object of the form `{ q, param }`, | ||
* where `q` is a mapping query and `param` is a function for creating | ||
* parameters. The argument to `param` is the name of the parameter, which | ||
* must occur as a property of `P`. You may parameterize inserted values, | ||
* updated values, and right-hand-side values of filters. Parameters may not | ||
* be arrays, but you can parameterize the individual elements of an array. | ||
* Returns a mapping query that containing the parameterized values. | ||
* @returns a parameterized mapping query | ||
*/ | ||
// compile<P extends ParametersObject<P>>( | ||
// factory: ParamedSelectionQueryFactory< | ||
// P, | ||
// MappingSelectQuery<DB, TB, SelectedObject, QB> | ||
// > | ||
// ): ParameterizedRowQuery<P, SelectedObject> { | ||
// const parameterMaker = new QueryParameterMaker<P>(); | ||
// return new ParameterizedRowQuery( | ||
// factory({ | ||
// q: this, | ||
// param: parameterMaker.param.bind(parameterMaker), | ||
// }).qb, | ||
// ); | ||
// } | ||
/** | ||
* Factory function for parameterizing MappingSelectQuery. | ||
*/ | ||
// interface ParamedSelectionQueryFactory< | ||
// P extends ParametersObject<P>, | ||
// Q extends MappingSelectQuery<any, any, any, any> | ||
// > { | ||
// (args: { q: Q; param: QueryParameterMaker<P>['param'] }): Q; | ||
// } | ||
/** | ||
* Returns a mapping query for deleting rows from the table. | ||
* @param filter Optional filter for selecting rows to delete. | ||
* @returns A mapping query for deleting rows. | ||
*/ | ||
delete(filter) { | ||
return new delete_query_1.MappingDeleteQuery(this.db, filter === undefined | ||
delete(filterOrLHS, op, rhs) { | ||
return new delete_query_1.MappingDeleteQuery(this.db, filterOrLHS === undefined | ||
? this.getDeleteQB() | ||
: (0, query_filter_1.applyQueryFilter)(this.db, this.getDeleteQB(), filter), this.countTransform); | ||
: (0, query_filter_1.applyQueryFilter)(this.db, this.getDeleteQB(), this.keyColumns, filterOrLHS, op, rhs), this.countTransform); | ||
} | ||
@@ -130,3 +94,3 @@ // TODO: support listing inserted columns | ||
insert() { | ||
return new insert_query_1.MappingInsertQuery(this.db, this.getInsertQB(), this.options.insertTransform, this.options.returnColumns, this.options.insertReturnTransform); | ||
return new insert_query_1.MappingInsertQuery(this.db, this.getInsertQB(), this.options.insertTransform, this.returnColumns, this.options.insertReturnTransform); | ||
} | ||
@@ -138,26 +102,15 @@ /** | ||
*/ | ||
// TODO: do I need this? | ||
ref(column) { | ||
return this.db.dynamic.ref(column); | ||
} | ||
/** | ||
* Returns a mapping query for selecting rows of the table that match | ||
* the provided filter. | ||
* @param filter Optional filter to apply to the query. | ||
* @returns A mapping query for retrieving rows as objects. | ||
*/ | ||
select(filter) { | ||
return new select_query_1.MappingSelectQuery(this.db, filter === undefined | ||
select(filterOrLHS, op, rhs) { | ||
return new select_query_1.MappingSelectQuery(this.db, filterOrLHS === undefined | ||
? this.getSelectQB() | ||
: (0, query_filter_1.applyQueryFilter)(this.db, this.getSelectQB(), filter), this.options.selectTransform); | ||
: (0, query_filter_1.applyQueryFilter)(this.db, this.getSelectQB(), this.keyColumns, filterOrLHS, op, rhs), this.options.selectTransform); | ||
} | ||
/** | ||
* Returns a mapping query for updating rows of the table that match | ||
* the provided filter. | ||
* @param filter Optional filter to apply to the query. | ||
* @returns A mapping query for updating table rows. | ||
*/ | ||
update(filter) { | ||
return new update_query_1.MappingUpdateQuery(this.db, filter === undefined | ||
update(filterOrLHS, op, rhs) { | ||
return new update_query_1.MappingUpdateQuery(this.db, filterOrLHS === undefined | ||
? this.getUpdateQB() | ||
: (0, query_filter_1.applyQueryFilter)(this.db, this.getUpdateQB(), filter), this.countTransform, this.options.updateTransform, this.options.returnColumns, this.options.updateReturnTransform); | ||
: (0, query_filter_1.applyQueryFilter)(this.db, this.getUpdateQB(), this.keyColumns, filterOrLHS, op, rhs), this.countTransform, this.options.updateTransform, this.returnColumns, this.options.updateReturnTransform); | ||
} | ||
@@ -164,0 +117,0 @@ /** |
@@ -1,2 +0,2 @@ | ||
import { Insertable, Selectable } from 'kysely'; | ||
import { Insertable } from 'kysely'; | ||
import { SelectableColumnTuple, SelectionColumn } from '../lib/type-utils'; | ||
@@ -11,12 +11,13 @@ import { TableMapperOptions } from './table-mapper-options'; | ||
* as columns of the table. | ||
* @typeparam PrimaryKeyColumns Tuple of the names of the primary key columns. | ||
* Defaults to `['id']`. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `['id']`. `[]` indicates no key columns. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam ReturnColumns The columns that are returned from the database | ||
* when selecting or updating rows, for use when creating the mapped objects. | ||
* `['*']` returns all columns; `[]` returns none. Defaults to `PrimaryKeyColumns`. | ||
* `['*']` returns all columns; `[]` returns none. May specify aliases. | ||
* Defaults to `KeyColumns`. | ||
* @typeparam ReturnCount Type of count query results. | ||
*/ | ||
export interface UniformTableMapperOptions<DB, TB extends keyof DB & string, MappedObject extends object, PrimaryKeyColumns extends SelectableColumnTuple<DB[TB]>, SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'], ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'], ReturnCount> extends TableMapperOptions<DB, TB, SelectedColumns, MappedObject, MappedObject, MappedObject | Partial<Insertable<DB[TB]>>, ReturnColumns, ReturnCount, true, true> { | ||
/** Columns that make up the primary key of the table. */ | ||
readonly primaryKeyColumns?: PrimaryKeyColumns; | ||
export interface UniformTableMapperOptions<DB, TB extends keyof DB & string, MappedObject extends object, KeyColumns extends SelectableColumnTuple<DB[TB]> | [], SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'], ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'], ReturnCount> extends TableMapperOptions<DB, TB, KeyColumns, SelectedColumns, MappedObject, MappedObject, MappedObject | Partial<Insertable<DB[TB]>>, ReturnCount, ReturnColumns, true, true> { | ||
/** Indicates whether the provided object is an instance of `MappedObject`. */ | ||
@@ -23,0 +24,0 @@ readonly isMappedObject: (obj: any) => boolean; |
@@ -1,2 +0,2 @@ | ||
import { Insertable, Kysely, Selectable } from 'kysely'; | ||
import { Insertable, Kysely } from 'kysely'; | ||
import { TableMapper } from './table-mapper'; | ||
@@ -8,4 +8,3 @@ import { SelectableColumn, SelectableColumnTuple, SelectionColumn } from '../lib/type-utils'; | ||
/** | ||
* A mapper for a table representing a store of objects, where each object has a | ||
* unique identifying key given by one or more primary key columns. | ||
* A mapper for a table representing a store of objects. | ||
* @typeparam DB The database type. | ||
@@ -16,21 +15,25 @@ * @typeparam TB The name of the table. | ||
* as columns of the table. | ||
* @typeparam PrimaryKeyColumns Tuple of the names of the primary key columns. | ||
* Defaults to `['id']`. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `['id']`. By default, falsy key values are assumed to require | ||
* generation and `insertTransform` removes them from the insertion. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam ReturnCount Type of count query results. | ||
* @typeparam ReturnColumns The columns that are returned from the database | ||
* when selecting or updating rows, for use when creating the mapped objects. | ||
* `['*']` returns all columns; `[]` returns none. Defaults to `PrimaryKeyColumns`. | ||
* @typeparam ReturnCount Type of count query results. | ||
* when selecting or updating rows, for use when creating mapped objects. | ||
* `['*']` returns all columns; `[]` returns none. By default, the columns | ||
* are added to objects returned on update. Defaults to `KeyColumns`. | ||
*/ | ||
export declare class UniformTableMapper<DB, TB extends keyof DB & string, MappedObject extends object, PrimaryKeyColumns extends SelectableColumnTuple<DB[TB]> = [ | ||
export declare class UniformTableMapper<DB, TB extends keyof DB & string, MappedObject extends object, KeyColumns extends SelectableColumnTuple<DB[TB]> | [] = [ | ||
'id' & SelectableColumn<DB[TB]> | ||
], SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], ReturnCount = bigint, ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'] = PrimaryKeyColumns> extends TableMapper<DB, TB, SelectedColumns, MappedObject, MappedObject, MappedObject | Partial<Insertable<DB[TB]>>, ReturnColumns, ReturnCount, true, true> { | ||
], SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], ReturnCount = bigint, ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'] = KeyColumns> extends TableMapper<DB, TB, KeyColumns, SelectedColumns, MappedObject, MappedObject, MappedObject | Partial<Insertable<DB[TB]>>, ReturnCount, ReturnColumns, true, true> { | ||
/** | ||
* @param db The Kysely database instance. | ||
* @param tableName The name of the table. | ||
* @param options Options governing mapper behavior. Default to a | ||
* primary key of `id`, to selecting all columns, and to returning | ||
* @param options Options governing mapper behavior. Defaults to | ||
* a key of `id`, to selecting all columns, and to returning | ||
* the `id` on insert or update, when the caller requests returns. | ||
*/ | ||
constructor(db: Kysely<DB>, tableName: TB, options: UniformTableMapperOptions<DB, TB, MappedObject, PrimaryKeyColumns, SelectedColumns, ReturnColumns, ReturnCount>); | ||
constructor(db: Kysely<DB>, tableName: TB, options: UniformTableMapperOptions<DB, TB, MappedObject, KeyColumns, SelectedColumns, ReturnColumns, ReturnCount>); | ||
} | ||
//# sourceMappingURL=uniform-table-mapper.d.ts.map |
@@ -10,4 +10,3 @@ "use strict"; | ||
/** | ||
* A mapper for a table representing a store of objects, where each object has a | ||
* unique identifying key given by one or more primary key columns. | ||
* A mapper for a table representing a store of objects. | ||
* @typeparam DB The database type. | ||
@@ -18,8 +17,12 @@ * @typeparam TB The name of the table. | ||
* as columns of the table. | ||
* @typeparam PrimaryKeyColumns Tuple of the names of the primary key columns. | ||
* Defaults to `['id']`. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `['id']`. By default, falsy key values are assumed to require | ||
* generation and `insertTransform` removes them from the insertion. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam ReturnCount Type of count query results. | ||
* @typeparam ReturnColumns The columns that are returned from the database | ||
* when selecting or updating rows, for use when creating the mapped objects. | ||
* `['*']` returns all columns; `[]` returns none. Defaults to `PrimaryKeyColumns`. | ||
* @typeparam ReturnCount Type of count query results. | ||
* when selecting or updating rows, for use when creating mapped objects. | ||
* `['*']` returns all columns; `[]` returns none. By default, the columns | ||
* are added to objects returned on update. Defaults to `KeyColumns`. | ||
*/ | ||
@@ -30,4 +33,4 @@ class UniformTableMapper extends table_mapper_1.TableMapper { | ||
* @param tableName The name of the table. | ||
* @param options Options governing mapper behavior. Default to a | ||
* primary key of `id`, to selecting all columns, and to returning | ||
* @param options Options governing mapper behavior. Defaults to | ||
* a key of `id`, to selecting all columns, and to returning | ||
* the `id` on insert or update, when the caller requests returns. | ||
@@ -45,7 +48,7 @@ */ | ||
var _a; | ||
const primaryKeyColumns = (_a = options.primaryKeyColumns) !== null && _a !== void 0 ? _a : exports.DEFAULT_KEY; | ||
// Remove primary keys from inserted object, by default | ||
const keyColumns = (_a = options.keyColumns) !== null && _a !== void 0 ? _a : exports.DEFAULT_KEY; | ||
// Remove falsy key values from inserted object, by default | ||
const insertTransform = (obj) => { | ||
const insertedValues = Object.assign({}, obj); | ||
primaryKeyColumns.forEach((column) => { | ||
keyColumns.forEach((column) => { | ||
if (!obj[column]) { | ||
@@ -58,7 +61,5 @@ delete insertedValues[column]; | ||
// Add returned values to inserted object, by default | ||
const insertReturnTransform = (obj, returns) => { | ||
return Object.assign(Object.assign({}, obj), returns); | ||
}; | ||
// Use insert transform by default; or if none is provided, remove primary | ||
// keys from inserted object if the object is a `MappedObject`. | ||
const insertReturnTransform = (obj, returns) => (Object.assign(Object.assign({}, obj), returns)); | ||
// Use insert transform by default; or if none is provided, remove falsy | ||
// key values from inserted object if the object is a `MappedObject`. | ||
const updateTransform = options.insertTransform !== undefined | ||
@@ -75,8 +76,8 @@ ? options.insertTransform | ||
: options.insertReturnTransform(obj, returns); | ||
return Object.assign({ primaryKeyColumns, | ||
return Object.assign({ keyColumns, | ||
insertTransform, | ||
insertReturnTransform, | ||
updateTransform, | ||
updateReturnTransform, returnColumns: primaryKeyColumns }, options); | ||
updateReturnTransform, returnColumns: keyColumns }, options); | ||
} | ||
//# sourceMappingURL=uniform-table-mapper.js.map |
@@ -1,7 +0,7 @@ | ||
import { Kysely, InsertQueryBuilder, InsertResult, Selectable, Insertable } from 'kysely'; | ||
import { ObjectWithKeys } from '../lib/type-utils'; | ||
import { Kysely, InsertQueryBuilder, InsertResult, Selection, Insertable } from 'kysely'; | ||
import { SelectionColumn } from '../lib/type-utils'; | ||
/** | ||
* Mapping query for inserting rows into a database table. | ||
*/ | ||
export declare class MappingInsertQuery<DB, TB extends keyof DB & string, QB extends InsertQueryBuilder<DB, TB, InsertResult>, InsertedObject extends object, SelectedObject extends object, ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'], InsertReturnsSelectedObject extends boolean, DefaultReturnObject extends object> { | ||
export declare class MappingInsertQuery<DB, TB extends keyof DB & string, QB extends InsertQueryBuilder<DB, TB, InsertResult>, InsertedObject extends object, SelectedObject extends object, ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'], InsertReturnsSelectedObject extends boolean, DefaultReturnObject extends object> { | ||
#private; | ||
@@ -11,3 +11,3 @@ protected readonly db: Kysely<DB>; | ||
protected readonly insertTransform?: ((obj: InsertedObject) => Insertable<DB[TB]>) | undefined; | ||
protected readonly insertReturnTransform?: ((source: InsertedObject, returns: ReturnColumns extends [] ? never : ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject) | undefined; | ||
protected readonly insertReturnTransform?: ((source: InsertedObject, returns: ReturnColumns extends [] ? never : Selection<DB, TB, ReturnColumns[number]>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject) | undefined; | ||
protected readonly returnColumns: ReturnColumns; | ||
@@ -28,3 +28,3 @@ /** | ||
*/ | ||
constructor(db: Kysely<DB>, qb: QB, insertTransform?: ((obj: InsertedObject) => Insertable<DB[TB]>) | undefined, returnColumns?: ReturnColumns, insertReturnTransform?: ((source: InsertedObject, returns: ReturnColumns extends [] ? never : ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject) | undefined); | ||
constructor(db: Kysely<DB>, qb: QB, insertTransform?: ((obj: InsertedObject) => Insertable<DB[TB]>) | undefined, returnColumns?: ReturnColumns, insertReturnTransform?: ((source: InsertedObject, returns: ReturnColumns extends [] ? never : Selection<DB, TB, ReturnColumns[number]>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject) | undefined); | ||
/** | ||
@@ -31,0 +31,0 @@ * Inserts the provided objects into the table as rows, first transforming |
@@ -1,7 +0,7 @@ | ||
import { Kysely, Selectable, UpdateQueryBuilder, UpdateResult, Updateable } from 'kysely'; | ||
import { ObjectWithKeys } from '../lib/type-utils'; | ||
import { Kysely, Selection, UpdateQueryBuilder, UpdateResult, Updateable } from 'kysely'; | ||
import { SelectionColumn } from '../lib/type-utils'; | ||
/** | ||
* Mapping query for updating rows from a database table. | ||
*/ | ||
export declare class MappingUpdateQuery<DB, TB extends keyof DB & string, QB extends UpdateQueryBuilder<DB, TB, TB, UpdateResult>, UpdatingObject extends object, SelectedObject extends object, ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'], ReturnCount, UpdateReturnsSelectedObjectWhenProvided extends boolean, DefaultReturnObject extends object> { | ||
export declare class MappingUpdateQuery<DB, TB extends keyof DB & string, QB extends UpdateQueryBuilder<DB, TB, TB, UpdateResult>, UpdatingObject extends object, SelectedObject extends object, ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'], ReturnCount, UpdateReturnsSelectedObjectWhenProvided extends boolean, DefaultReturnObject extends object> { | ||
#private; | ||
@@ -12,3 +12,3 @@ readonly db: Kysely<DB>; | ||
protected readonly updateTransform?: ((update: UpdatingObject) => Updateable<DB[TB]>) | undefined; | ||
protected readonly updateReturnTransform?: ((source: UpdatingObject, returns: ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject) | undefined; | ||
protected readonly updateReturnTransform?: ((source: UpdatingObject, returns: Selection<DB, TB, ReturnColumns[number]>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject) | undefined; | ||
protected readonly returnColumns: ReturnColumns; | ||
@@ -31,3 +31,3 @@ /** | ||
*/ | ||
constructor(db: Kysely<DB>, qb: QB, countTransform: (count: bigint) => ReturnCount, updateTransform?: ((update: UpdatingObject) => Updateable<DB[TB]>) | undefined, returnColumns?: ReturnColumns, updateReturnTransform?: ((source: UpdatingObject, returns: ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject) | undefined); | ||
constructor(db: Kysely<DB>, qb: QB, countTransform: (count: bigint) => ReturnCount, updateTransform?: ((update: UpdatingObject) => Updateable<DB[TB]>) | undefined, returnColumns?: ReturnColumns, updateReturnTransform?: ((source: UpdatingObject, returns: Selection<DB, TB, ReturnColumns[number]>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject) | undefined); | ||
/** | ||
@@ -34,0 +34,0 @@ * Runs the query, returning the number of rows updated, in |
@@ -19,5 +19,7 @@ "use strict"; | ||
let userMapper; | ||
let userMapperReturningNothing; | ||
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { | ||
db = yield (0, test_setup_1.createDB)(); | ||
userMapper = new test_mappers_1.UserTableMapperReturningAll(db); | ||
userMapperReturningNothing = new test_mappers_1.UserTableMapperReturningNothing(db); | ||
})); | ||
@@ -106,2 +108,12 @@ beforeEach(() => (0, test_setup_1.resetDB)(db)); | ||
})); | ||
it('deletes rows specified via binary operation', () => __awaiter(void 0, void 0, void 0, function* () { | ||
yield userMapper.insert().run(test_objects_1.USERS); | ||
const count1 = yield userMapper | ||
.delete('name', '=', test_objects_1.USERS[0].name) | ||
.getCount(); | ||
expect(count1).toEqual(2); | ||
const users = yield userMapper.select().getAll(); | ||
expect(users.length).toEqual(1); | ||
expect(users[0].handle).toEqual(test_objects_1.USERS[1].handle); | ||
})); | ||
it('modifies a delete query builder', () => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -156,5 +168,3 @@ yield userMapper.insert().run(test_objects_1.USERS); | ||
// @ts-expect-error - table must have all filter fields | ||
userMapper.delete(['notThere', '=', 'foo']); | ||
// @ts-expect-error - doesn't allow plain string expression filters | ||
userMapper.delete("name = 'John Doe'"); | ||
userMapper.delete('notThere', '=', 'foo'); | ||
userMapper.delete(({ or, cmpr }) => | ||
@@ -166,4 +176,12 @@ // @ts-expect-error - only table columns are accessible via anyOf() | ||
or([cmpr('notThere', '=', 'xyz'), cmpr('alsoNotThere', '=', 'Sue')])); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapper.delete('str'); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapper.delete(['str']); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.delete(1); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.delete([1]); | ||
})); | ||
}); | ||
//# sourceMappingURL=TableMapper.delete.test.js.map |
@@ -24,3 +24,3 @@ "use strict"; | ||
let postTableMapper; | ||
let postTableMapperReturningIDAndTitle; | ||
let postTableMapperReturningIDAndTitleAsT; | ||
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -35,4 +35,4 @@ db = yield (0, test_setup_1.createDB)(); | ||
}); | ||
postTableMapperReturningIDAndTitle = new table_mapper_1.TableMapper(db, 'posts', { | ||
returnColumns: ['id', 'title'], | ||
postTableMapperReturningIDAndTitleAsT = new table_mapper_1.TableMapper(db, 'posts', { | ||
returnColumns: ['id', 'title as t'], | ||
countTransform: (count) => Number(count), | ||
@@ -126,11 +126,17 @@ }); | ||
const post2 = Object.assign({}, test_objects_1.POSTS[2], { userId: insertReturns[2].id }); | ||
const updatingPosts = yield postTableMapperReturningIDAndTitle | ||
const updateReturns = yield postTableMapperReturningIDAndTitleAsT | ||
.insert() | ||
.getAll([post0, post1, post2]); | ||
expect(updatingPosts.length).toEqual(3); | ||
for (let i = 0; i < updatingPosts.length; i++) { | ||
expect(updatingPosts[i].id).toBeGreaterThan(0); | ||
expect(updatingPosts[i].title).toEqual(test_objects_1.POSTS[i].title); | ||
expect(Object.keys(updatingPosts[i]).length).toEqual(2); | ||
expect(updateReturns.length).toEqual(3); | ||
for (let i = 0; i < updateReturns.length; i++) { | ||
expect(updateReturns[i].id).toBeGreaterThan(0); | ||
expect(updateReturns[i].t).toEqual(test_objects_1.POSTS[i].title); | ||
expect(Object.keys(updateReturns[i]).length).toEqual(2); | ||
} | ||
(0, test_utils_1.ignore)('check return types', () => { | ||
// @ts-expect-error - check return types | ||
updateReturns[0].title; | ||
// @ts-expect-error - check return types | ||
updateReturns[0].userId; | ||
}); | ||
})); | ||
@@ -186,3 +192,3 @@ it('inserts multiple returning no columns by default', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const readUser0 = yield userMapperReturningAll | ||
.select(['email', '=', test_objects_1.USERS[0].email]) | ||
.select('email', '=', test_objects_1.USERS[0].email) | ||
.getOne(); | ||
@@ -195,3 +201,3 @@ expect(readUser0 === null || readUser0 === void 0 ? void 0 : readUser0.email).toEqual(test_objects_1.USERS[0].email); | ||
const readUser0 = yield userMapperReturningAll | ||
.select(['email', '=', test_objects_1.USERS[0].email]) | ||
.select('email', '=', test_objects_1.USERS[0].email) | ||
.getOne(); | ||
@@ -205,19 +211,25 @@ expect(readUser0 === null || readUser0 === void 0 ? void 0 : readUser0.email).toEqual(test_objects_1.USERS[0].email); | ||
const readUser0 = yield userMapperReturningAll | ||
.select(['id', '=', insertReturn.id]) | ||
.select('id', '=', insertReturn.id) | ||
.getOne(); | ||
expect(readUser0 === null || readUser0 === void 0 ? void 0 : readUser0.email).toEqual(test_objects_1.USERS[0].email); | ||
const post0 = Object.assign({}, test_objects_1.POSTS[0], { userId: insertReturn.id }); | ||
const updatingPost = yield postTableMapperReturningIDAndTitle | ||
const updateReturn = yield postTableMapperReturningIDAndTitleAsT | ||
.insert() | ||
.getOne(post0); | ||
expect(updatingPost.id).toBeGreaterThan(0); | ||
expect(updatingPost.title).toEqual(test_objects_1.POSTS[0].title); | ||
expect(Object.keys(updatingPost).length).toEqual(2); | ||
expect(updateReturn.id).toBeGreaterThan(0); | ||
expect(updateReturn.t).toEqual(test_objects_1.POSTS[0].title); | ||
expect(Object.keys(updateReturn).length).toEqual(2); | ||
const readPost0 = yield postTableMapper | ||
.select(({ and, cmpr }) => and([ | ||
cmpr('id', '=', updatingPost.id), | ||
cmpr('title', '=', updatingPost.title), | ||
cmpr('id', '=', updateReturn.id), | ||
cmpr('title', '=', updateReturn.t), | ||
])) | ||
.getOne(); | ||
expect(readPost0 === null || readPost0 === void 0 ? void 0 : readPost0.likeCount).toEqual(post0.likeCount); | ||
(0, test_utils_1.ignore)('check return types', () => { | ||
// @ts-expect-error - check return types | ||
updateReturn.title; | ||
// @ts-expect-error - check return types | ||
updateReturn.userId; | ||
}); | ||
})); | ||
@@ -272,3 +284,3 @@ it('inserts one configured to return all columns', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const readUsers = yield insertTransformMapper | ||
.select(['id', '>', insertReturn.id]) | ||
.select('id', '>', insertReturn.id) | ||
.getAll(); | ||
@@ -275,0 +287,0 @@ expect(readUsers.length).toEqual(2); |
@@ -24,5 +24,7 @@ "use strict"; | ||
let userMapper; | ||
let userMapperReturningNothing; | ||
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { | ||
db = yield (0, test_setup_1.createDB)(); | ||
userMapper = new test_mappers_1.UserTableMapperReturningID(db); | ||
userMapperReturningNothing = new test_mappers_1.UserTableMapperReturningNothing(db); | ||
})); | ||
@@ -113,5 +115,45 @@ beforeEach(() => (0, test_setup_1.resetDB)(db)); | ||
})); | ||
it('selects via a multi-column key tuple (definition order)', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const mapper = new table_mapper_1.TableMapper(db, 'users', { | ||
keyColumns: ['id', 'name'], | ||
}); | ||
yield mapper.insert().run(test_objects_1.USERS); | ||
const users = yield mapper.select([3, 'Sue']).getAll(); | ||
expect(users.length).toEqual(1); | ||
expect(users[0].name).toEqual(test_objects_1.USERS[2].name); | ||
(0, test_utils_1.ignore)('detects key colum tuple type errors', () => { | ||
// @ts-expect-error - key tuple must have correct length | ||
mapper.select(['Sue']); | ||
// @ts-expect-error - key tuple must have correct length | ||
mapper.select(['Sue', 3, 'foo']); | ||
// @ts-expect-error - key tuple must have correct types | ||
mapper.select(['Sue', 'foo']); | ||
// @ts-expect-error - primitive key values are not allowed | ||
mapper.select('Sue'); | ||
// @ts-expect-error - primitive key values are not allowed | ||
mapper.select(1); | ||
}); | ||
})); | ||
it('selects via a multi-column key tuple (different order)', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const mapper = new table_mapper_1.TableMapper(db, 'users', { | ||
keyColumns: ['name', 'id'], | ||
}); | ||
yield mapper.insert().run(test_objects_1.USERS); | ||
const users = yield mapper.select(['Sue', 3]).getAll(); | ||
expect(users.length).toEqual(1); | ||
expect(users[0].name).toEqual(test_objects_1.USERS[2].name); | ||
(0, test_utils_1.ignore)('detects key colum tuple type errors', () => { | ||
// @ts-expect-error - key tuple must have correct length | ||
mapper.select(['Sue']); | ||
// @ts-expect-error - key tuple must have correct length | ||
mapper.select(['Sue', 3, 'foo']); | ||
// @ts-expect-error - key tuple must have correct types | ||
mapper.select(['Sue', 'foo']); | ||
// @ts-expect-error - primitive key values are not allowed | ||
mapper.select('Sue'); | ||
// @ts-expect-error - primitive key values are not allowed | ||
mapper.select(1); | ||
}); | ||
})); | ||
(0, test_utils_1.ignore)('detects select(filter) type errors', () => __awaiter(void 0, void 0, void 0, function* () { | ||
// @ts-expect-error - doesn't allow plain string expressions | ||
userMapper.select("name = 'John Doe'"); | ||
// @ts-expect-error - doesn't allow only two arguments | ||
@@ -125,5 +167,13 @@ userMapper.select('name', '='); | ||
// @ts-expect-error - binary op filter fields must be valid | ||
userMapper.select(['notThere', '=', 'foo']); | ||
userMapper.select('notThere', '=', 'foo'); | ||
// @ts-expect-error - binary op filter fields must be valid | ||
userMapper.select(['users.notThere', '=', 'foo']); | ||
userMapper.select('users.notThere', '=', 'foo'); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapper.select('str'); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapper.select(['str']); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.select(1); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.select([1]); | ||
})); | ||
@@ -146,2 +196,13 @@ }); | ||
})); | ||
it('selects via key column values', () => __awaiter(void 0, void 0, void 0, function* () { | ||
yield userMapper.insert().run(test_objects_1.USERS); | ||
// Test selecting via key value | ||
const users1 = yield userMapper.select(2).getAll(); | ||
expect(users1.length).toEqual(1); | ||
expect(users1[0].handle).toEqual(test_objects_1.USERS[1].handle); | ||
// Test selecting via key tuple | ||
const users2 = yield userMapper.select([2]).getAll(); | ||
expect(users2.length).toEqual(1); | ||
expect(users2[0].handle).toEqual(test_objects_1.USERS[1].handle); | ||
})); | ||
it('selects with a matching field filter', () => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -169,3 +230,3 @@ yield userMapper.insert().run(test_objects_1.USERS); | ||
// Test selecting by condition (with results) | ||
let users = yield userMapper.select(['name', '=', test_objects_1.USERS[0].name]).getAll(); | ||
let users = yield userMapper.select('name', '=', test_objects_1.USERS[0].name).getAll(); | ||
expect(users.length).toEqual(2); | ||
@@ -175,3 +236,3 @@ expect(users[0].handle).toEqual(test_objects_1.USERS[0].handle); | ||
// Test selecting by condition (no results) | ||
users = yield userMapper.select(['name', '=', 'nonexistent']).getAll(); | ||
users = yield userMapper.select('name', '=', 'nonexistent').getAll(); | ||
expect(users.length).toEqual(0); | ||
@@ -209,3 +270,3 @@ })); | ||
// Test selecting by condition (with results) | ||
let users = yield userMapper.select(['name', '=', test_objects_1.USERS[0].name]).getAll(); | ||
let users = yield userMapper.select('name', '=', test_objects_1.USERS[0].name).getAll(); | ||
expect(users.length).toEqual(2); | ||
@@ -215,3 +276,3 @@ expect(users[0].handle).toEqual(test_objects_1.USERS[0].handle); | ||
// Test selecting by condition (no results) | ||
users = yield userMapper.select(['name', '=', 'nonexistent']).getAll(); | ||
users = yield userMapper.select('name', '=', 'nonexistent').getAll(); | ||
expect(users.length).toEqual(0); | ||
@@ -254,3 +315,3 @@ })); | ||
// prettier-ignore | ||
(yield userMapper.select(["name", "=", "Sue"]).getAll())[0].notThere; | ||
(yield userMapper.select("name", "=", "Sue").getAll())[0].notThere; | ||
// prettier-ignore | ||
@@ -293,6 +354,6 @@ (yield userMapper | ||
// Test selecting by condition (with result) | ||
let user = yield userMapper.select(['name', '=', test_objects_1.USERS[0].name]).getOne(); | ||
let user = yield userMapper.select('name', '=', test_objects_1.USERS[0].name).getOne(); | ||
expect(user === null || user === void 0 ? void 0 : user.handle).toEqual(test_objects_1.USERS[0].handle); | ||
// Test selecting by condition (no result) | ||
user = yield userMapper.select(['name', '=', 'nonexistent']).getOne(); | ||
user = yield userMapper.select('name', '=', 'nonexistent').getOne(); | ||
expect(user).toBeNull(); | ||
@@ -329,6 +390,6 @@ })); | ||
// Test selecting by condition (with result) | ||
let user = yield userMapper.select(['name', '=', test_objects_1.USERS[0].name]).getOne(); | ||
let user = yield userMapper.select('name', '=', test_objects_1.USERS[0].name).getOne(); | ||
expect(user === null || user === void 0 ? void 0 : user.handle).toEqual(test_objects_1.USERS[0].handle); | ||
// Test selecting by condition (no result) | ||
user = yield userMapper.select(['name', '=', 'nonexistent']).getOne(); | ||
user = yield userMapper.select('name', '=', 'nonexistent').getOne(); | ||
expect(user).toBeNull(); | ||
@@ -357,3 +418,3 @@ })); | ||
// prettier-ignore | ||
(yield userMapper.select(["name", "=", "Sue"]).getOne()).notThere; | ||
(yield userMapper.select("name", "=", "Sue").getOne()).notThere; | ||
// prettier-ignore | ||
@@ -360,0 +421,0 @@ (yield userMapper |
@@ -23,3 +23,3 @@ "use strict"; | ||
let userMapperReturningID; | ||
let userMapperReturningIDAndHandle; | ||
let userMapperReturningIDAndHandleAsH; | ||
let userMapperReturningAll; | ||
@@ -31,3 +31,4 @@ beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { | ||
userMapperReturningID = new test_mappers_1.UserTableMapperReturningID(db); | ||
userMapperReturningIDAndHandle = new test_mappers_1.UserTableMapperReturningIDAndHandle(db); | ||
userMapperReturningIDAndHandleAsH = | ||
new test_mappers_1.UserTableMapperReturningIDAndHandleAsH(db); | ||
userMapperReturningAll = new test_mappers_1.UserTableMapperReturningAll(db); | ||
@@ -67,3 +68,3 @@ })); | ||
const readUser1 = yield userMapperReturningID | ||
.select(['id', '=', insertReturn0.id]) | ||
.select('id', '=', insertReturn0.id) | ||
.getOne(); | ||
@@ -76,3 +77,3 @@ expect(readUser1 === null || readUser1 === void 0 ? void 0 : readUser1.email).toEqual(updateValues.email); | ||
const readUsers = yield userMapperReturningID | ||
.select(['name', '=', 'Sue']) | ||
.select('name', '=', 'Sue') | ||
.getAll(); | ||
@@ -92,5 +93,3 @@ expect(readUsers.length).toEqual(2); | ||
expect(update).toEqual({ id: 1 }); | ||
const readUser2 = yield userMapperReturningID | ||
.select(['id', '=', 1]) | ||
.getOne(); | ||
const readUser2 = yield userMapperReturningID.select('id', '=', 1).getOne(); | ||
expect(readUser2 === null || readUser2 === void 0 ? void 0 : readUser2.name).toEqual('Every User 2'); | ||
@@ -117,3 +116,3 @@ const updateCount = yield userMapperReturningID.update().getCount({ | ||
let readUser = yield userMapperReturningID | ||
.select(['id', '=', insertReturn.id]) | ||
.select('id', '=', insertReturn.id) | ||
.getOne(); | ||
@@ -123,13 +122,15 @@ expect(readUser === null || readUser === void 0 ? void 0 : readUser.email).toEqual(updateValues1.email); | ||
const updateValues2 = { name: 'Sue' }; | ||
const updateReturns2 = yield userMapperReturningIDAndHandle | ||
const updateReturns2 = yield userMapperReturningIDAndHandleAsH | ||
.update({ email: updateValues1.email }) | ||
.getAll(updateValues2); | ||
updateReturns2[0].id; // ensure key is accessible | ||
updateReturns2[0].h; // ensure key is accessible | ||
expect(updateReturns2).toEqual([ | ||
{ | ||
id: insertReturn.id, | ||
handle: test_objects_1.USERS[1].handle, | ||
h: test_objects_1.USERS[1].handle, | ||
}, | ||
]); | ||
readUser = yield userMapperReturningID | ||
.select(['id', '=', insertReturn.id]) | ||
.select('id', '=', insertReturn.id) | ||
.getOne(); | ||
@@ -139,13 +140,19 @@ expect(readUser === null || readUser === void 0 ? void 0 : readUser.name).toEqual(updateValues2.name); | ||
const updateValues3 = { name: 'Replacement Sue' }; | ||
const updateReturns3 = yield userMapperReturningIDAndHandle | ||
const updateReturns3 = yield userMapperReturningIDAndHandleAsH | ||
.update({ name: 'Sue' }) | ||
.getAll(updateValues3); | ||
expect(updateReturns3.length).toEqual(3); | ||
expect(updateReturns3[0].handle).toEqual(test_objects_1.USERS[0].handle); | ||
expect(updateReturns3[1].handle).toEqual(test_objects_1.USERS[1].handle); | ||
expect(updateReturns3[2].handle).toEqual(test_objects_1.USERS[2].handle); | ||
expect(updateReturns3[0].h).toEqual(test_objects_1.USERS[0].handle); | ||
expect(updateReturns3[1].h).toEqual(test_objects_1.USERS[1].handle); | ||
expect(updateReturns3[2].h).toEqual(test_objects_1.USERS[2].handle); | ||
const readUsers = yield userMapperReturningID | ||
.select(['name', '=', updateValues3.name]) | ||
.select('name', '=', updateValues3.name) | ||
.getAll(); | ||
expect(readUsers.length).toEqual(3); | ||
(0, test_utils_1.ignore)('check return types', () => { | ||
// @ts-expect-error - check return types | ||
updateReturns2[0].title; | ||
// @ts-expect-error - check return types | ||
updateReturns2[0].userId; | ||
}); | ||
})); | ||
@@ -193,8 +200,9 @@ it('update returns void when defaulting to no return columns', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const updateValues = { email: 'new.email@xyz.pdq' }; | ||
const updateReturns = yield userMapperReturningIDAndHandle | ||
const updateReturns = yield userMapperReturningIDAndHandleAsH | ||
.update() | ||
.getAll(updateValues); | ||
const expectedUsers = test_objects_1.USERS.map((user, i) => { | ||
return { id: insertReturns[i].id, handle: user.handle }; | ||
}); | ||
const expectedUsers = test_objects_1.USERS.map((user, i) => ({ | ||
id: insertReturns[i].id, | ||
h: user.handle, | ||
})); | ||
expect(updateReturns).toEqual(expectedUsers); | ||
@@ -211,7 +219,7 @@ const readUsers = yield userMapperReturningID.select().getAll(); | ||
const updateCount = yield userMapperReturningAll | ||
.update(['id', '>', insertReturns[0].id]) | ||
.update('id', '>', insertReturns[0].id) | ||
.getCount(updateValues); | ||
expect(updateCount).toEqual(2); | ||
const readUsers = yield userMapperReturningID | ||
.select(['id', '>', insertReturns[0].id]) | ||
.select('id', '>', insertReturns[0].id) | ||
.getAll(); | ||
@@ -231,3 +239,3 @@ expect(readUsers.length).toEqual(2); | ||
const readUsers = yield userMapperReturningID | ||
.select(['id', '>', insertReturns[0].id]) | ||
.select('id', '>', insertReturns[0].id) | ||
.getAll(); | ||
@@ -273,7 +281,7 @@ expect(readUsers.length).toEqual(2); | ||
// @ts-expect-error - table must have all filter fields | ||
userMapperReturningID.update(['notThere', '=', 'foo']).getAll({ | ||
userMapperReturningID.update('notThere', '=', 'foo').getAll({ | ||
email: 'abc@def.ghi', | ||
}); | ||
// @ts-expect-error - table must have all filter fields | ||
userMapperReturningID.update(['notThere', '=', 'foo']).getAll({ | ||
userMapperReturningID.update('notThere', '=', 'foo').getAll({ | ||
email: 'abc@def.ghi', | ||
@@ -288,6 +296,2 @@ }); | ||
{ notThere: 'xyz@pdq.xyz' }); | ||
// @ts-expect-error - doesn't allow plain string expression filters | ||
userMapperReturningID.update("name = 'John Doe'", test_objects_1.USERS[0]); | ||
// @ts-expect-error - doesn't allow plain string expression filters | ||
userMapperReturningID.update("name = 'John Doe'", test_objects_1.USERS[0]); | ||
// @ts-expect-error - only requested columns are accessible | ||
@@ -309,2 +313,10 @@ // prettier-ignore | ||
.getAll(test_objects_1.USERS[0]); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapperReturningID.update('str'); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapperReturningID.update(['str']); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.update(1); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.update([1]); | ||
})); | ||
@@ -311,0 +323,0 @@ }); |
@@ -106,12 +106,8 @@ "use strict"; | ||
isMappedObject: (obj) => obj instanceof MappedUser, | ||
insertTransform: (user) => { | ||
return { | ||
name: `${user.firstName} ${user.lastName}`, | ||
handle: user.handle, | ||
email: user.email, | ||
}; | ||
}, | ||
insertReturnTransform: (user, returns) => { | ||
return new MappedUser(returns.id, user.firstName, user.lastName, user.handle, user.email); | ||
}, | ||
insertTransform: (user) => ({ | ||
name: `${user.firstName} ${user.lastName}`, | ||
handle: user.handle, | ||
email: user.email, | ||
}), | ||
insertReturnTransform: (user, returns) => new MappedUser(returns.id, user.firstName, user.lastName, user.handle, user.email), | ||
updateTransform: (user) => { | ||
@@ -171,3 +167,3 @@ if (!(user instanceof MappedUser)) { | ||
const updateColumnReturns = yield userMapper | ||
.update(['id', '=', insertReturn.serialNo]) | ||
.update('id', '=', insertReturn.serialNo) | ||
.getAll({ | ||
@@ -209,12 +205,8 @@ name: 'Foo Foo', | ||
isMappedObject: (obj) => obj instanceof MappedUser, | ||
insertTransform: (user) => { | ||
return { | ||
name: `${user.firstName} ${user.lastName}`, | ||
handle: user.handle, | ||
email: user.email, | ||
}; | ||
}, | ||
insertReturnTransform: (user, returns) => { | ||
return new MappedUser(returns.id, user.firstName, user.lastName, user.handle, user.email); | ||
}, | ||
insertTransform: (user) => ({ | ||
name: `${user.firstName} ${user.lastName}`, | ||
handle: user.handle, | ||
email: user.email, | ||
}), | ||
insertReturnTransform: (user, returns) => new MappedUser(returns.id, user.firstName, user.lastName, user.handle, user.email), | ||
selectTransform: (row) => { | ||
@@ -272,2 +264,26 @@ const names = row.name.split(' '); | ||
})); | ||
it('supports queries with no key columns', () => __awaiter(void 0, void 0, void 0, function* () { | ||
class MappedUser { | ||
constructor(id, name, handle, email) { | ||
this.id = id; | ||
this.name = name; | ||
this.handle = handle; | ||
this.email = email; | ||
} | ||
} | ||
const userMapper = new uniform_table_mapper_1.UniformTableMapper(db, 'users', { | ||
isMappedObject: (obj) => obj instanceof MappedUser, | ||
keyColumns: [], | ||
}); | ||
// test inserting a user | ||
const insertedUser = new MappedUser(0, // use 0 so we can tell it wasn't generated by the DB | ||
test_objects_1.insertedUser1.firstName, test_objects_1.insertedUser1.handle, test_objects_1.insertedUser1.email); | ||
const insertReturn = yield userMapper.insert().getOne(insertedUser); | ||
expect(insertReturn).toBeUndefined(); | ||
// test getting a user by ID | ||
const selectedUser1 = yield userMapper | ||
.select({ id: insertedUser.id }) | ||
.getOne(); | ||
expect(selectedUser1).toEqual(insertedUser); | ||
})); | ||
//# sourceMappingURL=UniformTableMapper.test.js.map |
@@ -9,5 +9,5 @@ import { Insertable, Kysely, Selectable } from 'kysely'; | ||
export declare class UserTableMapperReturningNothing extends TableMapper<Database, 'users', [ | ||
], [ | ||
'*' | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, [ | ||
], number> { | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, number> { | ||
readonly db: Kysely<Database>; | ||
@@ -17,15 +17,17 @@ constructor(db: Kysely<Database>); | ||
export declare class UserTableMapperReturningID extends TableMapper<Database, 'users', [ | ||
'id' | ||
], [ | ||
'*' | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, [ | ||
'id' | ||
], number> { | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, number> { | ||
readonly db: Kysely<Database>; | ||
constructor(db: Kysely<Database>); | ||
} | ||
export declare class UserTableMapperReturningIDAndHandle extends TableMapper<Database, 'users', [ | ||
export declare class UserTableMapperReturningIDAndHandleAsH extends TableMapper<Database, 'users', [ | ||
'id' | ||
], [ | ||
'*' | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, [ | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, number, [ | ||
'id', | ||
'handle' | ||
], number> { | ||
'handle as h' | ||
]> { | ||
readonly db: Kysely<Database>; | ||
@@ -35,6 +37,7 @@ constructor(db: Kysely<Database>); | ||
export declare class UserTableMapperReturningAll extends TableMapper<Database, 'users', [ | ||
], [ | ||
'*' | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, [ | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, number, [ | ||
'*' | ||
], number> { | ||
]> { | ||
readonly db: Kysely<Database>; | ||
@@ -41,0 +44,0 @@ constructor(db: Kysely<Database>); |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.UserTableMapperReturningAll = exports.UserTableMapperReturningIDAndHandle = exports.UserTableMapperReturningID = exports.UserTableMapperReturningNothing = exports.UserTableMapperReturningDefault = void 0; | ||
exports.UserTableMapperReturningAll = exports.UserTableMapperReturningIDAndHandleAsH = exports.UserTableMapperReturningID = exports.UserTableMapperReturningNothing = exports.UserTableMapperReturningDefault = void 0; | ||
const table_mapper_1 = require("../../mappers/table-mapper"); | ||
@@ -15,3 +15,3 @@ const countTransform = (count) => Number(count); | ||
constructor(db) { | ||
super(db, 'users', { returnColumns: [], countTransform }); | ||
super(db, 'users', { keyColumns: [], countTransform }); | ||
this.db = db; | ||
@@ -23,3 +23,3 @@ } | ||
constructor(db) { | ||
super(db, 'users', { returnColumns: ['id'], countTransform }); | ||
super(db, 'users', { keyColumns: ['id'], countTransform }); | ||
this.db = db; | ||
@@ -29,9 +29,13 @@ } | ||
exports.UserTableMapperReturningID = UserTableMapperReturningID; | ||
class UserTableMapperReturningIDAndHandle extends table_mapper_1.TableMapper { | ||
class UserTableMapperReturningIDAndHandleAsH extends table_mapper_1.TableMapper { | ||
constructor(db) { | ||
super(db, 'users', { returnColumns: ['id', 'handle'], countTransform }); | ||
super(db, 'users', { | ||
keyColumns: ['id'], | ||
returnColumns: ['id', 'handle as h'], | ||
countTransform, | ||
}); | ||
this.db = db; | ||
} | ||
} | ||
exports.UserTableMapperReturningIDAndHandle = UserTableMapperReturningIDAndHandle; | ||
exports.UserTableMapperReturningIDAndHandleAsH = UserTableMapperReturningIDAndHandleAsH; | ||
class UserTableMapperReturningAll extends table_mapper_1.TableMapper { | ||
@@ -38,0 +42,0 @@ constructor(db) { |
@@ -5,4 +5,6 @@ /** | ||
*/ | ||
import { ComparisonOperatorExpression, Expression, ExtractTypeFromStringReference, Kysely, OperandValueExpressionOrList, ReferenceExpression, SelectType, WhereExpressionFactory, WhereInterface } from 'kysely'; | ||
import { ComparisonOperatorExpression, Expression, ExtractTypeFromStringReference, Kysely, OperandValueExpressionOrList, ReferenceExpression, SelectType, Selectable, WhereExpressionFactory, WhereInterface } from 'kysely'; | ||
import { KeyTuple, SelectableColumnTuple } from './type-utils'; | ||
type AnyWhereInterface = WhereInterface<any, any>; | ||
type KeyColumnType<DB, TB extends keyof DB, K extends keyof Selectable<DB[TB]> & string> = NonNullable<Selectable<DB[TB]>[K]>; | ||
/** | ||
@@ -12,12 +14,4 @@ * Type of the query filter object, which can be passed as an argument | ||
*/ | ||
export type QueryFilter<DB, TB extends keyof DB & string, RE extends ReferenceExpression<DB, TB>, QB1 extends AnyWhereInterface, QB2 extends AnyWhereInterface> = BinaryOperationFilter<DB, TB, RE> | FieldMatchingFilter<DB, TB, RE> | QueryModifier<QB1, QB2> | WhereExpressionFactory<DB, TB> | Expression<any>; | ||
export type QueryFilter<DB, TB extends keyof DB & string, KeyColumns extends SelectableColumnTuple<DB[TB]> | [], RE extends ReferenceExpression<DB, TB>> = (KeyColumns extends [string] ? KeyColumnType<DB, TB, KeyColumns[0]> : never) | (KeyColumns extends [] ? never : Readonly<KeyTuple<DB[TB], KeyColumns>>) | FieldMatchingFilter<DB, TB, RE> | WhereExpressionFactory<DB, TB> | Expression<any>; | ||
/** | ||
* A filter that is a binary operation, such as `eq` or `gt`. | ||
*/ | ||
export type BinaryOperationFilter<DB, TB extends keyof DB & string, RE extends ReferenceExpression<DB, TB>> = [ | ||
lhs: RE, | ||
op: ComparisonOperatorExpression, | ||
rhs: OperandValueExpressionOrList<DB, TB, RE> | ||
]; | ||
/** | ||
* A filter that matches columns against the fields of an object. | ||
@@ -29,19 +23,14 @@ */ | ||
/** | ||
* A filter that is a function that takes a query builder and returns | ||
* a caller-modified query builder. | ||
*/ | ||
export declare class QueryModifier<QB1 extends AnyWhereInterface, QB2 extends AnyWhereInterface> { | ||
readonly modifier: (qb: QB1) => QB2; | ||
constructor(modifier: (qb: QB1) => QB2); | ||
} | ||
/** | ||
* Returns a query builder that constrains the provided query builder | ||
* according to the provided query filter. | ||
* according to the provided query filter or binary operation. | ||
* @param base The Kysely mapper that is used to create references. | ||
* @param qb The query builder to constrain. | ||
* @param filter The query filter. | ||
* @returns A query builder constrained for the provided query filter. | ||
* @param filterOrLHS The query filter or left-hand side of a binary operation. | ||
* @param op The operator of a binary operation. | ||
* @param rhs The right-hand side of a binary operation. | ||
* @returns A query builder constrained for the provided query filter | ||
* or binary operation. | ||
*/ | ||
export declare function applyQueryFilter<DB, TB extends keyof DB & string, QB1 extends AnyWhereInterface, QB2 extends AnyWhereInterface, RE extends ReferenceExpression<DB, TB>>(db: Kysely<DB>, qb: QB1, filter: QueryFilter<DB, TB, RE, QB1, QB2>): QB2; | ||
export declare function applyQueryFilter<DB, TB extends keyof DB & string, KeyColumns extends SelectableColumnTuple<DB[TB]> | [], QB extends AnyWhereInterface, RE extends ReferenceExpression<DB, TB>>(db: Kysely<DB>, qb: QB, keyColumns: KeyColumns, filterOrLHS: QueryFilter<DB, TB, KeyColumns, RE> | RE, op?: ComparisonOperatorExpression, rhs?: OperandValueExpressionOrList<DB, TB, RE>): QB; | ||
export {}; | ||
//# sourceMappingURL=query-filter.d.ts.map |
@@ -6,19 +6,39 @@ /** | ||
/** | ||
* A filter that is a function that takes a query builder and returns | ||
* a caller-modified query builder. | ||
*/ | ||
export class QueryModifier { | ||
constructor(modifier) { | ||
this.modifier = modifier; | ||
} | ||
} | ||
/** | ||
* Returns a query builder that constrains the provided query builder | ||
* according to the provided query filter. | ||
* according to the provided query filter or binary operation. | ||
* @param base The Kysely mapper that is used to create references. | ||
* @param qb The query builder to constrain. | ||
* @param filter The query filter. | ||
* @returns A query builder constrained for the provided query filter. | ||
* @param filterOrLHS The query filter or left-hand side of a binary operation. | ||
* @param op The operator of a binary operation. | ||
* @param rhs The right-hand side of a binary operation. | ||
* @returns A query builder constrained for the provided query filter | ||
* or binary operation. | ||
*/ | ||
export function applyQueryFilter(db, qb, filter) { | ||
export function applyQueryFilter(db, qb, keyColumns, filterOrLHS, op, rhs) { | ||
// Process a binary operation. | ||
if (op !== undefined) { | ||
return qb.where(filterOrLHS, op, rhs); | ||
} | ||
const filter = filterOrLHS; | ||
if (typeof filter === 'object') { | ||
// Process a key tuple filter. | ||
if (Array.isArray(filter)) { | ||
keyColumns.forEach((column, i) => { | ||
qb = qb.where(db.dynamic.ref(column), '=', filter[i]); | ||
}); | ||
return qb; | ||
} | ||
// Process a query expression filter. Check for expressions | ||
// first because they could potentially be plain objects. | ||
if ('expressionType' in filter) { | ||
return qb.where(filter); | ||
} | ||
// Process a field matching filter. `{}` matches all rows. | ||
if (filter.constructor === Object) { | ||
for (const [column, value] of Object.entries(filter)) { | ||
qb = qb.where(db.dynamic.ref(column), '=', value); | ||
} | ||
return qb; | ||
} | ||
} | ||
// Process a where expression factory. | ||
@@ -28,25 +48,8 @@ if (typeof filter === 'function') { | ||
} | ||
// Process a query expression filter. Check for expressions | ||
// first because they could potentially be plain objects. | ||
if ('expressionType' in filter) { | ||
return qb.where(filter); | ||
// Process a single key filter, expressed as a primitive value. | ||
if (keyColumns.length === 1) { | ||
return qb.where(db.dynamic.ref(keyColumns[0]), '=', filter); | ||
} | ||
// TODO: delete this | ||
// Process a query modifier filter. | ||
if (filter instanceof QueryModifier) { | ||
return filter.modifier(qb); | ||
} | ||
// Process a field matching filter. `{}` matches all rows. | ||
if (filter.constructor === Object) { | ||
for (const [column, value] of Object.entries(filter)) { | ||
qb = qb.where(db.dynamic.ref(column), '=', value); | ||
} | ||
return qb; | ||
} | ||
// Process a binary operation filter. | ||
if (Array.isArray(filter)) { | ||
return qb.where(...filter); | ||
} | ||
throw Error('Unrecognized query filter'); | ||
} | ||
//# sourceMappingURL=query-filter.js.map |
@@ -6,14 +6,8 @@ /** | ||
/** | ||
* Converts a key of object O to a string of the form `${K} as ${string}`, | ||
* where K is the key. | ||
* @typeparam O Object whose keys are to be converted to strings. | ||
* @typeparam K Key of O. | ||
*/ | ||
/** | ||
* Type of the primary key tuple whose column names are given by `KA` and are | ||
* Type of the key tuple whose column names are given by `KA` and are | ||
* found in the table interface `T`. Supports up to 4 columns. | ||
* @typeparam T Table interface. | ||
* @typeparam KA Array of the primary key column names. | ||
* @typeparam KA Array of the key column names. | ||
*/ | ||
export type KeyTuple<T, KA extends (keyof Selectable<T> & string)[]> = Selectable<T>[KA[3]] extends string ? [ | ||
export type KeyTuple<T, KA extends (keyof Selectable<T> & string)[]> = KA[3] extends string ? [ | ||
Selectable<T>[KA[0]], | ||
@@ -23,11 +17,4 @@ Selectable<T>[KA[1]], | ||
Selectable<T>[KA[3]] | ||
] : Selectable<T>[KA[2]] extends string ? [Selectable<T>[KA[0]], Selectable<T>[KA[1]], Selectable<T>[KA[2]]] : Selectable<T>[KA[1]] extends string ? [Selectable<T>[KA[0]], Selectable<T>[KA[1]]] : [Selectable<T>[KA[0]]]; | ||
] : KA[2] extends string ? [Selectable<T>[KA[0]], Selectable<T>[KA[1]], Selectable<T>[KA[2]]] : KA[1] extends string ? [Selectable<T>[KA[0]], Selectable<T>[KA[1]]] : [Selectable<T>[KA[0]]]; | ||
/** | ||
* Evaluates to the subset of a the given object having the keys in | ||
* the provided string array of key names. | ||
*/ | ||
export type ObjectWithKeys<O, KeyArray extends string[]> = { | ||
[K in KeyArray[number]]: K extends keyof O ? O[K] : never; | ||
}; | ||
/** | ||
* Evalutes to the type of the query builder output. | ||
@@ -34,0 +21,0 @@ */ |
@@ -1,3 +0,3 @@ | ||
import { Insertable, Selectable, Updateable } from 'kysely'; | ||
import { ObjectWithKeys, SelectedRow, SelectionColumn } from '../lib/type-utils'; | ||
import { Insertable, Selectable, Selection, Updateable } from 'kysely'; | ||
import { SelectableColumnTuple, SelectedRow, SelectionColumn } from '../lib/type-utils'; | ||
/** | ||
@@ -7,9 +7,14 @@ * Options governing TableMapper behavior. | ||
* @typeparam TB Name of the table. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `[]`, indicating no key columns. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam SelectedObject Type of objects returned by select queries. | ||
* @typeparam InsertedObject Type of objects inserted into the table. | ||
* @typeparam UpdatingObject Type of objects used to update rows of the table. | ||
* @typeparam ReturnCount Type of count query results. | ||
* @typeparam ReturnColumns Columns to return from the table on insert or | ||
* update, except when explicitly requesting no columns. `['*']` returns | ||
* all columns; `[]` returns none and is the default. | ||
* @typeparam ReturnCount Type of count query results. | ||
* all columns; `[]` returns none and is the default. May specify aliases. | ||
* Defaults to `KeyColumns`. | ||
* @typeparam InsertReturnsSelectedObject Whether insert queries return | ||
@@ -23,3 +28,10 @@ * `SelectedObject` or `DefaultReturnObject`. | ||
*/ | ||
export interface TableMapperOptions<DB, TB extends keyof DB & string, SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], SelectedObject extends object = SelectedRow<DB, TB, SelectedColumns extends ['*'] ? never : SelectedColumns[number], SelectedColumns>, InsertedObject extends object = Insertable<DB[TB]>, UpdatingObject extends object = Partial<Insertable<DB[TB]>>, ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'] = [], ReturnCount = bigint, InsertReturnsSelectedObject extends boolean = false, UpdateReturnsSelectedObjectWhenProvided extends boolean = false, DefaultReturnObject extends object = ReturnColumns extends ['*'] ? Selectable<DB[TB]> : ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>> { | ||
export interface TableMapperOptions<DB, TB extends keyof DB & string, KeyColumns extends SelectableColumnTuple<DB[TB]> | [] = [], SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], SelectedObject extends object = SelectedRow<DB, TB, SelectedColumns extends ['*'] ? never : SelectedColumns[number], SelectedColumns>, InsertedObject extends object = Insertable<DB[TB]>, UpdatingObject extends object = Partial<Insertable<DB[TB]>>, ReturnCount = bigint, ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'] = KeyColumns, InsertReturnsSelectedObject extends boolean = false, UpdateReturnsSelectedObjectWhenProvided extends boolean = false, DefaultReturnObject extends object = ReturnColumns extends ['*'] ? Selectable<DB[TB]> : Selection<DB, TB, ReturnColumns[number]>> { | ||
/** Tuple of the columns that make up the table's key. May be `[]`. */ | ||
readonly keyColumns?: KeyColumns; | ||
/** | ||
* Columns to return from selection queries. `[*]` selects all columns. | ||
* May contain aliases. | ||
*/ | ||
readonly selectedColumns?: SelectedColumns; | ||
/** Transformation to apply to inserted objects before insertion. */ | ||
@@ -36,4 +48,2 @@ readonly insertTransform?: (obj: InsertedObject) => Insertable<DB[TB]>; | ||
readonly updateReturnsSelectedObjectWhenProvided?: UpdateReturnsSelectedObjectWhenProvided; | ||
/** Columns to return from selection queries. */ | ||
readonly selectedColumns?: SelectedColumns; | ||
/** Transformation to apply to selected objects. */ | ||
@@ -44,8 +54,9 @@ readonly selectTransform?: (row: SelectedRow<DB, TB, SelectedColumns extends ['*'] ? never : SelectedColumns[number], SelectedColumns>) => SelectedObject; | ||
* requesting no columns. `['*']` returns all columns; `[]` returns none. | ||
* May contain aliases. | ||
*/ | ||
readonly returnColumns?: ReturnColumns; | ||
/** Transformation to apply to column values returned from inserts. */ | ||
readonly insertReturnTransform?: (source: InsertedObject, returns: ReturnColumns extends [] ? never : ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject; | ||
readonly insertReturnTransform?: (source: InsertedObject, returns: ReturnColumns extends [] ? never : Selection<DB, TB, ReturnColumns[number]>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject; | ||
/** Transformation to apply to column values returned from updates. */ | ||
readonly updateReturnTransform?: (source: UpdatingObject, returns: ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject; | ||
readonly updateReturnTransform?: (source: UpdatingObject, returns: Selection<DB, TB, ReturnColumns[number]>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject; | ||
/** Transformation to apply to bigint count results. */ | ||
@@ -52,0 +63,0 @@ readonly countTransform?: (count: bigint) => ReturnCount; |
@@ -1,4 +0,4 @@ | ||
import { Kysely, Insertable, ReferenceExpression, Selectable, InsertQueryBuilder, InsertResult, SelectQueryBuilder, Selection, DeleteQueryBuilder, DeleteResult, UpdateResult, UpdateQueryBuilder } from 'kysely'; | ||
import { Kysely, Insertable, ReferenceExpression, Selectable, InsertQueryBuilder, InsertResult, SelectQueryBuilder, Selection, DeleteQueryBuilder, DeleteResult, UpdateResult, UpdateQueryBuilder, ComparisonOperatorExpression, OperandValueExpressionOrList } from 'kysely'; | ||
import { QueryFilter } from '../lib/query-filter'; | ||
import { ObjectWithKeys, SelectedRow, SelectionColumn } from '../lib/type-utils'; | ||
import { SelectableColumnTuple, SelectedRow, SelectionColumn } from '../lib/type-utils'; | ||
import { TableMapperOptions } from './table-mapper-options'; | ||
@@ -14,2 +14,6 @@ import { MappingDeleteQuery } from '../queries/delete-query'; | ||
* @typeparam TB Name of the table. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `[]`, indicating no key columns. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam SelectedObject Type of objects returned by select queries. | ||
@@ -21,3 +25,4 @@ * @typeparam InsertedObject Type of objects inserted into the table. | ||
* update, except when explicitly requesting no columns. `['*']` returns | ||
* all columns; `[]` returns none and is the default. | ||
* all columns; `[]` returns none and is the default. May specify aliases. | ||
* Defaults to `KeyColumns`. | ||
* @typeparam InsertReturnsSelectedObject Whether insert queries return | ||
@@ -31,11 +36,13 @@ * `SelectedObject` or `DefaultReturnObject`. | ||
*/ | ||
export declare class TableMapper<DB, TB extends keyof DB & string, SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], SelectedObject extends object = SelectedRow<DB, TB, SelectedColumns extends ['*'] ? never : SelectedColumns[number], SelectedColumns>, InsertedObject extends object = Insertable<DB[TB]>, UpdatingObject extends object = Partial<Insertable<DB[TB]>>, ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'] = [], ReturnCount = bigint, InsertReturnsSelectedObject extends boolean = false, UpdateReturnsSelectedObjectWhenProvided extends boolean = false, DefaultReturnObject extends object = ReturnColumns extends ['*'] ? Selectable<DB[TB]> : ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>> { | ||
export declare class TableMapper<DB, TB extends keyof DB & string, KeyColumns extends SelectableColumnTuple<DB[TB]> | [] = [], SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], SelectedObject extends object = SelectedRow<DB, TB, SelectedColumns extends ['*'] ? never : SelectedColumns[number], SelectedColumns>, InsertedObject extends object = Insertable<DB[TB]>, UpdatingObject extends object = Partial<Insertable<DB[TB]>>, ReturnCount = bigint, ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'] = KeyColumns, InsertReturnsSelectedObject extends boolean = false, UpdateReturnsSelectedObjectWhenProvided extends boolean = false, DefaultReturnObject extends object = ReturnColumns extends ['*'] ? Selectable<DB[TB]> : Selection<DB, TB, ReturnColumns[number]>> { | ||
#private; | ||
readonly db: Kysely<DB>; | ||
readonly tableName: TB; | ||
readonly options: TableMapperOptions<DB, TB, SelectedColumns, SelectedObject, InsertedObject, UpdatingObject, ReturnColumns, ReturnCount, InsertReturnsSelectedObject, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>; | ||
readonly options: TableMapperOptions<DB, TB, KeyColumns, SelectedColumns, SelectedObject, InsertedObject, UpdatingObject, ReturnCount, ReturnColumns, InsertReturnsSelectedObject, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>; | ||
/** Columns that compose the table's primary key. */ | ||
protected readonly keyColumns: KeyColumns; | ||
/** Columns to return from selection queries. `[]` => all columns. */ | ||
protected readonly selectedColumns: SelectionColumn<DB, TB>[]; | ||
/** Columns to return from the table on insert or update. */ | ||
protected returnColumns: (keyof Selectable<DB[TB]> & string)[] | ['*']; | ||
protected returnColumns: SelectionColumn<DB, TB>[] | ['*']; | ||
/** Transforms query counts into `ReturnCount`. */ | ||
@@ -50,3 +57,3 @@ protected countTransform: (count: bigint) => ReturnCount; | ||
*/ | ||
constructor(db: Kysely<DB>, tableName: TB, options?: TableMapperOptions<DB, TB, SelectedColumns, SelectedObject, InsertedObject, UpdatingObject, ReturnColumns, ReturnCount, InsertReturnsSelectedObject, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>); | ||
constructor(db: Kysely<DB>, tableName: TB, options?: TableMapperOptions<DB, TB, KeyColumns, SelectedColumns, SelectedObject, InsertedObject, UpdatingObject, ReturnCount, ReturnColumns, InsertReturnsSelectedObject, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>); | ||
/** | ||
@@ -70,7 +77,10 @@ * Creates and returns a parameterized mapping query, which can be repeatedly | ||
/** | ||
* Returns a mapping query for deleting rows from the table. | ||
* @param filter Optional filter for selecting rows to delete. | ||
* Returns a mapping query for deleting the rows of the table that match | ||
* the provided filter or Kysely binary operation. | ||
* @param filter Optional filter to apply to the query or the left-hand-side | ||
* of a Kysely binary operation. | ||
* @returns A mapping query for deleting rows. | ||
*/ | ||
delete<RE extends ReferenceExpression<DB, TB>, QB extends DeleteQueryBuilder<DB, TB, DeleteResult>>(filter?: QueryFilter<DB, TB, RE, DeleteQueryBuilder<DB, any, DeleteResult>, QB>): MappingDeleteQuery<DB, TB, DeleteQueryBuilder<DB, TB, DeleteResult>, ReturnCount>; | ||
delete<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: ComparisonOperatorExpression, rhs: OperandValueExpressionOrList<DB, TB, RE>): MappingDeleteQuery<DB, TB, DeleteQueryBuilder<DB, TB, DeleteResult>, ReturnCount>; | ||
delete<RE extends ReferenceExpression<DB, TB>>(filter?: QueryFilter<DB, TB, KeyColumns, RE>): MappingDeleteQuery<DB, TB, DeleteQueryBuilder<DB, TB, DeleteResult>, ReturnCount>; | ||
/** | ||
@@ -89,14 +99,18 @@ * Returns a query for inserting rows into the table. | ||
* Returns a mapping query for selecting rows of the table that match | ||
* the provided filter. | ||
* @param filter Optional filter to apply to the query. | ||
* the provided filter or Kysely binary operation. | ||
* @param filter Optional filter to apply to the query or the left-hand-side | ||
* of a Kysely binary operation. | ||
* @returns A mapping query for retrieving rows as objects. | ||
*/ | ||
select<RE extends ReferenceExpression<DB, TB>, QB extends SelectQueryBuilder<DB, TB, object>>(filter?: QueryFilter<DB, TB, RE, SelectQueryBuilder<DB, TB, object>, QB>): MappingSelectQuery<DB, TB, SelectedColumns, SelectedObject, SelectQueryBuilder<DB, TB, object>>; | ||
select<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: ComparisonOperatorExpression, rhs: OperandValueExpressionOrList<DB, TB, RE>): MappingSelectQuery<DB, TB, SelectedColumns, SelectedObject, SelectQueryBuilder<DB, TB, object>>; | ||
select<RE extends ReferenceExpression<DB, TB>>(filter?: QueryFilter<DB, TB, KeyColumns, RE>): MappingSelectQuery<DB, TB, SelectedColumns, SelectedObject, SelectQueryBuilder<DB, TB, object>>; | ||
/** | ||
* Returns a mapping query for updating rows of the table that match | ||
* the provided filter. | ||
* @param filter Optional filter to apply to the query. | ||
* the provided filter or Kysely binary operation. | ||
* @param filter Optional filter to apply to the query or the left-hand-side | ||
* of a Kysely binary operation. | ||
* @returns A mapping query for updating table rows. | ||
*/ | ||
update<RE extends ReferenceExpression<DB, TB>, QB extends UpdateQueryBuilder<DB, TB, TB, UpdateResult>>(filter?: QueryFilter<DB, TB, RE, UpdateQueryBuilder<DB, TB, TB, UpdateResult>, QB>): MappingUpdateQuery<DB, TB, UpdateQueryBuilder<DB, TB, TB, UpdateResult>, UpdatingObject, SelectedObject, ReturnColumns, ReturnCount, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>; | ||
update<RE extends ReferenceExpression<DB, TB>>(lhs: RE, op: ComparisonOperatorExpression, rhs: OperandValueExpressionOrList<DB, TB, RE>): MappingUpdateQuery<DB, TB, UpdateQueryBuilder<DB, TB, TB, UpdateResult>, UpdatingObject, SelectedObject, ReturnColumns, ReturnCount, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>; | ||
update<RE extends ReferenceExpression<DB, TB>>(filter?: QueryFilter<DB, TB, KeyColumns, RE>): MappingUpdateQuery<DB, TB, UpdateQueryBuilder<DB, TB, TB, UpdateResult>, UpdatingObject, SelectedObject, ReturnColumns, ReturnCount, UpdateReturnsSelectedObjectWhenProvided, DefaultReturnObject>; | ||
/** | ||
@@ -103,0 +117,0 @@ * Returns a query builder for deleting rows from the table, caching the |
@@ -18,3 +18,2 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
import { MappingUpdateQuery } from '../queries/update-query'; | ||
// TODO: change [binary op] notation to three parameters | ||
/** | ||
@@ -24,2 +23,6 @@ * A mapper providing access to a single table. | ||
* @typeparam TB Name of the table. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `[]`, indicating no key columns. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam SelectedObject Type of objects returned by select queries. | ||
@@ -31,3 +34,4 @@ * @typeparam InsertedObject Type of objects inserted into the table. | ||
* update, except when explicitly requesting no columns. `['*']` returns | ||
* all columns; `[]` returns none and is the default. | ||
* all columns; `[]` returns none and is the default. May specify aliases. | ||
* Defaults to `KeyColumns`. | ||
* @typeparam InsertReturnsSelectedObject Whether insert queries return | ||
@@ -50,3 +54,3 @@ * `SelectedObject` or `DefaultReturnObject`. | ||
constructor(db, tableName, options = {}) { | ||
var _a; | ||
var _a, _b; | ||
this.db = db; | ||
@@ -60,4 +64,6 @@ this.tableName = tableName; | ||
/** Transforms query counts into `ReturnCount`. */ | ||
// TODO: readonly? | ||
this.countTransform = (count) => count; | ||
this.returnColumns = (_a = options.returnColumns) !== null && _a !== void 0 ? _a : []; | ||
this.keyColumns = (_a = options.keyColumns) !== null && _a !== void 0 ? _a : []; | ||
this.returnColumns = (_b = options.returnColumns) !== null && _b !== void 0 ? _b : this.keyColumns; | ||
this.selectedColumns = | ||
@@ -73,48 +79,6 @@ options.selectedColumns === undefined | ||
} | ||
/** | ||
* Creates and returns a parameterized mapping query, which can be repeatedly | ||
* executed with different parameter values, but which only ever compiles | ||
* the underlying Kysely query once (on the first execution). | ||
* @paramtype P Record characterizing the available parameter names and types. | ||
* @param factory Function that receives an object of the form `{ q, param }`, | ||
* where `q` is a mapping query and `param` is a function for creating | ||
* parameters. The argument to `param` is the name of the parameter, which | ||
* must occur as a property of `P`. You may parameterize inserted values, | ||
* updated values, and right-hand-side values of filters. Parameters may not | ||
* be arrays, but you can parameterize the individual elements of an array. | ||
* Returns a mapping query that containing the parameterized values. | ||
* @returns a parameterized mapping query | ||
*/ | ||
// compile<P extends ParametersObject<P>>( | ||
// factory: ParamedSelectionQueryFactory< | ||
// P, | ||
// MappingSelectQuery<DB, TB, SelectedObject, QB> | ||
// > | ||
// ): ParameterizedRowQuery<P, SelectedObject> { | ||
// const parameterMaker = new QueryParameterMaker<P>(); | ||
// return new ParameterizedRowQuery( | ||
// factory({ | ||
// q: this, | ||
// param: parameterMaker.param.bind(parameterMaker), | ||
// }).qb, | ||
// ); | ||
// } | ||
/** | ||
* Factory function for parameterizing MappingSelectQuery. | ||
*/ | ||
// interface ParamedSelectionQueryFactory< | ||
// P extends ParametersObject<P>, | ||
// Q extends MappingSelectQuery<any, any, any, any> | ||
// > { | ||
// (args: { q: Q; param: QueryParameterMaker<P>['param'] }): Q; | ||
// } | ||
/** | ||
* Returns a mapping query for deleting rows from the table. | ||
* @param filter Optional filter for selecting rows to delete. | ||
* @returns A mapping query for deleting rows. | ||
*/ | ||
delete(filter) { | ||
return new MappingDeleteQuery(this.db, filter === undefined | ||
delete(filterOrLHS, op, rhs) { | ||
return new MappingDeleteQuery(this.db, filterOrLHS === undefined | ||
? this.getDeleteQB() | ||
: applyQueryFilter(this.db, this.getDeleteQB(), filter), this.countTransform); | ||
: applyQueryFilter(this.db, this.getDeleteQB(), this.keyColumns, filterOrLHS, op, rhs), this.countTransform); | ||
} | ||
@@ -127,3 +91,3 @@ // TODO: support listing inserted columns | ||
insert() { | ||
return new MappingInsertQuery(this.db, this.getInsertQB(), this.options.insertTransform, this.options.returnColumns, this.options.insertReturnTransform); | ||
return new MappingInsertQuery(this.db, this.getInsertQB(), this.options.insertTransform, this.returnColumns, this.options.insertReturnTransform); | ||
} | ||
@@ -135,26 +99,15 @@ /** | ||
*/ | ||
// TODO: do I need this? | ||
ref(column) { | ||
return this.db.dynamic.ref(column); | ||
} | ||
/** | ||
* Returns a mapping query for selecting rows of the table that match | ||
* the provided filter. | ||
* @param filter Optional filter to apply to the query. | ||
* @returns A mapping query for retrieving rows as objects. | ||
*/ | ||
select(filter) { | ||
return new MappingSelectQuery(this.db, filter === undefined | ||
select(filterOrLHS, op, rhs) { | ||
return new MappingSelectQuery(this.db, filterOrLHS === undefined | ||
? this.getSelectQB() | ||
: applyQueryFilter(this.db, this.getSelectQB(), filter), this.options.selectTransform); | ||
: applyQueryFilter(this.db, this.getSelectQB(), this.keyColumns, filterOrLHS, op, rhs), this.options.selectTransform); | ||
} | ||
/** | ||
* Returns a mapping query for updating rows of the table that match | ||
* the provided filter. | ||
* @param filter Optional filter to apply to the query. | ||
* @returns A mapping query for updating table rows. | ||
*/ | ||
update(filter) { | ||
return new MappingUpdateQuery(this.db, filter === undefined | ||
update(filterOrLHS, op, rhs) { | ||
return new MappingUpdateQuery(this.db, filterOrLHS === undefined | ||
? this.getUpdateQB() | ||
: applyQueryFilter(this.db, this.getUpdateQB(), filter), this.countTransform, this.options.updateTransform, this.options.returnColumns, this.options.updateReturnTransform); | ||
: applyQueryFilter(this.db, this.getUpdateQB(), this.keyColumns, filterOrLHS, op, rhs), this.countTransform, this.options.updateTransform, this.returnColumns, this.options.updateReturnTransform); | ||
} | ||
@@ -161,0 +114,0 @@ /** |
@@ -1,2 +0,2 @@ | ||
import { Insertable, Selectable } from 'kysely'; | ||
import { Insertable } from 'kysely'; | ||
import { SelectableColumnTuple, SelectionColumn } from '../lib/type-utils'; | ||
@@ -11,12 +11,13 @@ import { TableMapperOptions } from './table-mapper-options'; | ||
* as columns of the table. | ||
* @typeparam PrimaryKeyColumns Tuple of the names of the primary key columns. | ||
* Defaults to `['id']`. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `['id']`. `[]` indicates no key columns. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam ReturnColumns The columns that are returned from the database | ||
* when selecting or updating rows, for use when creating the mapped objects. | ||
* `['*']` returns all columns; `[]` returns none. Defaults to `PrimaryKeyColumns`. | ||
* `['*']` returns all columns; `[]` returns none. May specify aliases. | ||
* Defaults to `KeyColumns`. | ||
* @typeparam ReturnCount Type of count query results. | ||
*/ | ||
export interface UniformTableMapperOptions<DB, TB extends keyof DB & string, MappedObject extends object, PrimaryKeyColumns extends SelectableColumnTuple<DB[TB]>, SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'], ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'], ReturnCount> extends TableMapperOptions<DB, TB, SelectedColumns, MappedObject, MappedObject, MappedObject | Partial<Insertable<DB[TB]>>, ReturnColumns, ReturnCount, true, true> { | ||
/** Columns that make up the primary key of the table. */ | ||
readonly primaryKeyColumns?: PrimaryKeyColumns; | ||
export interface UniformTableMapperOptions<DB, TB extends keyof DB & string, MappedObject extends object, KeyColumns extends SelectableColumnTuple<DB[TB]> | [], SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'], ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'], ReturnCount> extends TableMapperOptions<DB, TB, KeyColumns, SelectedColumns, MappedObject, MappedObject, MappedObject | Partial<Insertable<DB[TB]>>, ReturnCount, ReturnColumns, true, true> { | ||
/** Indicates whether the provided object is an instance of `MappedObject`. */ | ||
@@ -23,0 +24,0 @@ readonly isMappedObject: (obj: any) => boolean; |
@@ -1,2 +0,2 @@ | ||
import { Insertable, Kysely, Selectable } from 'kysely'; | ||
import { Insertable, Kysely } from 'kysely'; | ||
import { TableMapper } from './table-mapper'; | ||
@@ -8,4 +8,3 @@ import { SelectableColumn, SelectableColumnTuple, SelectionColumn } from '../lib/type-utils'; | ||
/** | ||
* A mapper for a table representing a store of objects, where each object has a | ||
* unique identifying key given by one or more primary key columns. | ||
* A mapper for a table representing a store of objects. | ||
* @typeparam DB The database type. | ||
@@ -16,21 +15,25 @@ * @typeparam TB The name of the table. | ||
* as columns of the table. | ||
* @typeparam PrimaryKeyColumns Tuple of the names of the primary key columns. | ||
* Defaults to `['id']`. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `['id']`. By default, falsy key values are assumed to require | ||
* generation and `insertTransform` removes them from the insertion. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam ReturnCount Type of count query results. | ||
* @typeparam ReturnColumns The columns that are returned from the database | ||
* when selecting or updating rows, for use when creating the mapped objects. | ||
* `['*']` returns all columns; `[]` returns none. Defaults to `PrimaryKeyColumns`. | ||
* @typeparam ReturnCount Type of count query results. | ||
* when selecting or updating rows, for use when creating mapped objects. | ||
* `['*']` returns all columns; `[]` returns none. By default, the columns | ||
* are added to objects returned on update. Defaults to `KeyColumns`. | ||
*/ | ||
export declare class UniformTableMapper<DB, TB extends keyof DB & string, MappedObject extends object, PrimaryKeyColumns extends SelectableColumnTuple<DB[TB]> = [ | ||
export declare class UniformTableMapper<DB, TB extends keyof DB & string, MappedObject extends object, KeyColumns extends SelectableColumnTuple<DB[TB]> | [] = [ | ||
'id' & SelectableColumn<DB[TB]> | ||
], SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], ReturnCount = bigint, ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'] = PrimaryKeyColumns> extends TableMapper<DB, TB, SelectedColumns, MappedObject, MappedObject, MappedObject | Partial<Insertable<DB[TB]>>, ReturnColumns, ReturnCount, true, true> { | ||
], SelectedColumns extends SelectionColumn<DB, TB>[] | ['*'] = ['*'], ReturnCount = bigint, ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'] = KeyColumns> extends TableMapper<DB, TB, KeyColumns, SelectedColumns, MappedObject, MappedObject, MappedObject | Partial<Insertable<DB[TB]>>, ReturnCount, ReturnColumns, true, true> { | ||
/** | ||
* @param db The Kysely database instance. | ||
* @param tableName The name of the table. | ||
* @param options Options governing mapper behavior. Default to a | ||
* primary key of `id`, to selecting all columns, and to returning | ||
* @param options Options governing mapper behavior. Defaults to | ||
* a key of `id`, to selecting all columns, and to returning | ||
* the `id` on insert or update, when the caller requests returns. | ||
*/ | ||
constructor(db: Kysely<DB>, tableName: TB, options: UniformTableMapperOptions<DB, TB, MappedObject, PrimaryKeyColumns, SelectedColumns, ReturnColumns, ReturnCount>); | ||
constructor(db: Kysely<DB>, tableName: TB, options: UniformTableMapperOptions<DB, TB, MappedObject, KeyColumns, SelectedColumns, ReturnColumns, ReturnCount>); | ||
} | ||
//# sourceMappingURL=uniform-table-mapper.d.ts.map |
@@ -7,4 +7,3 @@ import { TableMapper } from './table-mapper'; | ||
/** | ||
* A mapper for a table representing a store of objects, where each object has a | ||
* unique identifying key given by one or more primary key columns. | ||
* A mapper for a table representing a store of objects. | ||
* @typeparam DB The database type. | ||
@@ -15,8 +14,12 @@ * @typeparam TB The name of the table. | ||
* as columns of the table. | ||
* @typeparam PrimaryKeyColumns Tuple of the names of the primary key columns. | ||
* Defaults to `['id']`. | ||
* @typeparam KeyColumns Tuple of the names of the table's key columns. | ||
* Defaults to `['id']`. By default, falsy key values are assumed to require | ||
* generation and `insertTransform` removes them from the insertion. | ||
* @typeparam SelectedColumns Columns to return from selection queries. | ||
* Defaults to `['*']`, returning all columns. May specify aliases. | ||
* @typeparam ReturnCount Type of count query results. | ||
* @typeparam ReturnColumns The columns that are returned from the database | ||
* when selecting or updating rows, for use when creating the mapped objects. | ||
* `['*']` returns all columns; `[]` returns none. Defaults to `PrimaryKeyColumns`. | ||
* @typeparam ReturnCount Type of count query results. | ||
* when selecting or updating rows, for use when creating mapped objects. | ||
* `['*']` returns all columns; `[]` returns none. By default, the columns | ||
* are added to objects returned on update. Defaults to `KeyColumns`. | ||
*/ | ||
@@ -27,4 +30,4 @@ export class UniformTableMapper extends TableMapper { | ||
* @param tableName The name of the table. | ||
* @param options Options governing mapper behavior. Default to a | ||
* primary key of `id`, to selecting all columns, and to returning | ||
* @param options Options governing mapper behavior. Defaults to | ||
* a key of `id`, to selecting all columns, and to returning | ||
* the `id` on insert or update, when the caller requests returns. | ||
@@ -41,7 +44,7 @@ */ | ||
var _a; | ||
const primaryKeyColumns = (_a = options.primaryKeyColumns) !== null && _a !== void 0 ? _a : DEFAULT_KEY; | ||
// Remove primary keys from inserted object, by default | ||
const keyColumns = (_a = options.keyColumns) !== null && _a !== void 0 ? _a : DEFAULT_KEY; | ||
// Remove falsy key values from inserted object, by default | ||
const insertTransform = (obj) => { | ||
const insertedValues = Object.assign({}, obj); | ||
primaryKeyColumns.forEach((column) => { | ||
keyColumns.forEach((column) => { | ||
if (!obj[column]) { | ||
@@ -54,7 +57,5 @@ delete insertedValues[column]; | ||
// Add returned values to inserted object, by default | ||
const insertReturnTransform = (obj, returns) => { | ||
return Object.assign(Object.assign({}, obj), returns); | ||
}; | ||
// Use insert transform by default; or if none is provided, remove primary | ||
// keys from inserted object if the object is a `MappedObject`. | ||
const insertReturnTransform = (obj, returns) => (Object.assign(Object.assign({}, obj), returns)); | ||
// Use insert transform by default; or if none is provided, remove falsy | ||
// key values from inserted object if the object is a `MappedObject`. | ||
const updateTransform = options.insertTransform !== undefined | ||
@@ -71,8 +72,8 @@ ? options.insertTransform | ||
: options.insertReturnTransform(obj, returns); | ||
return Object.assign({ primaryKeyColumns, | ||
return Object.assign({ keyColumns, | ||
insertTransform, | ||
insertReturnTransform, | ||
updateTransform, | ||
updateReturnTransform, returnColumns: primaryKeyColumns }, options); | ||
updateReturnTransform, returnColumns: keyColumns }, options); | ||
} | ||
//# sourceMappingURL=uniform-table-mapper.js.map |
@@ -1,7 +0,7 @@ | ||
import { Kysely, InsertQueryBuilder, InsertResult, Selectable, Insertable } from 'kysely'; | ||
import { ObjectWithKeys } from '../lib/type-utils'; | ||
import { Kysely, InsertQueryBuilder, InsertResult, Selection, Insertable } from 'kysely'; | ||
import { SelectionColumn } from '../lib/type-utils'; | ||
/** | ||
* Mapping query for inserting rows into a database table. | ||
*/ | ||
export declare class MappingInsertQuery<DB, TB extends keyof DB & string, QB extends InsertQueryBuilder<DB, TB, InsertResult>, InsertedObject extends object, SelectedObject extends object, ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'], InsertReturnsSelectedObject extends boolean, DefaultReturnObject extends object> { | ||
export declare class MappingInsertQuery<DB, TB extends keyof DB & string, QB extends InsertQueryBuilder<DB, TB, InsertResult>, InsertedObject extends object, SelectedObject extends object, ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'], InsertReturnsSelectedObject extends boolean, DefaultReturnObject extends object> { | ||
#private; | ||
@@ -11,3 +11,3 @@ protected readonly db: Kysely<DB>; | ||
protected readonly insertTransform?: ((obj: InsertedObject) => Insertable<DB[TB]>) | undefined; | ||
protected readonly insertReturnTransform?: ((source: InsertedObject, returns: ReturnColumns extends [] ? never : ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject) | undefined; | ||
protected readonly insertReturnTransform?: ((source: InsertedObject, returns: ReturnColumns extends [] ? never : Selection<DB, TB, ReturnColumns[number]>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject) | undefined; | ||
protected readonly returnColumns: ReturnColumns; | ||
@@ -28,3 +28,3 @@ /** | ||
*/ | ||
constructor(db: Kysely<DB>, qb: QB, insertTransform?: ((obj: InsertedObject) => Insertable<DB[TB]>) | undefined, returnColumns?: ReturnColumns, insertReturnTransform?: ((source: InsertedObject, returns: ReturnColumns extends [] ? never : ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject) | undefined); | ||
constructor(db: Kysely<DB>, qb: QB, insertTransform?: ((obj: InsertedObject) => Insertable<DB[TB]>) | undefined, returnColumns?: ReturnColumns, insertReturnTransform?: ((source: InsertedObject, returns: ReturnColumns extends [] ? never : Selection<DB, TB, ReturnColumns[number]>) => InsertReturnsSelectedObject extends true ? SelectedObject : DefaultReturnObject) | undefined); | ||
/** | ||
@@ -31,0 +31,0 @@ * Inserts the provided objects into the table as rows, first transforming |
@@ -1,7 +0,7 @@ | ||
import { Kysely, Selectable, UpdateQueryBuilder, UpdateResult, Updateable } from 'kysely'; | ||
import { ObjectWithKeys } from '../lib/type-utils'; | ||
import { Kysely, Selection, UpdateQueryBuilder, UpdateResult, Updateable } from 'kysely'; | ||
import { SelectionColumn } from '../lib/type-utils'; | ||
/** | ||
* Mapping query for updating rows from a database table. | ||
*/ | ||
export declare class MappingUpdateQuery<DB, TB extends keyof DB & string, QB extends UpdateQueryBuilder<DB, TB, TB, UpdateResult>, UpdatingObject extends object, SelectedObject extends object, ReturnColumns extends (keyof Selectable<DB[TB]> & string)[] | ['*'], ReturnCount, UpdateReturnsSelectedObjectWhenProvided extends boolean, DefaultReturnObject extends object> { | ||
export declare class MappingUpdateQuery<DB, TB extends keyof DB & string, QB extends UpdateQueryBuilder<DB, TB, TB, UpdateResult>, UpdatingObject extends object, SelectedObject extends object, ReturnColumns extends SelectionColumn<DB, TB>[] | ['*'], ReturnCount, UpdateReturnsSelectedObjectWhenProvided extends boolean, DefaultReturnObject extends object> { | ||
#private; | ||
@@ -12,3 +12,3 @@ readonly db: Kysely<DB>; | ||
protected readonly updateTransform?: ((update: UpdatingObject) => Updateable<DB[TB]>) | undefined; | ||
protected readonly updateReturnTransform?: ((source: UpdatingObject, returns: ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject) | undefined; | ||
protected readonly updateReturnTransform?: ((source: UpdatingObject, returns: Selection<DB, TB, ReturnColumns[number]>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject) | undefined; | ||
protected readonly returnColumns: ReturnColumns; | ||
@@ -31,3 +31,3 @@ /** | ||
*/ | ||
constructor(db: Kysely<DB>, qb: QB, countTransform: (count: bigint) => ReturnCount, updateTransform?: ((update: UpdatingObject) => Updateable<DB[TB]>) | undefined, returnColumns?: ReturnColumns, updateReturnTransform?: ((source: UpdatingObject, returns: ObjectWithKeys<Selectable<DB[TB]>, ReturnColumns>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject) | undefined); | ||
constructor(db: Kysely<DB>, qb: QB, countTransform: (count: bigint) => ReturnCount, updateTransform?: ((update: UpdatingObject) => Updateable<DB[TB]>) | undefined, returnColumns?: ReturnColumns, updateReturnTransform?: ((source: UpdatingObject, returns: Selection<DB, TB, ReturnColumns[number]>) => UpdateReturnsSelectedObjectWhenProvided extends true ? UpdatingObject extends SelectedObject ? SelectedObject : DefaultReturnObject : DefaultReturnObject) | undefined); | ||
/** | ||
@@ -34,0 +34,0 @@ * Runs the query, returning the number of rows updated, in |
@@ -11,3 +11,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { createDB, resetDB, destroyDB } from './utils/test-setup'; | ||
import { UserTableMapperReturningAll, UserTableMapperReturningDefault, } from './utils/test-mappers'; | ||
import { UserTableMapperReturningAll, UserTableMapperReturningDefault, UserTableMapperReturningNothing, } from './utils/test-mappers'; | ||
import { USERS } from './utils/test-objects'; | ||
@@ -18,5 +18,7 @@ import { ignore } from './utils/test-utils'; | ||
let userMapper; | ||
let userMapperReturningNothing; | ||
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { | ||
db = yield createDB(); | ||
userMapper = new UserTableMapperReturningAll(db); | ||
userMapperReturningNothing = new UserTableMapperReturningNothing(db); | ||
})); | ||
@@ -105,2 +107,12 @@ beforeEach(() => resetDB(db)); | ||
})); | ||
it('deletes rows specified via binary operation', () => __awaiter(void 0, void 0, void 0, function* () { | ||
yield userMapper.insert().run(USERS); | ||
const count1 = yield userMapper | ||
.delete('name', '=', USERS[0].name) | ||
.getCount(); | ||
expect(count1).toEqual(2); | ||
const users = yield userMapper.select().getAll(); | ||
expect(users.length).toEqual(1); | ||
expect(users[0].handle).toEqual(USERS[1].handle); | ||
})); | ||
it('modifies a delete query builder', () => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -155,5 +167,3 @@ yield userMapper.insert().run(USERS); | ||
// @ts-expect-error - table must have all filter fields | ||
userMapper.delete(['notThere', '=', 'foo']); | ||
// @ts-expect-error - doesn't allow plain string expression filters | ||
userMapper.delete("name = 'John Doe'"); | ||
userMapper.delete('notThere', '=', 'foo'); | ||
userMapper.delete(({ or, cmpr }) => | ||
@@ -165,4 +175,12 @@ // @ts-expect-error - only table columns are accessible via anyOf() | ||
or([cmpr('notThere', '=', 'xyz'), cmpr('alsoNotThere', '=', 'Sue')])); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapper.delete('str'); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapper.delete(['str']); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.delete(1); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.delete([1]); | ||
})); | ||
}); | ||
//# sourceMappingURL=TableMapper.delete.test.js.map |
@@ -22,3 +22,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
let postTableMapper; | ||
let postTableMapperReturningIDAndTitle; | ||
let postTableMapperReturningIDAndTitleAsT; | ||
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -33,4 +33,4 @@ db = yield createDB(); | ||
}); | ||
postTableMapperReturningIDAndTitle = new TableMapper(db, 'posts', { | ||
returnColumns: ['id', 'title'], | ||
postTableMapperReturningIDAndTitleAsT = new TableMapper(db, 'posts', { | ||
returnColumns: ['id', 'title as t'], | ||
countTransform: (count) => Number(count), | ||
@@ -124,11 +124,17 @@ }); | ||
const post2 = Object.assign({}, POSTS[2], { userId: insertReturns[2].id }); | ||
const updatingPosts = yield postTableMapperReturningIDAndTitle | ||
const updateReturns = yield postTableMapperReturningIDAndTitleAsT | ||
.insert() | ||
.getAll([post0, post1, post2]); | ||
expect(updatingPosts.length).toEqual(3); | ||
for (let i = 0; i < updatingPosts.length; i++) { | ||
expect(updatingPosts[i].id).toBeGreaterThan(0); | ||
expect(updatingPosts[i].title).toEqual(POSTS[i].title); | ||
expect(Object.keys(updatingPosts[i]).length).toEqual(2); | ||
expect(updateReturns.length).toEqual(3); | ||
for (let i = 0; i < updateReturns.length; i++) { | ||
expect(updateReturns[i].id).toBeGreaterThan(0); | ||
expect(updateReturns[i].t).toEqual(POSTS[i].title); | ||
expect(Object.keys(updateReturns[i]).length).toEqual(2); | ||
} | ||
ignore('check return types', () => { | ||
// @ts-expect-error - check return types | ||
updateReturns[0].title; | ||
// @ts-expect-error - check return types | ||
updateReturns[0].userId; | ||
}); | ||
})); | ||
@@ -184,3 +190,3 @@ it('inserts multiple returning no columns by default', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const readUser0 = yield userMapperReturningAll | ||
.select(['email', '=', USERS[0].email]) | ||
.select('email', '=', USERS[0].email) | ||
.getOne(); | ||
@@ -193,3 +199,3 @@ expect(readUser0 === null || readUser0 === void 0 ? void 0 : readUser0.email).toEqual(USERS[0].email); | ||
const readUser0 = yield userMapperReturningAll | ||
.select(['email', '=', USERS[0].email]) | ||
.select('email', '=', USERS[0].email) | ||
.getOne(); | ||
@@ -203,19 +209,25 @@ expect(readUser0 === null || readUser0 === void 0 ? void 0 : readUser0.email).toEqual(USERS[0].email); | ||
const readUser0 = yield userMapperReturningAll | ||
.select(['id', '=', insertReturn.id]) | ||
.select('id', '=', insertReturn.id) | ||
.getOne(); | ||
expect(readUser0 === null || readUser0 === void 0 ? void 0 : readUser0.email).toEqual(USERS[0].email); | ||
const post0 = Object.assign({}, POSTS[0], { userId: insertReturn.id }); | ||
const updatingPost = yield postTableMapperReturningIDAndTitle | ||
const updateReturn = yield postTableMapperReturningIDAndTitleAsT | ||
.insert() | ||
.getOne(post0); | ||
expect(updatingPost.id).toBeGreaterThan(0); | ||
expect(updatingPost.title).toEqual(POSTS[0].title); | ||
expect(Object.keys(updatingPost).length).toEqual(2); | ||
expect(updateReturn.id).toBeGreaterThan(0); | ||
expect(updateReturn.t).toEqual(POSTS[0].title); | ||
expect(Object.keys(updateReturn).length).toEqual(2); | ||
const readPost0 = yield postTableMapper | ||
.select(({ and, cmpr }) => and([ | ||
cmpr('id', '=', updatingPost.id), | ||
cmpr('title', '=', updatingPost.title), | ||
cmpr('id', '=', updateReturn.id), | ||
cmpr('title', '=', updateReturn.t), | ||
])) | ||
.getOne(); | ||
expect(readPost0 === null || readPost0 === void 0 ? void 0 : readPost0.likeCount).toEqual(post0.likeCount); | ||
ignore('check return types', () => { | ||
// @ts-expect-error - check return types | ||
updateReturn.title; | ||
// @ts-expect-error - check return types | ||
updateReturn.userId; | ||
}); | ||
})); | ||
@@ -270,3 +282,3 @@ it('inserts one configured to return all columns', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const readUsers = yield insertTransformMapper | ||
.select(['id', '>', insertReturn.id]) | ||
.select('id', '>', insertReturn.id) | ||
.getAll(); | ||
@@ -273,0 +285,0 @@ expect(readUsers.length).toEqual(2); |
@@ -16,3 +16,3 @@ /** | ||
import { createDB, resetDB, destroyDB } from './utils/test-setup'; | ||
import { UserTableMapperReturningID } from './utils/test-mappers'; | ||
import { UserTableMapperReturningID, UserTableMapperReturningNothing, } from './utils/test-mappers'; | ||
import { USERS } from './utils/test-objects'; | ||
@@ -23,5 +23,7 @@ import { ignore } from './utils/test-utils'; | ||
let userMapper; | ||
let userMapperReturningNothing; | ||
beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { | ||
db = yield createDB(); | ||
userMapper = new UserTableMapperReturningID(db); | ||
userMapperReturningNothing = new UserTableMapperReturningNothing(db); | ||
})); | ||
@@ -112,5 +114,45 @@ beforeEach(() => resetDB(db)); | ||
})); | ||
it('selects via a multi-column key tuple (definition order)', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const mapper = new TableMapper(db, 'users', { | ||
keyColumns: ['id', 'name'], | ||
}); | ||
yield mapper.insert().run(USERS); | ||
const users = yield mapper.select([3, 'Sue']).getAll(); | ||
expect(users.length).toEqual(1); | ||
expect(users[0].name).toEqual(USERS[2].name); | ||
ignore('detects key colum tuple type errors', () => { | ||
// @ts-expect-error - key tuple must have correct length | ||
mapper.select(['Sue']); | ||
// @ts-expect-error - key tuple must have correct length | ||
mapper.select(['Sue', 3, 'foo']); | ||
// @ts-expect-error - key tuple must have correct types | ||
mapper.select(['Sue', 'foo']); | ||
// @ts-expect-error - primitive key values are not allowed | ||
mapper.select('Sue'); | ||
// @ts-expect-error - primitive key values are not allowed | ||
mapper.select(1); | ||
}); | ||
})); | ||
it('selects via a multi-column key tuple (different order)', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const mapper = new TableMapper(db, 'users', { | ||
keyColumns: ['name', 'id'], | ||
}); | ||
yield mapper.insert().run(USERS); | ||
const users = yield mapper.select(['Sue', 3]).getAll(); | ||
expect(users.length).toEqual(1); | ||
expect(users[0].name).toEqual(USERS[2].name); | ||
ignore('detects key colum tuple type errors', () => { | ||
// @ts-expect-error - key tuple must have correct length | ||
mapper.select(['Sue']); | ||
// @ts-expect-error - key tuple must have correct length | ||
mapper.select(['Sue', 3, 'foo']); | ||
// @ts-expect-error - key tuple must have correct types | ||
mapper.select(['Sue', 'foo']); | ||
// @ts-expect-error - primitive key values are not allowed | ||
mapper.select('Sue'); | ||
// @ts-expect-error - primitive key values are not allowed | ||
mapper.select(1); | ||
}); | ||
})); | ||
ignore('detects select(filter) type errors', () => __awaiter(void 0, void 0, void 0, function* () { | ||
// @ts-expect-error - doesn't allow plain string expressions | ||
userMapper.select("name = 'John Doe'"); | ||
// @ts-expect-error - doesn't allow only two arguments | ||
@@ -124,5 +166,13 @@ userMapper.select('name', '='); | ||
// @ts-expect-error - binary op filter fields must be valid | ||
userMapper.select(['notThere', '=', 'foo']); | ||
userMapper.select('notThere', '=', 'foo'); | ||
// @ts-expect-error - binary op filter fields must be valid | ||
userMapper.select(['users.notThere', '=', 'foo']); | ||
userMapper.select('users.notThere', '=', 'foo'); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapper.select('str'); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapper.select(['str']); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.select(1); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.select([1]); | ||
})); | ||
@@ -145,2 +195,13 @@ }); | ||
})); | ||
it('selects via key column values', () => __awaiter(void 0, void 0, void 0, function* () { | ||
yield userMapper.insert().run(USERS); | ||
// Test selecting via key value | ||
const users1 = yield userMapper.select(2).getAll(); | ||
expect(users1.length).toEqual(1); | ||
expect(users1[0].handle).toEqual(USERS[1].handle); | ||
// Test selecting via key tuple | ||
const users2 = yield userMapper.select([2]).getAll(); | ||
expect(users2.length).toEqual(1); | ||
expect(users2[0].handle).toEqual(USERS[1].handle); | ||
})); | ||
it('selects with a matching field filter', () => __awaiter(void 0, void 0, void 0, function* () { | ||
@@ -168,3 +229,3 @@ yield userMapper.insert().run(USERS); | ||
// Test selecting by condition (with results) | ||
let users = yield userMapper.select(['name', '=', USERS[0].name]).getAll(); | ||
let users = yield userMapper.select('name', '=', USERS[0].name).getAll(); | ||
expect(users.length).toEqual(2); | ||
@@ -174,3 +235,3 @@ expect(users[0].handle).toEqual(USERS[0].handle); | ||
// Test selecting by condition (no results) | ||
users = yield userMapper.select(['name', '=', 'nonexistent']).getAll(); | ||
users = yield userMapper.select('name', '=', 'nonexistent').getAll(); | ||
expect(users.length).toEqual(0); | ||
@@ -208,3 +269,3 @@ })); | ||
// Test selecting by condition (with results) | ||
let users = yield userMapper.select(['name', '=', USERS[0].name]).getAll(); | ||
let users = yield userMapper.select('name', '=', USERS[0].name).getAll(); | ||
expect(users.length).toEqual(2); | ||
@@ -214,3 +275,3 @@ expect(users[0].handle).toEqual(USERS[0].handle); | ||
// Test selecting by condition (no results) | ||
users = yield userMapper.select(['name', '=', 'nonexistent']).getAll(); | ||
users = yield userMapper.select('name', '=', 'nonexistent').getAll(); | ||
expect(users.length).toEqual(0); | ||
@@ -253,3 +314,3 @@ })); | ||
// prettier-ignore | ||
(yield userMapper.select(["name", "=", "Sue"]).getAll())[0].notThere; | ||
(yield userMapper.select("name", "=", "Sue").getAll())[0].notThere; | ||
// prettier-ignore | ||
@@ -292,6 +353,6 @@ (yield userMapper | ||
// Test selecting by condition (with result) | ||
let user = yield userMapper.select(['name', '=', USERS[0].name]).getOne(); | ||
let user = yield userMapper.select('name', '=', USERS[0].name).getOne(); | ||
expect(user === null || user === void 0 ? void 0 : user.handle).toEqual(USERS[0].handle); | ||
// Test selecting by condition (no result) | ||
user = yield userMapper.select(['name', '=', 'nonexistent']).getOne(); | ||
user = yield userMapper.select('name', '=', 'nonexistent').getOne(); | ||
expect(user).toBeNull(); | ||
@@ -328,6 +389,6 @@ })); | ||
// Test selecting by condition (with result) | ||
let user = yield userMapper.select(['name', '=', USERS[0].name]).getOne(); | ||
let user = yield userMapper.select('name', '=', USERS[0].name).getOne(); | ||
expect(user === null || user === void 0 ? void 0 : user.handle).toEqual(USERS[0].handle); | ||
// Test selecting by condition (no result) | ||
user = yield userMapper.select(['name', '=', 'nonexistent']).getOne(); | ||
user = yield userMapper.select('name', '=', 'nonexistent').getOne(); | ||
expect(user).toBeNull(); | ||
@@ -356,3 +417,3 @@ })); | ||
// prettier-ignore | ||
(yield userMapper.select(["name", "=", "Sue"]).getOne()).notThere; | ||
(yield userMapper.select("name", "=", "Sue").getOne()).notThere; | ||
// prettier-ignore | ||
@@ -359,0 +420,0 @@ (yield userMapper |
@@ -13,3 +13,3 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { createDB, resetDB, destroyDB } from './utils/test-setup'; | ||
import { UserTableMapperReturningDefault, UserTableMapperReturningID, UserTableMapperReturningIDAndHandle, UserTableMapperReturningAll, UserTableMapperReturningNothing, } from './utils/test-mappers'; | ||
import { UserTableMapperReturningDefault, UserTableMapperReturningID, UserTableMapperReturningIDAndHandleAsH, UserTableMapperReturningAll, UserTableMapperReturningNothing, } from './utils/test-mappers'; | ||
import { userObject1, userRow1, userRow2, userRow3, USERS, } from './utils/test-objects'; | ||
@@ -22,3 +22,3 @@ import { ignore } from './utils/test-utils'; | ||
let userMapperReturningID; | ||
let userMapperReturningIDAndHandle; | ||
let userMapperReturningIDAndHandleAsH; | ||
let userMapperReturningAll; | ||
@@ -30,3 +30,4 @@ beforeAll(() => __awaiter(void 0, void 0, void 0, function* () { | ||
userMapperReturningID = new UserTableMapperReturningID(db); | ||
userMapperReturningIDAndHandle = new UserTableMapperReturningIDAndHandle(db); | ||
userMapperReturningIDAndHandleAsH = | ||
new UserTableMapperReturningIDAndHandleAsH(db); | ||
userMapperReturningAll = new UserTableMapperReturningAll(db); | ||
@@ -66,3 +67,3 @@ })); | ||
const readUser1 = yield userMapperReturningID | ||
.select(['id', '=', insertReturn0.id]) | ||
.select('id', '=', insertReturn0.id) | ||
.getOne(); | ||
@@ -75,3 +76,3 @@ expect(readUser1 === null || readUser1 === void 0 ? void 0 : readUser1.email).toEqual(updateValues.email); | ||
const readUsers = yield userMapperReturningID | ||
.select(['name', '=', 'Sue']) | ||
.select('name', '=', 'Sue') | ||
.getAll(); | ||
@@ -91,5 +92,3 @@ expect(readUsers.length).toEqual(2); | ||
expect(update).toEqual({ id: 1 }); | ||
const readUser2 = yield userMapperReturningID | ||
.select(['id', '=', 1]) | ||
.getOne(); | ||
const readUser2 = yield userMapperReturningID.select('id', '=', 1).getOne(); | ||
expect(readUser2 === null || readUser2 === void 0 ? void 0 : readUser2.name).toEqual('Every User 2'); | ||
@@ -116,3 +115,3 @@ const updateCount = yield userMapperReturningID.update().getCount({ | ||
let readUser = yield userMapperReturningID | ||
.select(['id', '=', insertReturn.id]) | ||
.select('id', '=', insertReturn.id) | ||
.getOne(); | ||
@@ -122,13 +121,15 @@ expect(readUser === null || readUser === void 0 ? void 0 : readUser.email).toEqual(updateValues1.email); | ||
const updateValues2 = { name: 'Sue' }; | ||
const updateReturns2 = yield userMapperReturningIDAndHandle | ||
const updateReturns2 = yield userMapperReturningIDAndHandleAsH | ||
.update({ email: updateValues1.email }) | ||
.getAll(updateValues2); | ||
updateReturns2[0].id; // ensure key is accessible | ||
updateReturns2[0].h; // ensure key is accessible | ||
expect(updateReturns2).toEqual([ | ||
{ | ||
id: insertReturn.id, | ||
handle: USERS[1].handle, | ||
h: USERS[1].handle, | ||
}, | ||
]); | ||
readUser = yield userMapperReturningID | ||
.select(['id', '=', insertReturn.id]) | ||
.select('id', '=', insertReturn.id) | ||
.getOne(); | ||
@@ -138,13 +139,19 @@ expect(readUser === null || readUser === void 0 ? void 0 : readUser.name).toEqual(updateValues2.name); | ||
const updateValues3 = { name: 'Replacement Sue' }; | ||
const updateReturns3 = yield userMapperReturningIDAndHandle | ||
const updateReturns3 = yield userMapperReturningIDAndHandleAsH | ||
.update({ name: 'Sue' }) | ||
.getAll(updateValues3); | ||
expect(updateReturns3.length).toEqual(3); | ||
expect(updateReturns3[0].handle).toEqual(USERS[0].handle); | ||
expect(updateReturns3[1].handle).toEqual(USERS[1].handle); | ||
expect(updateReturns3[2].handle).toEqual(USERS[2].handle); | ||
expect(updateReturns3[0].h).toEqual(USERS[0].handle); | ||
expect(updateReturns3[1].h).toEqual(USERS[1].handle); | ||
expect(updateReturns3[2].h).toEqual(USERS[2].handle); | ||
const readUsers = yield userMapperReturningID | ||
.select(['name', '=', updateValues3.name]) | ||
.select('name', '=', updateValues3.name) | ||
.getAll(); | ||
expect(readUsers.length).toEqual(3); | ||
ignore('check return types', () => { | ||
// @ts-expect-error - check return types | ||
updateReturns2[0].title; | ||
// @ts-expect-error - check return types | ||
updateReturns2[0].userId; | ||
}); | ||
})); | ||
@@ -192,8 +199,9 @@ it('update returns void when defaulting to no return columns', () => __awaiter(void 0, void 0, void 0, function* () { | ||
const updateValues = { email: 'new.email@xyz.pdq' }; | ||
const updateReturns = yield userMapperReturningIDAndHandle | ||
const updateReturns = yield userMapperReturningIDAndHandleAsH | ||
.update() | ||
.getAll(updateValues); | ||
const expectedUsers = USERS.map((user, i) => { | ||
return { id: insertReturns[i].id, handle: user.handle }; | ||
}); | ||
const expectedUsers = USERS.map((user, i) => ({ | ||
id: insertReturns[i].id, | ||
h: user.handle, | ||
})); | ||
expect(updateReturns).toEqual(expectedUsers); | ||
@@ -210,7 +218,7 @@ const readUsers = yield userMapperReturningID.select().getAll(); | ||
const updateCount = yield userMapperReturningAll | ||
.update(['id', '>', insertReturns[0].id]) | ||
.update('id', '>', insertReturns[0].id) | ||
.getCount(updateValues); | ||
expect(updateCount).toEqual(2); | ||
const readUsers = yield userMapperReturningID | ||
.select(['id', '>', insertReturns[0].id]) | ||
.select('id', '>', insertReturns[0].id) | ||
.getAll(); | ||
@@ -230,3 +238,3 @@ expect(readUsers.length).toEqual(2); | ||
const readUsers = yield userMapperReturningID | ||
.select(['id', '>', insertReturns[0].id]) | ||
.select('id', '>', insertReturns[0].id) | ||
.getAll(); | ||
@@ -272,7 +280,7 @@ expect(readUsers.length).toEqual(2); | ||
// @ts-expect-error - table must have all filter fields | ||
userMapperReturningID.update(['notThere', '=', 'foo']).getAll({ | ||
userMapperReturningID.update('notThere', '=', 'foo').getAll({ | ||
email: 'abc@def.ghi', | ||
}); | ||
// @ts-expect-error - table must have all filter fields | ||
userMapperReturningID.update(['notThere', '=', 'foo']).getAll({ | ||
userMapperReturningID.update('notThere', '=', 'foo').getAll({ | ||
email: 'abc@def.ghi', | ||
@@ -287,6 +295,2 @@ }); | ||
{ notThere: 'xyz@pdq.xyz' }); | ||
// @ts-expect-error - doesn't allow plain string expression filters | ||
userMapperReturningID.update("name = 'John Doe'", USERS[0]); | ||
// @ts-expect-error - doesn't allow plain string expression filters | ||
userMapperReturningID.update("name = 'John Doe'", USERS[0]); | ||
// @ts-expect-error - only requested columns are accessible | ||
@@ -308,2 +312,10 @@ // prettier-ignore | ||
.getAll(USERS[0]); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapperReturningID.update('str'); | ||
// @ts-expect-error - ID filter must have correct type | ||
userMapperReturningID.update(['str']); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.update(1); | ||
// @ts-expect-error - ID filter not allowed when when no ID column | ||
userMapperReturningNothing.update([1]); | ||
})); | ||
@@ -310,0 +322,0 @@ }); |
@@ -104,12 +104,8 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
isMappedObject: (obj) => obj instanceof MappedUser, | ||
insertTransform: (user) => { | ||
return { | ||
name: `${user.firstName} ${user.lastName}`, | ||
handle: user.handle, | ||
email: user.email, | ||
}; | ||
}, | ||
insertReturnTransform: (user, returns) => { | ||
return new MappedUser(returns.id, user.firstName, user.lastName, user.handle, user.email); | ||
}, | ||
insertTransform: (user) => ({ | ||
name: `${user.firstName} ${user.lastName}`, | ||
handle: user.handle, | ||
email: user.email, | ||
}), | ||
insertReturnTransform: (user, returns) => new MappedUser(returns.id, user.firstName, user.lastName, user.handle, user.email), | ||
updateTransform: (user) => { | ||
@@ -169,3 +165,3 @@ if (!(user instanceof MappedUser)) { | ||
const updateColumnReturns = yield userMapper | ||
.update(['id', '=', insertReturn.serialNo]) | ||
.update('id', '=', insertReturn.serialNo) | ||
.getAll({ | ||
@@ -207,12 +203,8 @@ name: 'Foo Foo', | ||
isMappedObject: (obj) => obj instanceof MappedUser, | ||
insertTransform: (user) => { | ||
return { | ||
name: `${user.firstName} ${user.lastName}`, | ||
handle: user.handle, | ||
email: user.email, | ||
}; | ||
}, | ||
insertReturnTransform: (user, returns) => { | ||
return new MappedUser(returns.id, user.firstName, user.lastName, user.handle, user.email); | ||
}, | ||
insertTransform: (user) => ({ | ||
name: `${user.firstName} ${user.lastName}`, | ||
handle: user.handle, | ||
email: user.email, | ||
}), | ||
insertReturnTransform: (user, returns) => new MappedUser(returns.id, user.firstName, user.lastName, user.handle, user.email), | ||
selectTransform: (row) => { | ||
@@ -270,2 +262,26 @@ const names = row.name.split(' '); | ||
})); | ||
it('supports queries with no key columns', () => __awaiter(void 0, void 0, void 0, function* () { | ||
class MappedUser { | ||
constructor(id, name, handle, email) { | ||
this.id = id; | ||
this.name = name; | ||
this.handle = handle; | ||
this.email = email; | ||
} | ||
} | ||
const userMapper = new UniformTableMapper(db, 'users', { | ||
isMappedObject: (obj) => obj instanceof MappedUser, | ||
keyColumns: [], | ||
}); | ||
// test inserting a user | ||
const insertedUser = new MappedUser(0, // use 0 so we can tell it wasn't generated by the DB | ||
insertedUser1.firstName, insertedUser1.handle, insertedUser1.email); | ||
const insertReturn = yield userMapper.insert().getOne(insertedUser); | ||
expect(insertReturn).toBeUndefined(); | ||
// test getting a user by ID | ||
const selectedUser1 = yield userMapper | ||
.select({ id: insertedUser.id }) | ||
.getOne(); | ||
expect(selectedUser1).toEqual(insertedUser); | ||
})); | ||
//# sourceMappingURL=UniformTableMapper.test.js.map |
@@ -9,5 +9,5 @@ import { Insertable, Kysely, Selectable } from 'kysely'; | ||
export declare class UserTableMapperReturningNothing extends TableMapper<Database, 'users', [ | ||
], [ | ||
'*' | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, [ | ||
], number> { | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, number> { | ||
readonly db: Kysely<Database>; | ||
@@ -17,15 +17,17 @@ constructor(db: Kysely<Database>); | ||
export declare class UserTableMapperReturningID extends TableMapper<Database, 'users', [ | ||
'id' | ||
], [ | ||
'*' | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, [ | ||
'id' | ||
], number> { | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, number> { | ||
readonly db: Kysely<Database>; | ||
constructor(db: Kysely<Database>); | ||
} | ||
export declare class UserTableMapperReturningIDAndHandle extends TableMapper<Database, 'users', [ | ||
export declare class UserTableMapperReturningIDAndHandleAsH extends TableMapper<Database, 'users', [ | ||
'id' | ||
], [ | ||
'*' | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, [ | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, number, [ | ||
'id', | ||
'handle' | ||
], number> { | ||
'handle as h' | ||
]> { | ||
readonly db: Kysely<Database>; | ||
@@ -35,6 +37,7 @@ constructor(db: Kysely<Database>); | ||
export declare class UserTableMapperReturningAll extends TableMapper<Database, 'users', [ | ||
], [ | ||
'*' | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, [ | ||
], Selectable<Users>, Insertable<Users>, Partial<Insertable<Users>>, number, [ | ||
'*' | ||
], number> { | ||
]> { | ||
readonly db: Kysely<Database>; | ||
@@ -41,0 +44,0 @@ constructor(db: Kysely<Database>); |
@@ -11,3 +11,3 @@ import { TableMapper } from '../../mappers/table-mapper'; | ||
constructor(db) { | ||
super(db, 'users', { returnColumns: [], countTransform }); | ||
super(db, 'users', { keyColumns: [], countTransform }); | ||
this.db = db; | ||
@@ -18,9 +18,13 @@ } | ||
constructor(db) { | ||
super(db, 'users', { returnColumns: ['id'], countTransform }); | ||
super(db, 'users', { keyColumns: ['id'], countTransform }); | ||
this.db = db; | ||
} | ||
} | ||
export class UserTableMapperReturningIDAndHandle extends TableMapper { | ||
export class UserTableMapperReturningIDAndHandleAsH extends TableMapper { | ||
constructor(db) { | ||
super(db, 'users', { returnColumns: ['id', 'handle'], countTransform }); | ||
super(db, 'users', { | ||
keyColumns: ['id'], | ||
returnColumns: ['id', 'handle as h'], | ||
countTransform, | ||
}); | ||
this.db = db; | ||
@@ -27,0 +31,0 @@ } |
{ | ||
"name": "kysely-mapper", | ||
"version": "0.2.3", | ||
"version": "0.2.4", | ||
"author": "Joseph T. Lapp <arachnojoe@gmail.com>", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
641696
7429