214 lines
5.4 KiB
TypeScript
214 lines
5.4 KiB
TypeScript
/**
|
|
* Typed metadata builders for Microsoft SQL Server stored procedure calls.
|
|
*
|
|
* This module defines the `Procedure` values consumed by `MssqlClient.call`.
|
|
* `make` starts a procedure definition, `param` and `outputParam` add typed
|
|
* Tedious parameter metadata, `withRows` sets the expected row type, and
|
|
* `compile` binds input values before execution. The module also defines the
|
|
* typed result shape for output parameters and returned rows.
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
import { identity } from "effect/Function"
|
|
import type { Pipeable } from "effect/Pipeable"
|
|
import { pipeArguments } from "effect/Pipeable"
|
|
import type { Covariant } from "effect/Types"
|
|
import type { Row } from "effect/unstable/sql/SqlConnection"
|
|
import type { DataType } from "tedious/lib/data-type.ts"
|
|
import type { ParameterOptions } from "tedious/lib/request.ts"
|
|
import * as Parameter from "./Parameter.ts"
|
|
|
|
/**
|
|
* Runtime type identifier used to mark SQL Server stored procedure definitions.
|
|
*
|
|
* @category type IDs
|
|
* @since 4.0.0
|
|
*/
|
|
export const TypeId: TypeId = "~@effect/sql-mssql/Procedure"
|
|
|
|
/**
|
|
* Type-level identifier used to mark SQL Server stored procedure definitions.
|
|
*
|
|
* @category type IDs
|
|
* @since 4.0.0
|
|
*/
|
|
export type TypeId = "~@effect/sql-mssql/Procedure"
|
|
|
|
/**
|
|
* Pipeable definition of a SQL Server stored procedure, tracking its input parameters, output parameters, and result row type.
|
|
*
|
|
* @category models
|
|
* @since 4.0.0
|
|
*/
|
|
export interface Procedure<
|
|
I extends Record<string, Parameter.Parameter<any>>,
|
|
O extends Record<string, Parameter.Parameter<any>>,
|
|
A = never
|
|
> extends Pipeable {
|
|
readonly [TypeId]: {
|
|
readonly _A: Covariant<A>
|
|
}
|
|
readonly _tag: "Procedure"
|
|
readonly name: string
|
|
readonly params: I
|
|
readonly outputParams: O
|
|
}
|
|
|
|
/**
|
|
* Stored procedure definition with concrete input values bound for execution.
|
|
*
|
|
* @category models
|
|
* @since 4.0.0
|
|
*/
|
|
export interface ProcedureWithValues<
|
|
I extends Record<string, Parameter.Parameter<any>>,
|
|
O extends Record<string, Parameter.Parameter<any>>,
|
|
A
|
|
> extends Procedure<I, O, A> {
|
|
readonly values: Procedure.ParametersRecord<I>
|
|
}
|
|
|
|
/**
|
|
* Namespace containing type helpers and result types for SQL Server stored procedures.
|
|
*
|
|
* @since 4.0.0
|
|
*/
|
|
export declare namespace Procedure {
|
|
/**
|
|
* Maps a record of `Parameter` metadata to the corresponding record of parameter value types.
|
|
*
|
|
* @category utility types
|
|
* @since 4.0.0
|
|
*/
|
|
export type ParametersRecord<
|
|
A extends Record<string, Parameter.Parameter<any>>
|
|
> =
|
|
& {
|
|
readonly [K in keyof A]: A[K] extends Parameter.Parameter<infer T> ? T
|
|
: never
|
|
}
|
|
& {}
|
|
|
|
/**
|
|
* Result of a SQL Server stored procedure call, containing typed output parameter values and returned rows.
|
|
*
|
|
* @category models
|
|
* @since 4.0.0
|
|
*/
|
|
export interface Result<
|
|
O extends Record<string, Parameter.Parameter<any>>,
|
|
A
|
|
> {
|
|
readonly output: ParametersRecord<O>
|
|
readonly rows: ReadonlyArray<A>
|
|
}
|
|
}
|
|
|
|
type Simplify<A> = { [K in keyof A]: A[K] } & {}
|
|
|
|
const procedureProto = {
|
|
[TypeId]: {
|
|
_A: identity
|
|
},
|
|
_tag: "Procedure",
|
|
pipe() {
|
|
return pipeArguments(this, arguments)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Creates an empty SQL Server stored procedure definition for the given procedure name.
|
|
*
|
|
* @category constructors
|
|
* @since 4.0.0
|
|
*/
|
|
export const make = (name: string): Procedure<{}, {}> => {
|
|
const procedure = Object.create(procedureProto)
|
|
procedure.name = name
|
|
procedure.params = {}
|
|
procedure.outputParams = {}
|
|
return procedure
|
|
}
|
|
|
|
/**
|
|
* Adds a typed input parameter to a SQL Server stored procedure definition.
|
|
*
|
|
* @category combinators
|
|
* @since 4.0.0
|
|
*/
|
|
export const param = <A>() =>
|
|
<N extends string, T extends DataType>(
|
|
name: N,
|
|
type: T,
|
|
options?: ParameterOptions
|
|
) =>
|
|
<
|
|
I extends Record<string, Parameter.Parameter<any>>,
|
|
O extends Record<string, Parameter.Parameter<any>>
|
|
>(
|
|
self: Procedure<I, O>
|
|
): Procedure<Simplify<I & { [K in N]: Parameter.Parameter<A> }>, O> => ({
|
|
...self,
|
|
params: {
|
|
...self.params,
|
|
[name]: Parameter.make(name, type, options)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* Adds a typed output parameter to a SQL Server stored procedure definition.
|
|
*
|
|
* @category combinators
|
|
* @since 4.0.0
|
|
*/
|
|
export const outputParam = <A>() =>
|
|
<N extends string, T extends DataType>(
|
|
name: N,
|
|
type: T,
|
|
options?: ParameterOptions
|
|
) =>
|
|
<
|
|
I extends Record<string, Parameter.Parameter<any>>,
|
|
O extends Record<string, Parameter.Parameter<any>>
|
|
>(
|
|
self: Procedure<I, O>
|
|
): Procedure<I, Simplify<O & { [K in N]: Parameter.Parameter<A> }>> => ({
|
|
...self,
|
|
outputParams: {
|
|
...self.outputParams,
|
|
[name]: Parameter.make(name, type, options)
|
|
}
|
|
})
|
|
|
|
/**
|
|
* Sets the expected row type for a SQL Server stored procedure definition.
|
|
*
|
|
* @category combinators
|
|
* @since 4.0.0
|
|
*/
|
|
export const withRows = <A extends object = Row>() =>
|
|
<
|
|
I extends Record<string, Parameter.Parameter<any>>,
|
|
O extends Record<string, Parameter.Parameter<any>>
|
|
>(
|
|
self: Procedure<I, O>
|
|
): Procedure<I, O, A> => self as any
|
|
|
|
/**
|
|
* Binds input values to a SQL Server stored procedure definition, producing a value that can be executed with `MssqlClient.call`.
|
|
*
|
|
* @category combinators
|
|
* @since 4.0.0
|
|
*/
|
|
export const compile = <
|
|
I extends Record<string, Parameter.Parameter<any>>,
|
|
O extends Record<string, Parameter.Parameter<any>>,
|
|
A
|
|
>(
|
|
self: Procedure<I, O, A>
|
|
) =>
|
|
(input: Procedure.ParametersRecord<I>): ProcedureWithValues<I, O, A> => ({
|
|
...self,
|
|
values: input
|
|
})
|