db-model-router 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/docs/README.md ADDED
@@ -0,0 +1,208 @@
1
+ # rest-router
2
+
3
+ A database-agnostic REST API generator for Node.js. Works with Express or ultimate-express (a high-performance drop-in replacement). Define a model, get a full CRUD API with filtering, pagination, and bulk operations — backed by any of 9 supported databases.
4
+
5
+ ## Supported Adapters
6
+
7
+ | Adapter | Module Key | Driver | Install |
8
+ | ---------------------------------------- | ------------- | ------------------------ | ---------------------------------------------------------------------- |
9
+ | [MySQL](#mysql-example) | `mysql` | mysql2 | `npm i db-model-router mysql2` |
10
+ | [PostgreSQL](./adapters/postgres.md) | `postgres` | pg | `npm i db-model-router pg` |
11
+ | [SQLite3](./adapters/sqlite3.md) | `sqlite3` | better-sqlite3 | `npm i db-model-router better-sqlite3` |
12
+ | [MongoDB](./adapters/mongodb.md) | `mongodb` | mongodb | `npm i db-model-router mongodb` |
13
+ | [MSSQL](./adapters/mssql.md) | `mssql` | mssql | `npm i db-model-router mssql` |
14
+ | [CockroachDB](./adapters/cockroachdb.md) | `cockroachdb` | pg | `npm i db-model-router pg` |
15
+ | [Oracle](./adapters/oracle.md) | `oracle` | oracledb | `npm i db-model-router oracledb` |
16
+ | [Redis](./adapters/redis.md) | `redis` | ioredis | `npm i db-model-router ioredis` |
17
+ | [DynamoDB](./adapters/dynamodb.md) | `dynamodb` | @aws-sdk/client-dynamodb | `npm i db-model-router @aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb` |
18
+
19
+ ## Installation
20
+
21
+ Install the core package, your preferred Express framework, and the driver for your database:
22
+
23
+ ```bash
24
+ # Pick your Express framework (one of the two)
25
+ npm install express
26
+ # OR for ~6x faster performance:
27
+ npm install ultimate-express
28
+
29
+ # Then install db-model-router + your database driver
30
+ npm install db-model-router <driver>
31
+ ```
32
+
33
+ Both `express` and `ultimate-express` are optional peer dependencies — the library auto-detects which one is installed (preferring `ultimate-express` when both are present). All database drivers are also optional peer dependencies.
34
+
35
+ ## MySQL Example
36
+
37
+ ### 1. Connect
38
+
39
+ ```js
40
+ const { init, db, model, route } = require("db-model-router");
41
+
42
+ // Default adapter is mysql, so init() is optional
43
+ db.connect({
44
+ host: "localhost",
45
+ port: 3306,
46
+ user: "root",
47
+ password: "password",
48
+ database: "my_app",
49
+ connectionLimit: 100,
50
+ });
51
+ ```
52
+
53
+ ### 2. Define a Model
54
+
55
+ ```js
56
+ const users = model(
57
+ db,
58
+ "users",
59
+ {
60
+ name: "required|string",
61
+ email: "required|string",
62
+ age: "required|integer",
63
+ meta: "object",
64
+ },
65
+ "id",
66
+ ["email"],
67
+ { safeDelete: "is_deleted" },
68
+ );
69
+ ```
70
+
71
+ Schema types: `string`, `integer`, `numeric`, `object`. Prefix with `required|` to enforce on insert/update.
72
+
73
+ ### 3. Mount REST Routes
74
+
75
+ ```js
76
+ // Works with either express or ultimate-express
77
+ const express = require("express"); // or require("ultimate-express")
78
+ const app = express();
79
+ app.use(express.json());
80
+ app.use("/users", route(users));
81
+ app.listen(3000);
82
+ ```
83
+
84
+ This creates 9 endpoints:
85
+
86
+ | Method | Path | Description |
87
+ | ------ | ------------ | ------------------------------- |
88
+ | GET | `/users/:id` | Get one record by PK |
89
+ | POST | `/users/:id` | Insert a single record |
90
+ | PUT | `/users/:id` | Update a single record |
91
+ | PATCH | `/users/:id` | Partial update (changed fields) |
92
+ | DELETE | `/users/:id` | Delete a single record |
93
+ | GET | `/users/` | List with pagination |
94
+ | POST | `/users/` | Bulk insert (`{ data: [...] }`) |
95
+ | PUT | `/users/` | Bulk update (`{ data: [...] }`) |
96
+ | DELETE | `/users/` | Bulk delete |
97
+
98
+ ### 4. Payload Override
99
+
100
+ Inject values from the request into every payload (useful for multi-tenant apps):
101
+
102
+ ```js
103
+ app.use("/users", route(users, { user_id: "user.user_id" }));
104
+ ```
105
+
106
+ ## Model API
107
+
108
+ All model methods are async.
109
+
110
+ ### insert / update / patch / upsert
111
+
112
+ ```js
113
+ const user = await users.insert({ name: "Alice", email: "a@b.com", age: 30 });
114
+ const bulk = await users.insert({ data: [{ ... }, { ... }] });
115
+ const updated = await users.update({ id: 1, name: "Alice V2", email: "a@b.com", age: 31 });
116
+ const patched = await users.patch({ id: 1, age: 35 }); // partial — only updates age
117
+ ```
118
+
119
+ ### byId / find / findOne / list
120
+
121
+ ```js
122
+ await users.byId(1); // record or null
123
+ await users.find({ name: "Alice" }); // { data: [...], count }
124
+ await users.findOne({ email: "a@b.com" }); // record or false
125
+ await users.list({ page: 0, size: 10, sort: ["-age"] }); // { data: [...], count }
126
+ ```
127
+
128
+ ### remove
129
+
130
+ ```js
131
+ await users.remove(1);
132
+ await users.remove({ name: "Bob" });
133
+ ```
134
+
135
+ ## Filter System
136
+
137
+ Structure: `[OR_groups[AND_conditions[column, operator, value]]]`
138
+
139
+ Operators: `=`, `like`, `not like`, `in`, `not in`, `<`, `>`, `<=`, `>=`, `!=`
140
+
141
+ ```js
142
+ // Alice AND age 30
143
+ await db.get("users", [
144
+ [
145
+ ["name", "=", "Alice"],
146
+ ["age", "=", 30],
147
+ ],
148
+ ]);
149
+
150
+ // Alice OR age > 30
151
+ await db.get("users", [[["name", "=", "Alice"]], [["age", ">", 30]]]);
152
+ ```
153
+
154
+ ## Switching Adapters
155
+
156
+ ```js
157
+ const { init, db, model, route } = require("db-model-router");
158
+ init("postgres"); // or "mongodb", "sqlite3", "mssql", etc.
159
+ db.connect({
160
+ host: "localhost",
161
+ port: 5432,
162
+ user: "postgres",
163
+ password: "password",
164
+ database: "my_app",
165
+ });
166
+ ```
167
+
168
+ The model and route APIs remain identical across all adapters.
169
+
170
+ ## CLI Tools
171
+
172
+ ### generate-app
173
+
174
+ Scaffolds a complete Express REST API from an existing database.
175
+
176
+ ```bash
177
+ rest-router-generate-app --type mysql --env .env
178
+ rest-router-generate-app --type sqlite3 --database ./myapp.db --output ./my-api
179
+ rest-router-generate-app --type postgres --env .env --tables users,posts,posts.comments
180
+ ```
181
+
182
+ Creates: `app.js`, `models/`, `routes/`, `middleware/logger.js`, `.env.example`, `openapi.json`
183
+
184
+ ### generate-model
185
+
186
+ Introspects DB → generates model files with auto-detected PK, unique indexes, timestamps, soft-delete.
187
+
188
+ ```bash
189
+ rest-router-generate-model --type mysql --env .env --output ./models [--tables users,posts]
190
+ ```
191
+
192
+ ### generate-route
193
+
194
+ Generates route files + OpenAPI spec from models. Supports parent-child via dot notation.
195
+
196
+ ```bash
197
+ rest-router-generate-route --models ./models --output ./routes [--tables posts,posts.comments]
198
+ ```
199
+
200
+ `posts.comments` → nested route `posts/:post_id/comments` with FK scoping.
201
+
202
+ ## License
203
+
204
+ Apache-2.0
205
+
206
+ ## LLM Skill Reference
207
+
208
+ For AI/LLM integration, see the [Skill Reference](./SKILL.md).
package/docs/SKILL.md ADDED
@@ -0,0 +1,202 @@
1
+ # db-model-router — LLM Skill Reference
2
+
3
+ Database-agnostic REST API generator for Node.js/Express. Define model → get CRUD API + Express routes. 9 adapters, identical API.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install db-model-router <driver>
9
+ ```
10
+
11
+ Drivers: `mysql2`, `pg`, `better-sqlite3`, `mongodb`, `mssql`, `oracledb`, `ioredis`, `@aws-sdk/client-dynamodb @aws-sdk/lib-dynamodb`
12
+
13
+ ## Init → Connect → Model → Route
14
+
15
+ ```js
16
+ const { init, db, model, route } = require("db-model-router");
17
+ init("postgres"); // mysql|postgres|sqlite3|mongodb|mssql|cockroachdb|oracle|redis|dynamodb
18
+ db.connect({ host, port: 5432, user, password, database });
19
+
20
+ const users = model(
21
+ db,
22
+ "users",
23
+ {
24
+ name: "required|string",
25
+ email: "required|string",
26
+ age: "integer",
27
+ meta: "object",
28
+ },
29
+ "id",
30
+ ["email"],
31
+ {
32
+ safeDelete: "is_deleted",
33
+ created_at: "created_at",
34
+ modified_at: "updated_at",
35
+ },
36
+ );
37
+
38
+ app.use("/users", route(users));
39
+ ```
40
+
41
+ **Critical**: call `init()` before `db.connect()`. Default adapter is mysql. Do NOT destructure `db` before `init()`.
42
+
43
+ ## model(db, table, structure, pk, unique, option)
44
+
45
+ | Param | Type | Description |
46
+ | --------- | --------------- | --------------------------------------------------------------------------------------------------------------------- |
47
+ | structure | `{col: "rule"}` | Types: `string\|integer\|numeric\|object`. Prefix `required\|` for NOT NULL. Exclude PK, timestamps, soft-delete cols |
48
+ | pk | string | Primary key column. Default `"id"` |
49
+ | unique | string[] | Columns for upsert conflict resolution |
50
+ | option | object | `{ safeDelete, created_at, modified_at }` — column names or null |
51
+
52
+ ## Model Methods (all async)
53
+
54
+ ```js
55
+ // INSERT — single returns record, bulk returns {rows, message, type}
56
+ await m.insert({ name: "Alice", email: "a@b.com", age: 30 }) // → {id:1, name:"Alice", ...}
57
+ await m.insert({ data: [{...}, {...}] }) // → {rows:2, message, type:"success"}
58
+
59
+ // UPDATE — PK required in payload
60
+ await m.update({ id: 1, name: "Alice V2", email: "a@b.com", age: 31 })
61
+ await m.update({ data: [{id:1,...}, {id:2,...}] })
62
+
63
+ // PATCH — partial update, only sends changed fields, PK required
64
+ await m.patch({ id: 1, age: 35 }) // → full merged record
65
+
66
+ // UPSERT — PK optional, uses unique cols for conflict
67
+ await m.upsert({ email: "new@b.com", name: "New", age: 20 })
68
+
69
+ // READ
70
+ await m.byId(1) // → record or null
71
+ await m.find({ name: "Alice" }) // → {data:[], count}
72
+ await m.findOne({ email: "a@b.com" }) // → record or false
73
+ await m.list({ page: 0, size: 10, sort: ["-age"] }) // → {data:[], count}
74
+
75
+ // DELETE — with safeDelete: sets column=1; without: hard delete
76
+ await m.remove(1)
77
+ await m.remove({ name: "Bob" })
78
+ ```
79
+
80
+ ## Filter Syntax
81
+
82
+ Structure: `[OR_groups[AND_conditions[col, op, val]]]`
83
+ Ops: `= != < > <= >= like not like in not in`
84
+
85
+ ```js
86
+ [
87
+ [
88
+ ["age", ">", 25],
89
+ ["type", "=", 1],
90
+ ],
91
+ ][([["name", "=", "A"]], [["name", "=", "B"]])][[["type", "in", [1, 2, 3]]]][ // AND // OR // IN
92
+ [["name", "like", "Ali"]]
93
+ ]; // LIKE %Ali%
94
+ ```
95
+
96
+ ## route(model, override?)
97
+
98
+ Generates Express Router with 9 endpoints:
99
+
100
+ | Method | Path | Action |
101
+ | ------ | ------ | -------------------------------- |
102
+ | GET | `/:pk` | Get by PK |
103
+ | POST | `/:id` | Insert single |
104
+ | PUT | `/:id` | Update single (PK from URL) |
105
+ | PATCH | `/:id` | Partial update |
106
+ | DELETE | `/:id` | Delete single |
107
+ | GET | `/` | List (page, size, sort, filters) |
108
+ | POST | `/` | Bulk insert `{data:[...]}` |
109
+ | PUT | `/` | Bulk update `{data:[...]}` |
110
+ | DELETE | `/` | Bulk delete `{data:[...]}` |
111
+
112
+ **Payload override** (multi-tenancy): `route(m, { tenant_id: "user.tenant_id" })` — maps cols to `req` paths via lodash.get.
113
+
114
+ **Query params**: `select_columns=name,email`, `output_content_type=csv|xml|json`, `sort=-age,name`
115
+
116
+ ## CLI Tools
117
+
118
+ ### generate-app (full scaffold)
119
+
120
+ ```bash
121
+ rest-router-generate-app --type mysql --env .env [--output ./dir] [--tables users,posts,posts.comments]
122
+ ```
123
+
124
+ Creates: `app.js`, `models/`, `routes/`, `middleware/logger.js`, `.env.example`, `.gitignore`, `migrations/`, `sessions/`, `openapi.json`
125
+
126
+ ### generate-model (DB introspection → model files)
127
+
128
+ ```bash
129
+ rest-router-generate-model --type <db> --env .env [--output ./models] [--tables t1,t2] [--schema public]
130
+ ```
131
+
132
+ Auto-detects: PK, unique indexes, DEFAULT→optional, timestamp cols, soft-delete cols.
133
+
134
+ ### generate-route (model files → route files + OpenAPI)
135
+
136
+ ```bash
137
+ rest-router-generate-route --models ./models --output ./routes [--tables posts,posts.comments]
138
+ ```
139
+
140
+ Dot notation `parent.child` creates nested routes: `parent/:parent_id/child` with FK scoping via `<parent_singular>_id`.
141
+
142
+ ## Connection Configs
143
+
144
+ ```js
145
+ // MySQL (default)
146
+ db.connect({
147
+ host,
148
+ port: 3306,
149
+ user,
150
+ password,
151
+ database,
152
+ connectionLimit: 100,
153
+ });
154
+
155
+ // PostgreSQL / CockroachDB
156
+ init("postgres"); // cockroachdb port: 26257
157
+ db.connect({ host, port: 5432, user, password, database });
158
+
159
+ // SQLite3
160
+ init("sqlite3");
161
+ db.connect({ database: "./file.db" }); // or ":memory:"
162
+
163
+ // MongoDB
164
+ init("mongodb");
165
+ db.connect({ host, port: 27017, username, password, database });
166
+ // or: db.connect({ uri: "mongodb://user:pass@host:27017/db" })
167
+
168
+ // MSSQL
169
+ init("mssql");
170
+ await db.connect({
171
+ server: host,
172
+ port: 1433,
173
+ user,
174
+ password,
175
+ database,
176
+ options: { encrypt: false, trustServerCertificate: true },
177
+ });
178
+
179
+ // Oracle
180
+ init("oracle");
181
+ db.connect({ host, port: 1521, user, password, database });
182
+
183
+ // Redis
184
+ init("redis");
185
+ db.connect({ host, port: 6379, password });
186
+
187
+ // DynamoDB
188
+ init("dynamodb");
189
+ db.connect({ region, endpoint, accessKeyId, secretAccessKey });
190
+ ```
191
+
192
+ ## Rules
193
+
194
+ 1. `init()` before `db.connect()`. Don't destructure `db` before `init()`.
195
+ 2. `modelStructure` excludes: PK col, timestamp cols, soft-delete cols.
196
+ 3. `update()`/`patch()` require PK in payload. `upsert()` PK is optional.
197
+ 4. `findOne()` returns `false` on no match. `byId()` returns `null`.
198
+ 5. Bulk ops wrap in `{ data: [...] }`. Single ops use flat object.
199
+ 6. Timestamps auto-stripped from payloads. DB handles defaults/triggers.
200
+ 7. `safeDelete` makes `remove()` soft-delete; all reads auto-filter deleted rows.
201
+ 8. `list()` defaults: page=0, size=30. `sort` array: `["-col"]` for DESC.
202
+ 9. CommonJS only (`require`). Use dynamic `import()` for ESM.
@@ -0,0 +1,49 @@
1
+ # CockroachDB Adapter
2
+
3
+ Uses the [pg](https://www.npmjs.com/package/pg) driver (CockroachDB is PostgreSQL wire-compatible).
4
+
5
+ ## Connection
6
+
7
+ ```js
8
+ const { init, db, model, route } = require("db-model-router");
9
+ init("cockroachdb");
10
+
11
+ db.connect({
12
+ host: "localhost",
13
+ port: 26257,
14
+ database: "defaultdb",
15
+ user: "root",
16
+ password: "",
17
+ });
18
+ ```
19
+
20
+ ## Environment Variables
21
+
22
+ ```env
23
+ CRDB_HOST=localhost
24
+ CRDB_PORT=26257
25
+ CRDB_NAME=defaultdb
26
+ CRDB_USER=root
27
+ CRDB_PASS=
28
+ ```
29
+
30
+ ## Notes
31
+
32
+ - `SERIAL` columns use CockroachDB's `unique_rowid()` which generates INT8 values
33
+ - Large INT8 values that exceed `Number.MAX_SAFE_INTEGER` are kept as strings to preserve precision
34
+ - Includes automatic retry logic for transient connection errors
35
+ - Uses `ON CONFLICT` for upsert operations
36
+ - Run with `--insecure` flag for local development (see docker-compose.yml)
37
+
38
+ ## Table Creation
39
+
40
+ ```sql
41
+ CREATE TABLE users (
42
+ id SERIAL PRIMARY KEY,
43
+ name VARCHAR NOT NULL,
44
+ email VARCHAR NOT NULL,
45
+ age INTEGER NOT NULL
46
+ );
47
+ ```
48
+
49
+ [← Back to main docs](../README.md)
@@ -0,0 +1,53 @@
1
+ # DynamoDB Adapter
2
+
3
+ Uses [@aws-sdk/client-dynamodb](https://www.npmjs.com/package/@aws-sdk/client-dynamodb) and [@aws-sdk/lib-dynamodb](https://www.npmjs.com/package/@aws-sdk/lib-dynamodb).
4
+
5
+ ## Connection
6
+
7
+ ```js
8
+ const { init, db, model, route } = require("db-model-router");
9
+ init("dynamodb");
10
+
11
+ db.connect({
12
+ region: "us-east-1",
13
+ // For local development (DynamoDB Local):
14
+ endpoint: "http://localhost:8000",
15
+ accessKeyId: "fakeAccessKey",
16
+ secretAccessKey: "fakeSecretKey",
17
+ primaryKey: "id",
18
+ });
19
+ ```
20
+
21
+ ## Environment Variables
22
+
23
+ ```env
24
+ DYNAMODB_HOST=localhost
25
+ DYNAMODB_PORT=8000
26
+ DYNAMODB_REGION=us-east-1
27
+ DYNAMODB_ACCESS_KEY=fakeAccessKey
28
+ DYNAMODB_SECRET_KEY=fakeSecretKey
29
+ ```
30
+
31
+ ## Notes
32
+
33
+ - Tables must be created beforehand (the adapter does not create tables)
34
+ - Auto-generates UUID primary keys for records missing the PK field
35
+ - Filter operators are mapped to DynamoDB FilterExpression syntax
36
+ - `like` uses `contains()`, `in` uses `IN ()`
37
+ - All filtering and pagination happen via `Scan` with in-memory post-processing
38
+ - Batch writes are chunked into groups of 25 (DynamoDB limit)
39
+ - `UpdateCommand` is used for upsert operations
40
+ - Best suited for serverless / AWS-native architectures
41
+
42
+ ## Table Creation (AWS CLI)
43
+
44
+ ```bash
45
+ aws dynamodb create-table \
46
+ --table-name users \
47
+ --attribute-definitions AttributeName=id,AttributeType=S \
48
+ --key-schema AttributeName=id,KeyType=HASH \
49
+ --billing-mode PAY_PER_REQUEST \
50
+ --endpoint-url http://localhost:8000
51
+ ```
52
+
53
+ [← Back to main docs](../README.md)
@@ -0,0 +1,56 @@
1
+ # MongoDB Adapter
2
+
3
+ Uses the official [mongodb](https://www.npmjs.com/package/mongodb) Node.js driver.
4
+
5
+ ## Connection
6
+
7
+ ```js
8
+ const { init, db, model, route } = require("db-model-router");
9
+ init("mongodb");
10
+
11
+ db.connect({
12
+ host: "localhost",
13
+ port: 27017,
14
+ database: "my_app",
15
+ // or with auth:
16
+ username: "admin",
17
+ password: "secret",
18
+ // or with a full URI:
19
+ uri: "mongodb://admin:secret@localhost:27017",
20
+ });
21
+ ```
22
+
23
+ ## Environment Variables
24
+
25
+ ```env
26
+ MONGO_HOST=localhost
27
+ MONGO_PORT=27017
28
+ MONGO_DB=test_db
29
+ ```
30
+
31
+ ## Notes
32
+
33
+ - Primary key is `_id` (MongoDB's default ObjectId)
34
+ - String `_id` values matching the 24-char hex format are auto-converted to `ObjectId`
35
+ - Filter operators are mapped to MongoDB query operators (`$eq`, `$regex`, `$in`, etc.)
36
+ - `like` uses `$regex` with case-insensitive matching
37
+ - No schema/table creation needed — collections are created on first insert
38
+
39
+ ## Model Definition
40
+
41
+ ```js
42
+ const users = model(
43
+ db,
44
+ "users",
45
+ {
46
+ _id: "string",
47
+ name: "required|string",
48
+ email: "required|string",
49
+ age: "required|integer",
50
+ },
51
+ "_id",
52
+ ["_id"],
53
+ );
54
+ ```
55
+
56
+ [← Back to main docs](../README.md)
@@ -0,0 +1,55 @@
1
+ # MSSQL (SQL Server) Adapter
2
+
3
+ Uses the [mssql](https://www.npmjs.com/package/mssql) driver with tedious.
4
+
5
+ ## Connection
6
+
7
+ ```js
8
+ const { init, db, model, route } = require("db-model-router");
9
+ init("mssql");
10
+
11
+ await db.connect({
12
+ server: "localhost",
13
+ port: 1433,
14
+ database: "master",
15
+ user: "sa",
16
+ password: "Password123!",
17
+ options: {
18
+ encrypt: false,
19
+ trustServerCertificate: true,
20
+ },
21
+ });
22
+ ```
23
+
24
+ Note: `db.connect()` is async for MSSQL — use `await`.
25
+
26
+ ## Environment Variables
27
+
28
+ ```env
29
+ MSSQL_HOST=localhost
30
+ MSSQL_PORT=1433
31
+ MSSQL_DB=master
32
+ MSSQL_USER=sa
33
+ MSSQL_PASSWORD=Password123!
34
+ ```
35
+
36
+ ## Notes
37
+
38
+ - Column names are escaped with `[brackets]`
39
+ - Uses `MERGE` statements for upsert operations
40
+ - IDENTITY columns are auto-excluded from INSERT in MERGE statements
41
+ - Pagination uses `OFFSET ... ROWS FETCH NEXT ... ROWS ONLY`
42
+ - `OUTPUT INSERTED.*` is used to return inserted rows
43
+
44
+ ## Table Creation
45
+
46
+ ```sql
47
+ CREATE TABLE users (
48
+ id INT IDENTITY(1,1) PRIMARY KEY,
49
+ name NVARCHAR(255),
50
+ email NVARCHAR(255),
51
+ age INT
52
+ );
53
+ ```
54
+
55
+ [← Back to main docs](../README.md)
@@ -0,0 +1,52 @@
1
+ # Oracle Adapter
2
+
3
+ Uses [oracledb](https://www.npmjs.com/package/oracledb) (Oracle Instant Client required).
4
+
5
+ ## Connection
6
+
7
+ ```js
8
+ const { init, db, model, route } = require("db-model-router");
9
+ init("oracle");
10
+
11
+ db.connect({
12
+ host: "localhost",
13
+ port: 1521,
14
+ database: "XEPDB1",
15
+ user: "system",
16
+ password: "oracle",
17
+ });
18
+ ```
19
+
20
+ ## Environment Variables
21
+
22
+ ```env
23
+ ORACLE_HOST=localhost
24
+ ORACLE_PORT=1521
25
+ ORACLE_DB=XEPDB1
26
+ ORACLE_USER=system
27
+ ORACLE_PASSWORD=oracle
28
+ ```
29
+
30
+ ## Notes
31
+
32
+ - Requires Oracle Instant Client installed on the host
33
+ - Uses connection pooling with session callbacks for NLS date format
34
+ - MySQL-style `?` placeholders are auto-translated to `:1, :2, ...`
35
+ - Includes a SQL translator that converts MySQL DDL/DML to Oracle syntax
36
+ - `MERGE INTO ... USING DUAL` is used for upsert operations
37
+ - `RETURNING ... INTO :pk_out` is used to retrieve auto-generated IDs
38
+ - Oracle reserved words in column names are auto-quoted
39
+ - `CLOB` values are fetched as strings
40
+
41
+ ## Table Creation
42
+
43
+ ```sql
44
+ CREATE TABLE users (
45
+ id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
46
+ name VARCHAR2(255) NOT NULL,
47
+ email VARCHAR2(255) NOT NULL,
48
+ age NUMBER NOT NULL
49
+ );
50
+ ```
51
+
52
+ [← Back to main docs](../README.md)