[slonik] update types to support sql.join (#39202)

This commit is contained in:
bram-l 2019-10-22 22:34:54 +02:00 committed by Wesley Wigham
parent 8a10918272
commit 08e1da0136
3 changed files with 72 additions and 34 deletions

View File

@ -26,6 +26,17 @@ export type LogicalBooleanOperatorType = 'AND' | 'OR';
// EXPRESSIONS AND TOKENS
// ----------------------------------------------------------------------
export type TypeNameIdentifierType =
'bool' |
'bytea' |
'float4' |
'float8' |
'int2' |
'int4' |
'json' |
'text' |
'timestamptz';
export type SerializableValueType =
| string
| number
@ -42,23 +53,30 @@ export interface SerializableValueObject {
export interface SerializableValueArray
extends ReadonlyArray<SerializableValueType> {}
export interface IdentifierTokenType {
export type PositionalParameterValuesType = ReadonlyArray<ValueExpressionType>;
export type NamedParameterValuesType = Record<string, ValueExpressionType>;
export interface ArraySqlTokenType {
memberType: TypeNameIdentifierType | SqlTokenType;
type: typeof SlonikSymbol.ArrayTokenSymbol;
values: PositionalParameterValuesType;
}
export interface BinarySqlTokenType {
data: Buffer;
type: typeof SlonikSymbol.BinaryTokenSymbol;
}
export interface IdentifierSqlTokenType {
names: ReadonlyArray<string>;
type: typeof SlonikSymbol.IdentifierTokenSymbol;
}
export type SqlSqlTokenType<T> = TaggedTemplateLiteralInvocationType<T>;
export interface RawSqlTokenType {
sql: string;
type: typeof SlonikSymbol.RawSqlTokenSymbol;
values: PrimitiveValueExpressionType[];
}
export interface ArraySqlTokenType {
memberType: string;
type: typeof SlonikSymbol.ArrayTokenSymbol;
values: PrimitiveValueExpressionType[];
export interface ListSqlTokenType {
glue: SqlTokenType;
members: ReadonlyArray<SqlTokenType>;
type: typeof SlonikSymbol.ListTokenSymbol;
}
export interface JsonSqlTokenType {
@ -66,19 +84,24 @@ export interface JsonSqlTokenType {
type: typeof SlonikSymbol.JsonTokenSymbol;
}
export type SqlSqlTokenType<T> = TaggedTemplateLiteralInvocationType<T>;
export interface UnnestSqlTokenType {
columnTypes: string[];
tuples: PrimitiveValueExpressionType[][];
columnTypes: ReadonlyArray<string>;
tuples: ReadonlyArray<PositionalParameterValuesType>;
type: typeof SlonikSymbol.UnnestTokenSymbol;
}
export type PrimitiveValueExpressionType = string | number | boolean | null;
export type PrimitiveValueExpressionType = string | number | boolean | null | PrimitiveValueExpressionTypeArray;
export interface PrimitiveValueExpressionTypeArray extends Array<PrimitiveValueExpressionType> {}
export type SqlTokenType =
ArraySqlTokenType |
IdentifierTokenType |
BinarySqlTokenType |
IdentifierSqlTokenType |
JsonSqlTokenType |
RawSqlTokenType |
ListSqlTokenType |
SqlSqlTokenType<any> |
UnnestSqlTokenType;
@ -281,20 +304,24 @@ export interface SqlTaggedTemplateType {
) => ArraySqlTokenType;
identifier: (
names: string[]
) => IdentifierTokenType;
) => IdentifierSqlTokenType;
json: (
value: SerializableValueType
) => JsonSqlTokenType;
join: (
members: ReadonlyArray<ValueExpressionType>,
glue: SqlTokenType,
) => ListSqlTokenType;
raw: (
rawSql: string,
values?: PrimitiveValueExpressionType[]
) => RawSqlTokenType;
values?: ReadonlyArray<PrimitiveValueExpressionType>
) => SqlTokenType;
unnest: (
// Value might be PrimitiveValueExpressionType[],
// Value might be ReadonlyArray<ReadonlyArray<PrimitiveValueExpressionType>>,
// or it can be infinitely nested array, e.g.
// https://github.com/gajus/slonik/issues/44
tuples: any[][],
columnTypes: string[]
tuples: ReadonlyArray<ReadonlyArray<any>>,
columnTypes: ReadonlyArray<string>
) => UnnestSqlTokenType;
}

View File

@ -22,11 +22,11 @@ import {
UniqueIntegrityConstraintViolationError,
SqlTaggedTemplateType
} from 'slonik';
import { ArrayTokenSymbol, TupleListTokenSymbol } from 'slonik/symbols';
import { ArrayTokenSymbol, BinaryTokenSymbol } from 'slonik/symbols';
// make sure symbols are unique
// $ExpectError
const badSymbolAssignment: typeof ArrayTokenSymbol = TupleListTokenSymbol;
const badSymbolAssignment: typeof ArrayTokenSymbol = BinaryTokenSymbol;
const VALUE = 'foo';
@ -268,6 +268,23 @@ createTimestampWithTimeZoneTypeParser();
// ExpectType SqlSqlTokenType
const query1 = sql`SELECT ${'baz'} FROM (${query0})`;
await connection.query(sql`
SELECT ${sql.identifier(['foo', 'a'])}
FROM (
VALUES
(
${sql.join(
[
sql.join(['a1', 'b1', 'c1'], sql`, `),
sql.join(['a2', 'b2', 'c2'], sql`, `)
],
sql`), (`
)}
)
) foo(a, b, c)
WHERE foo.b IN (${sql.join(['c1', 'a2'], sql`, `)})
`);
await connection.query(sql`
SELECT (${sql.json([1, 2, { test: 12, other: 'test' }])})
`);

View File

@ -1,13 +1,7 @@
export const ArrayTokenSymbol: unique symbol;
export const AssignmentListTokenSymbol: unique symbol;
export const BooleanExpressionTokenSymbol: unique symbol;
export const ComparisonPredicateTokenSymbol: unique symbol;
export const IdentifierListTokenSymbol: unique symbol;
export const BinaryTokenSymbol: unique symbol;
export const IdentifierTokenSymbol: unique symbol;
export const JsonTokenSymbol: unique symbol;
export const RawSqlTokenSymbol: unique symbol;
export const ListTokenSymbol: unique symbol;
export const SqlTokenSymbol: unique symbol;
export const ValueListTokenSymbol: unique symbol;
export const TupleTokenSymbol: unique symbol;
export const TupleListTokenSymbol: unique symbol;
export const UnnestTokenSymbol: unique symbol;