| 149 | * @since 4.0.0 |
| 150 | */ |
| 151 | export const grouped = <Req extends Schema.Constraint, Res extends Schema.Constraint, K, Row, E, R>( |
| 152 | options: { |
| 153 | readonly Request: Req |
| 154 | readonly RequestGroupKey: (request: Req["Type"]) => K |
| 155 | readonly Result: Res |
| 156 | readonly ResultGroupKey: (result: Res["Type"], row: Types.NoInfer<Row>) => K |
| 157 | readonly execute: ( |
| 158 | requests: Arr.NonEmptyArray<Req["Encoded"]> |
| 159 | ) => Effect.Effect<ReadonlyArray<Row>, E, R> |
| 160 | } |
| 161 | ): RequestResolver.RequestResolver< |
| 162 | SqlRequest< |
| 163 | Req["Type"], |
| 164 | Arr.NonEmptyArray<Res["Type"]>, |
| 165 | E | Schema.SchemaError | Cause.NoSuchElementError, |
| 166 | Req["EncodingServices"] | Res["DecodingServices"] | R |
| 167 | > |
| 168 | > => { |
| 169 | const decodeResults = Schema.decodeUnknownEffect(Schema.Array(options.Result)) |
| 170 | |
| 171 | return RequestResolver.makeGrouped< |
| 172 | SqlRequest< |
| 173 | Req["Type"], |
| 174 | Arr.NonEmptyArray<Res["Type"]>, |
| 175 | E | Schema.SchemaError | Cause.NoSuchElementError, |
| 176 | Req["EncodingServices"] | Res["DecodingServices"] | R |
| 177 | >, |
| 178 | SqlClient.TransactionConnection.Service | undefined |
| 179 | >({ |
| 180 | key: transactionKey, |
| 181 | resolver: Effect.fnUntraced(function*(entries) { |
| 182 | const [inputs] = yield* partitionRequests(entries, options.Request) |
| 183 | if (!Arr.isArrayNonEmpty(inputs)) return |
| 184 | const resultMap = MutableHashMap.empty<K, Arr.NonEmptyArray<Res["Type"]>>() |
| 185 | const results = yield* options.execute(inputs).pipe( |
| 186 | Effect.provideContext(entries[0].context) |
| 187 | ) |
| 188 | const decodedResults = yield* decodeResults(results).pipe( |
| 189 | Effect.provideContext(entries[0].context) |
| 190 | ) |
| 191 | for (let i = 0, len = decodedResults.length; i < len; i++) { |
| 192 | const result = decodedResults[i] |
| 193 | const key = options.ResultGroupKey(result, results[i]) |
| 194 | const group = MutableHashMap.get(resultMap, key) |
| 195 | if (group._tag === "None") { |
| 196 | MutableHashMap.set(resultMap, key, [result]) |
| 197 | } else { |
| 198 | group.value.push(result) |
| 199 | } |
| 200 | } |
| 201 | for (let i = 0, len = entries.length; i < len; i++) { |
| 202 | const entry = entries[i] |
| 203 | const key = options.RequestGroupKey(entry.request.payload) |
| 204 | const result = MutableHashMap.get(resultMap, key) |
| 205 | entry.completeUnsafe( |
| 206 | result._tag === "None" ? constNoSuchElement : Exit.succeed(result.value) |
| 207 | ) |
| 208 | } |