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