@protoutil/repo
MongoDB Engine
Section titled “MongoDB Engine”An Engine implementation backed by mongodb.
Install
Section titled “Install”npm install @protoutil/repo mongodbimport { MongoClient } from "mongodb";import { createMongoDBEngine } from "@protoutil/repo/mongodb";
const client = new MongoClient("mongodb://localhost:27017");await client.connect();
const engine = createMongoDBEngine({ client, database: "app",});Custom Dialect
Section titled “Custom Dialect”Override the default dialect to inject custom AIP-160 function handlers:
import { mongo } from "@protoutil/aipql";
const engine = createMongoDBEngine({ client, database: "app", dialect: (expr) => mongo(expr, { functions: { fuzzy: myHandler }, }),});CRUD Operations
Section titled “CRUD Operations”The engine provides higher-level methods that accept checked AIP-160 filter expressions:
import { check, contextDecls, parse } from "@protoutil/aip/filtering";import { parse as parseOrderBy } from "@protoutil/aip/orderby";
const parsed = parse('active = true AND age > 21');const { checkedExpr } = check(parsed, { decls: contextDecls(UserSchema) });
const user = await engine.findOne({ table: "users", filter: checkedExpr });
const users = await engine.findMany({ table: "users", filter: checkedExpr, orderBy: parseOrderBy("age desc"), limit: 10, offset: 0,});
const created = await engine.insertOne({ table: "users", row: { _id: "u1", email: "alice@example.com", active: true },});
const updated = await engine.updateOne({ table: "users", filter: checkedExpr, row: { active: false },});
const deleted = await engine.deleteOne({ table: "users", filter: checkedExpr });
const total = await engine.count({ table: "users" });const active = await engine.count({ table: "users", filter: checkedExpr });Raw Commands
Section titled “Raw Commands”The execute method accepts a MongoDB command object and returns normalized result documents. String queries are not supported by the MongoDB engine.
const stats = await engine.execute<{ ok: number }>({ ping: 1,});Transactions
Section titled “Transactions”The transaction method executes a callback within a MongoDB session transaction. The transaction is committed when the callback resolves and rolled back if it throws.
await engine.transaction(async (tx) => { await tx.insertOne({ table: "users", row: { _id: "u1", name: "alice" }, });
await tx.insertOne({ table: "users", row: { _id: "u2", name: "bob" }, });});Nested transactions are not supported. Calling transaction from inside an active MongoDB transaction throws FailedPreconditionError.
Error Handling
Section titled “Error Handling”Database errors are automatically wrapped in AIP status errors:
| MongoDB Error | AIP Error |
|---|---|
11000 | AlreadyExistsError |
121 | InvalidArgumentError |
2 / "BadValue" | InvalidArgumentError |
66 | FailedPreconditionError |
| Other errors | InternalError |
The original database error message is preserved in the error’s debugInfo.detail.
Closing
Section titled “Closing”Call close when the engine is no longer needed. The underlying MongoClient is closed and the engine must not be used afterwards.
await engine.close();API Reference
Section titled “API Reference”| Export | Description |
|---|---|
createMongoDBEngine(config) | Create an engine from a MongoClient and database name. |
MongoDBEngineConfig | Configuration interface: { client: MongoClient, database: string, dialect?: Dialect }. |