/** * 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>, O extends Record>, A = never > extends Pipeable { readonly [TypeId]: { readonly _A: Covariant } 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>, O extends Record>, A > extends Procedure { readonly values: Procedure.ParametersRecord } /** * 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> > = & { readonly [K in keyof A]: A[K] extends Parameter.Parameter ? 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>, A > { readonly output: ParametersRecord readonly rows: ReadonlyArray } } type Simplify = { [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 = () => ( name: N, type: T, options?: ParameterOptions ) => < I extends Record>, O extends Record> >( self: Procedure ): Procedure }>, 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 = () => ( name: N, type: T, options?: ParameterOptions ) => < I extends Record>, O extends Record> >( self: Procedure ): Procedure }>> => ({ ...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 = () => < I extends Record>, O extends Record> >( self: Procedure ): Procedure => 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>, O extends Record>, A >( self: Procedure ) => (input: Procedure.ParametersRecord): ProcedureWithValues => ({ ...self, values: input })