@aradox/multi-orm
Version:
Type-safe ORM with multi-datasource support, row-level security, and Prisma-like API for PostgreSQL, SQL Server, and HTTP APIs
370 lines (293 loc) • 7.54 kB
Markdown
# Quick Reference Card
**One-page reference for common ORM operations**
## Setup
```typescript
import { ORMClient } from '@your-org/orm';
import * as fs from 'fs';
const schema = fs.readFileSync('./orm.qts', 'utf-8');
const orm = new ORMClient(schema, { schemaPath: './orm.qts' });
const db = orm.generate();
```
## Query Operations
### Find Many
```typescript
const users = await db.User.findMany({
where: { role: { eq: 'admin' } },
orderBy: { created_at: 'desc' },
skip: 0,
take: 10
});
```
### Find Unique
```typescript
const user = await db.User.findUnique({
where: { id: 123 }
});
```
### Find First
```typescript
const firstAdmin = await db.User.findFirst({
where: { role: { eq: 'admin' } }
});
```
### Count
```typescript
const count = await db.User.count({
where: { is_active: { eq: true } }
});
```
## CRUD Operations
### Create
```typescript
const user = await db.User.create({
data: {
email: 'john@example.com',
name: 'John Doe',
role: 'user',
tenant_id: 1
}
});
```
### Create Many
```typescript
const result = await db.User.createMany({
data: [
{ email: 'user1@example.com', name: 'User 1', role: 'user', tenant_id: 1 },
{ email: 'user2@example.com', name: 'User 2', role: 'user', tenant_id: 1 }
]
});
console.log(`Created ${result.count} users`);
```
### Update
```typescript
const updated = await db.User.update({
where: { id: 123 },
data: { name: 'Jane Updated' }
});
```
### Update Many
```typescript
const result = await db.User.updateMany({
where: { role: { eq: 'user' } },
data: { is_active: true }
});
```
### Delete
```typescript
const deleted = await db.User.delete({
where: { id: 123 }
});
```
### Delete Many
```typescript
const result = await db.User.deleteMany({
where: { is_active: { eq: false } }
});
```
### Upsert
```typescript
const user = await db.User.upsert({
where: { email: 'john@example.com' },
create: {
email: 'john@example.com',
name: 'John Doe',
role: 'user',
tenant_id: 1
},
update: {
name: 'John Updated'
}
});
```
## Where Operators
### Comparison
```typescript
{ price: { eq: 99.99 } } // Equal
{ price: { ne: 0 } } // Not equal
{ price: { gt: 50 } } // Greater than
{ price: { gte: 50 } } // Greater than or equal
{ price: { lt: 100 } } // Less than
{ price: { lte: 100 } } // Less than or equal
{ status: { in: ['active', 'pending'] } }
{ status: { notIn: ['deleted', 'archived'] } }
```
### String
```typescript
{ email: { contains: '@example.com' } } // LIKE '%value%'
{ name: { startsWith: 'John' } } // LIKE 'value%'
{ phone: { endsWith: '1234' } } // LIKE '%value'
```
### Null
```typescript
{ name: { isNull: true } } // IS NULL
{ email: { isNotNull: true } } // IS NOT NULL
```
### Logical
```typescript
// AND (implicit)
{ is_active: { eq: true }, role: { eq: 'admin' } }
// OR
{ OR: [{ role: { eq: 'admin' } }, { role: { eq: 'moderator' } }] }
// NOT
{ NOT: { status: { eq: 'banned' } } }
```
## Relations
```typescript
const users = await db.User.findMany({
include: {
orders: {
where: { status: { eq: 'completed' } },
take: 5
}
}
});
```
## Field Selection
```typescript
const users = await db.User.findMany({
select: {
id: true,
email: true,
name: true
}
});
```
## Middleware
### Register Middleware
```typescript
import {
tenantIsolationMiddleware,
rbacMiddleware,
auditLoggingMiddleware
} from '@your-org/orm/middleware/examples';
db.use(tenantIsolationMiddleware(['Customer', 'Order']));
db.use(rbacMiddleware({ 'Invoice': ['admin', 'finance'] }));
db.use(auditLoggingMiddleware({ async log(entry) { ... } }));
```
### Set Context
```typescript
db.setContext({
user: {
id: session.user.id,
tenantId: session.user.tenantId,
role: session.user.role
}
});
```
## Environment Variables
```bash
# Database
DATABASE_URL="Server=localhost;Database=MyDB;Integrated Security=true;TrustServerCertificate=true"
# Logging
LOG_LEVEL=debug # off, error, warn, info, debug
LOG_MODULES=mssql,postgres # Comma-separated module names
```
## CLI Commands
```bash
npm run generate # Generate types from schema
npm run validate # Validate schema
npm run build # Build TypeScript
```
## Debug SQL Queries
```bash
# Windows
$env:LOG_LEVEL="debug"; $env:LOG_MODULES="mssql"; node dist/app.js
# Linux/Mac
LOG_LEVEL=debug LOG_MODULES=mssql node dist/app.js
```
## Schema Example
```typescript
config {
maxIncludeDepth = 5
maxFanOut = 100
strictMode = false
}
datasource main_db {
provider = "sqlserver"
url = env("DATABASE_URL")
}
model User @datasource(main_db) {
id Int @id @default(autoincrement())
email String @unique
name String?
role String
tenant_id Int
created_at DateTime?
orders Order[] @relation(fields:[id],references:[user_id],strategy:"lookup")
}
model Order @datasource(main_db) {
id Int @id @default(autoincrement())
user_id Int
total Float
status String?
tenant_id Int
user User @relation(fields:[user_id],references:[id],strategy:"lookup")
}
```
## Connection Strings
### SQL Server - Windows Auth
```
Server=MYSERVER;Database=MyDB;Integrated Security=true;TrustServerCertificate=true
```
### SQL Server - SQL Auth
```
Server=localhost;Database=MyDB;User Id=sa;Password=yourPassword;Encrypt=true
```
### PostgreSQL
```
postgresql://user:password@localhost:5432/mydb?schema=public
```
## Best Practices
✅ **DO:**
- Generate types after schema changes: `npm run generate`
- Set context per request (not globally)
- Use defense in depth (DB RLS + middleware + API validation)
- Always call `db.$disconnect()` when done
- Handle middleware errors appropriately
❌ **DON'T:**
- Expose ORM client to frontend (use API layer)
- Trust user input for `tenant_id` (use session value)
- Set global context (causes race conditions)
- Forget to regenerate types after schema changes
## Error Handling
```typescript
try {
const customers = await db.Customer.findMany({});
return NextResponse.json({ customers });
} catch (error) {
if (error.message.includes('RBAC:')) {
return NextResponse.json({ error: 'Forbidden' }, { status: 403 });
}
if (error.message.includes('Tenant isolation:')) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
}
console.error('Database error:', error);
return NextResponse.json({ error: 'Internal error' }, { status: 500 });
}
```
## Full Documentation
📚 **[Complete User Guide](./USER_GUIDE.md)** - Comprehensive documentation
### Quick Links
- [User Guide](./USER_GUIDE.md) - Complete documentation
- [Hooks & Middleware Guide](./HOOKS_MIDDLEWARE_GUIDE.md) - RLS and middleware
- [SQL Logging Guide](./SQL_LOGGING_GUIDE.md) - Debug queries
- [CRUD Guide](./CRUD_GUIDE.md) - CRUD operations
- [AI Coding Guide](./AI_CODING_GUIDE.md) - Multi-tenant apps
**Version:** 1.0.0
**Last Updated:** November 17, 2025