@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
266 lines (204 loc) • 7.66 kB
Markdown
# SQL Query Debugging Guide
## Overview
The ORM includes comprehensive SQL query logging to help you debug and understand the queries being generated from your schema.
## Quick Start
Enable SQL query logging by setting the `LOG_LEVEL` environment variable to `debug`:
### Windows (PowerShell)
```powershell
$env:LOG_LEVEL="debug"
node dist/Example/test-sql-logging.js
```
### Linux/macOS
```bash
LOG_LEVEL=debug node dist/Example/test-sql-logging.js
```
## Features
### 📋 SQL Query Logging
All database adapters log the generated SQL queries with the 📋 indicator:
```
2025-11-17T10:10:03.678Z [MSSQL] 📋 SQL Query: SELECT TOP(?) Name, Email FROM [dbo].[Customers] WHERE Name LIKE ?
2025-11-17T10:10:03.680Z [MSSQL] 📋 Parameters: [5,"%John%"]
```
### 🌐 HTTP Request Logging
HTTP API calls are logged with the 🌐 indicator:
```
2025-11-17T10:10:03.123Z [HTTP] 🌐 HTTP Request: GET https://jsonplaceholder.typicode.com/posts
2025-11-17T10:10:03.124Z [HTTP] 🌐 Query params: {"userId":1}
```
## Filtering by Module
Use `LOG_MODULES` to filter logs by adapter or component:
### Show only MSSQL queries
```powershell
$env:LOG_LEVEL="debug"; $env:LOG_MODULES="mssql"
node dist/Example/test-sql-logging.js
```
### Show only PostgreSQL queries
```powershell
$env:LOG_LEVEL="debug"; $env:LOG_MODULES="postgres"
node dist/Example/test-sql-logging.js
```
### Show only HTTP requests
```powershell
$env:LOG_LEVEL="debug"; $env:LOG_MODULES="http"
node dist/Example/test-sql-logging.js
```
### Show multiple modules
```powershell
$env:LOG_LEVEL="debug"; $env:LOG_MODULES="mssql,http"
node dist/Example/test-sql-logging.js
```
## Available Modules
- `mssql` - SQL Server queries (both tedious and ODBC drivers)
- `postgres` - PostgreSQL queries
- `http` - HTTP API requests
- `stitcher` - Cross-datasource relation stitching
- `runtime` - ORM initialization and adapter creation
- `parser` - Schema parsing
- `typegen` - Type generation
- `cli` - CLI commands
## Adapter-Specific Details
### MSSQL Adapter (Tedious)
Logs parameterized queries with `@param` placeholders:
```
📋 SQL Query: SELECT * FROM [dbo].[Customers] WHERE Id = @p1
📋 Parameters: [42]
```
### MSSQL Native Adapter (ODBC)
Logs both named and ODBC-style queries:
```
📋 SQL Query (named params): SELECT * FROM [dbo].[Customers] WHERE Id = @p0
📋 SQL Query (ODBC): SELECT * FROM [dbo].[Customers] WHERE Id = ?
📋 Parameters: [42]
```
### PostgreSQL Adapter
Logs queries with `$1, $2` placeholders:
```
📋 SQL Query: SELECT * FROM customers WHERE id = $1
📋 Parameters: [42]
```
### HTTP Adapter
Logs HTTP method, URL, and query parameters:
```
🌐 HTTP Request: GET https://api.example.com/users
🌐 Query params: {"limit":10,"offset":0}
```
## Use Cases
### 1. Verify @map Attribute
Check that field names are correctly mapped to database columns:
```typescript
// Schema
model User {
id Int @id @map("Id")
firstName String @map("FirstName")
email String @map("Email")
}
// Logged SQL
📋 SQL Query: SELECT Id, FirstName, Email FROM [dbo].[User]
```
### 2. Debug WHERE Clauses
See how filters are translated to SQL:
```typescript
await client.Customers.findMany({
where: {
Name: { contains: 'John' },
IsActive: true
}
});
// Logged SQL
📋 SQL Query: SELECT * FROM [dbo].[Customers] WHERE Name LIKE ? AND IsActive = ?
📋 Parameters: ["%John%",true]
```
### 3. Optimize Queries
Identify slow or inefficient queries:
```typescript
// Check if you're accidentally fetching too many fields
await client.Orders.findMany({
select: { Id: true, OrderNumber: true } // Selective fields
});
// Logged SQL
📋 SQL Query: SELECT Id, OrderNumber FROM [dbo].[Orders] // Good!
```
### 4. Learn SQL Generation
Understand how the ORM translates your DSL queries:
```typescript
// Complex query with multiple filters
await client.Products.findMany({
where: {
OR: [
{ Price: { gte: 100 } },
{ Category: 'Electronics' }
]
},
orderBy: { Price: 'desc' },
take: 10
});
// See the generated SQL with all conditions
```
## Performance Considerations
- **Zero overhead when disabled**: Logging is OFF by default (`LOG_LEVEL=off`)
- **Fast path**: Level check happens before any string formatting
- **Production safe**: No performance impact unless explicitly enabled
## Environment Variables
| Variable | Values | Default | Description |
|----------|--------|---------|-------------|
| `LOG_LEVEL` | `off`, `error`, `warn`, `info`, `debug` | `off` | Controls log verbosity |
| `LOG_MODULES` | Comma-separated module names | (all) | Filters logs by module |
## Example: Full Debug Session
```powershell
# Enable all debug logging
$env:LOG_LEVEL="debug"
# Run your application
node dist/your-app.js
# You'll see:
# - SQL queries with parameters
# - HTTP requests with URLs
# - Relation stitching logic
# - Adapter initialization
# - Type generation steps
```
## Tips
1. **Start with single module**: Use `LOG_MODULES` to focus on one adapter
2. **Check parameters**: SQL injection protection uses parameterization
3. **Verify @map**: Ensure physical column names match your database
4. **Copy queries**: Test SQL directly in SQL Server Management Studio or psql
5. **Performance**: Look for N+1 query patterns in relation stitching
## Multi-Database Query Example
See `Example/test-multi-db-logging.ts` for a comprehensive demo showing SQL query logging across multiple datasources:
```bash
# Windows PowerShell
$env:LOG_LEVEL="debug"; node dist/Example/test-multi-db-logging.js
# Linux/Mac
LOG_LEVEL=debug node dist/Example/test-multi-db-logging.js
```
This example demonstrates:
- **Database 1 (ORMtest)**: Customers, Products, Orders, OrderItems
- **Database 2 (ORMtest2)**: Employees, Payments, Invoices
- **HTTP API (JSONPlaceholder)**: Posts, Comments
Example output shows queries from all three datasources:
```
2025-11-17T10:20:33.372Z [MSSQL] 📋 SQL Query: SELECT TOP(?) * FROM [dbo].[Customers] WHERE PostId = ?
2025-11-17T10:20:33.373Z [MSSQL] 📋 Parameters: [2,1]
✅ Result: Found 2 customers
2025-11-17T10:20:33.464Z [MSSQL] 📋 SQL Query: SELECT TOP(?) * FROM [dbo].[Payments] WHERE Status = ?
✅ Result: Found 0 paid payments (from DB2)
2025-11-17T10:20:33.476Z [MSSQL] 📋 SQL Query: SELECT TOP(?) * FROM [dbo].[Products] WHERE CommentId = ?
✅ Result: Found 2 products with comments (from DB1)
```
### Key Observations from Multi-Database Queries
1. **Adapter-Specific Formats**: Each datasource shows queries in its native format
- SQL Server (MSSQL): `?` placeholders (ODBC) or `@param` (tedious)
- PostgreSQL: `$1, $2` placeholders
- HTTP: Full URL with query parameters
2. **Relation Stitching**: The stitcher joins data in memory
- Root query fetches parent records from one datasource
- Related records fetched separately from other datasources
- All stitching happens in-memory after individual queries complete
3. **Performance Insights**:
- Identify N+1 query patterns across datasources
- See when bulk endpoints reduce HTTP request count
- Verify SQL queries are properly parameterized for safety
## Next Steps
- See `Example/test-sql-logging.ts` for basic SQL logging example
- See `Example/test-multi-db-logging.ts` for multi-database example
- Check `src/utils/logger.ts` for logger implementation
- Read `docs/done.md` for implementation details