( schema: AnySchema, client: MongoClient, session?: ClientSession )
| 261 | * This adapter uses string ids instead of object id, which is better suited for the API design of FumaDB. |
| 262 | */ |
| 263 | export function fromMongoDB( |
| 264 | schema: AnySchema, |
| 265 | client: MongoClient, |
| 266 | session?: ClientSession |
| 267 | ): AbstractQuery<AnySchema> { |
| 268 | const db = client.db(); |
| 269 | |
| 270 | function buildFindPipeline( |
| 271 | table: AnyTable, |
| 272 | v: SimplifyFindOptions<FindManyOptions> |
| 273 | ) { |
| 274 | const pipeline: Document[] = []; |
| 275 | const where = v.where ? buildWhere(v.where) : undefined; |
| 276 | |
| 277 | if (where) pipeline.push({ $match: where }); |
| 278 | if (v.limit !== undefined) |
| 279 | pipeline.push({ |
| 280 | $limit: v.limit, |
| 281 | }); |
| 282 | if (v.offset !== undefined) |
| 283 | pipeline.push({ |
| 284 | $skip: v.offset, |
| 285 | }); |
| 286 | if (v.orderBy) { |
| 287 | pipeline.push({ $sort: mapSort(v.orderBy) }); |
| 288 | } |
| 289 | const project = mapProjection(v.select, table); |
| 290 | |
| 291 | if (v.join) { |
| 292 | for (const { relation, options: joinOptions } of v.join) { |
| 293 | project[relation.name] = 1; |
| 294 | |
| 295 | if (joinOptions === false) continue; |
| 296 | const vars: Record<string, string> = {}; |
| 297 | |
| 298 | for (const column of Object.values(table.columns)) { |
| 299 | vars[`${table.ormName}_${column.ormName}`] = |
| 300 | `$${column.names.mongodb}`; |
| 301 | } |
| 302 | |
| 303 | const targetTable = relation.table; |
| 304 | pipeline.push({ |
| 305 | $lookup: { |
| 306 | from: targetTable.names.mongodb, |
| 307 | let: vars, |
| 308 | pipeline: [ |
| 309 | ...relation.on.map(([left, right]) => { |
| 310 | return { |
| 311 | $match: { |
| 312 | $expr: { |
| 313 | $eq: [ |
| 314 | `$${targetTable.columns[right].names.mongodb}`, |
| 315 | `$$${table.ormName}_${left}`, |
| 316 | ], |
| 317 | }, |
| 318 | }, |
| 319 | }; |
| 320 | }), |
no test coverage detected