Skip to content

Commit ec96958

Browse files
chore: wip
1 parent f866596 commit ec96958

File tree

3 files changed

+322
-0
lines changed

3 files changed

+322
-0
lines changed

docs/.vitepress/components.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// @ts-nocheck
33
// Generated by unplugin-vue-components
44
// Read more: https://github.com/vuejs/core/pull/3399
5+
// biome-ignore lint: disable
56
export {}
67

78
/* prettier-ignore */

docs/.vitepress/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ const sidebar = [
6565
{ text: 'Relations', link: '/features/relations' },
6666
{ text: 'Transactions', link: '/features/transactions' },
6767
{ text: 'Pagination', link: '/features/pagination' },
68+
{ text: 'Migrations', link: '/features/migrations' },
6869
{ text: 'CLI', link: '/features/cli' },
6970
],
7071
},

docs/features/migrations.md

Lines changed: 320 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,320 @@
1+
# Migrations
2+
3+
Generate and execute database migrations directly from your TypeScript models with full type safety and dialect support.
4+
5+
## Overview
6+
7+
The migration system automatically generates SQL DDL statements from your model definitions, supporting incremental migrations and full schema generation. It handles table creation, column additions, foreign keys, indexes, and more across PostgreSQL, MySQL, and SQLite.
8+
9+
## Features
10+
11+
- **Model-driven**: Generate migrations from your TypeScript model definitions
12+
- **Multi-dialect**: Support for PostgreSQL, MySQL, and SQLite
13+
- **Incremental**: Smart diff-based migrations that only apply changes
14+
- **Full schema**: Option to generate complete schema SQL
15+
- **State tracking**: Maintains migration state for incremental updates
16+
- **Type safe**: Full TypeScript support with inferred types
17+
18+
## Basic Usage
19+
20+
### Generate and Apply Migration
21+
22+
```ts
23+
import { generateMigration, executeMigration } from 'bun-query-builder'
24+
25+
// Generate migration from models directory
26+
const migration = await generateMigration('./models', {
27+
dialect: 'postgres',
28+
apply: true,
29+
full: true
30+
})
31+
32+
// Execute the migration
33+
await executeMigration(migration)
34+
```
35+
36+
### Migration Options
37+
38+
```ts
39+
interface MigrateOptions {
40+
dialect?: 'postgres' | 'mysql' | 'sqlite' // Default: 'postgres'
41+
state?: string // Path to state file
42+
apply?: boolean // Execute SQL immediately
43+
full?: boolean // Force full schema generation
44+
}
45+
```
46+
47+
## CLI Commands
48+
49+
### migrate
50+
51+
Generate SQL migrations from models:
52+
53+
```bash
54+
# Basic migration generation
55+
query-builder migrate ./app/Models
56+
57+
# With specific dialect
58+
query-builder migrate ./app/Models --dialect mysql
59+
60+
# Apply migration immediately
61+
query-builder migrate ./app/Models --apply
62+
63+
# Force full schema generation
64+
query-builder migrate ./app/Models --full
65+
66+
# Custom state file location
67+
query-builder migrate ./app/Models --state ./migrations/state.json
68+
```
69+
70+
### Examples
71+
72+
```bash
73+
# Generate PostgreSQL migration for User models
74+
query-builder migrate ./app/Models --dialect postgres
75+
76+
# Apply MySQL migration immediately
77+
query-builder migrate ./app/Models --dialect mysql --apply
78+
79+
# Generate full schema for SQLite
80+
query-builder migrate ./app/Models --dialect sqlite --full
81+
```
82+
83+
## Migration Types
84+
85+
### Incremental Migrations
86+
87+
By default, the system generates incremental migrations that only apply changes:
88+
89+
- Creates new tables
90+
- Adds new columns
91+
- Adds new foreign keys
92+
- Adds new indexes
93+
- Maintains existing data
94+
95+
### Full Schema Migrations
96+
97+
Use the `--full` flag to generate complete schema SQL:
98+
99+
- Drops and recreates all tables
100+
- Useful for development/testing
101+
- **Warning**: Destructive operation
102+
103+
## State Management
104+
105+
The migration system maintains state in a JSON file (default: `.qb-migrations.<dialect>.json`) that tracks:
106+
107+
- Current schema plan
108+
- Migration hash for change detection
109+
- Last update timestamp
110+
111+
### State File Location
112+
113+
```ts
114+
// Default location
115+
const defaultStatePath = join(dir, `.qb-migrations.${dialect}.json`)
116+
117+
// Custom location
118+
const migration = await generateMigration('./models', {
119+
state: './custom/path/state.json'
120+
})
121+
```
122+
123+
## Model Inference
124+
125+
Migrations are generated by analyzing your model definitions:
126+
127+
```ts
128+
// Example model that generates migration
129+
const models = defineModels({
130+
User: {
131+
name: 'User',
132+
table: 'users',
133+
primaryKey: 'id',
134+
attributes: {
135+
id: { validation: { rule: {} } },
136+
name: { validation: { rule: {} } },
137+
email: { validation: { rule: {} } },
138+
active: { validation: { rule: {} } }
139+
}
140+
}
141+
})
142+
```
143+
144+
### Supported Types
145+
146+
The system automatically infers SQL types from your validation rules:
147+
148+
- `string``varchar(255)` / `text`
149+
- `boolean``boolean` / `tinyint(1)`
150+
- `integer``integer`
151+
- `bigint``bigint`
152+
- `float``real`
153+
- `date``date`
154+
- `datetime``timestamp` / `datetime`
155+
- `json``jsonb` / `json` / `text`
156+
157+
## Advanced Features
158+
159+
### Foreign Key Relationships
160+
161+
```ts
162+
const models = defineModels({
163+
Post: {
164+
name: 'Post',
165+
table: 'posts',
166+
attributes: {
167+
user_id: {
168+
validation: { rule: {} },
169+
references: { table: 'users', column: 'id' }
170+
}
171+
}
172+
}
173+
})
174+
```
175+
176+
### Indexes and Constraints
177+
178+
```ts
179+
const models = defineModels({
180+
User: {
181+
name: 'User',
182+
table: 'users',
183+
attributes: {
184+
email: {
185+
validation: { rule: {} },
186+
unique: true
187+
},
188+
created_at: {
189+
validation: { rule: {} },
190+
index: { name: 'created_at_idx' }
191+
}
192+
}
193+
}
194+
})
195+
```
196+
197+
## Error Handling
198+
199+
### Migration Failures
200+
201+
```ts
202+
try {
203+
const migration = await generateMigration('./models', {
204+
dialect: 'postgres',
205+
apply: true
206+
})
207+
208+
await executeMigration(migration)
209+
} catch (err) {
210+
console.error('Migration failed:', err)
211+
// Handle rollback or retry logic
212+
}
213+
```
214+
215+
### Common Issues
216+
217+
- **Dialect mismatch**: Ensure state file dialect matches current dialect
218+
- **Permission errors**: Check database connection and privileges
219+
- **Syntax errors**: Verify model definitions and validation rules
220+
221+
## Best Practices
222+
223+
### Development Workflow
224+
225+
1. **Start with full migration**: Use `--full` for initial schema setup
226+
2. **Use incremental for changes**: Let the system detect and apply only changes
227+
3. **Version control state files**: Commit migration state files to track schema evolution
228+
4. **Test migrations**: Always test migrations in development before production
229+
230+
### Production Considerations
231+
232+
- **Backup first**: Always backup before applying migrations
233+
- **Review SQL**: Check generated SQL before applying
234+
- **Rollback plan**: Have a strategy for migration failures
235+
- **State consistency**: Ensure state files are properly managed across environments
236+
237+
## Integration Examples
238+
239+
### With Build Scripts
240+
241+
```json
242+
{
243+
"scripts": {
244+
"migrate": "query-builder migrate ./src/models --apply",
245+
"migrate:dev": "query-builder migrate ./src/models --dialect postgres --full",
246+
"migrate:test": "query-builder migrate ./test/models --dialect sqlite --full"
247+
}
248+
}
249+
```
250+
251+
### With CI/CD
252+
253+
```yaml
254+
# GitHub Actions example
255+
- name: Run migrations
256+
run: |
257+
query-builder migrate ./src/models --dialect postgres --apply
258+
```
259+
260+
### With Testing
261+
262+
```ts
263+
// In test setup
264+
beforeAll(async () => {
265+
const result = await generateMigration('./test/models', {
266+
dialect: 'postgres',
267+
full: true
268+
})
269+
270+
if (result.sqlStatements.length > 0) {
271+
await executeMigration(result)
272+
}
273+
})
274+
```
275+
276+
## API Reference
277+
278+
### generateMigration
279+
280+
```ts
281+
function generateMigration(
282+
dir: string,
283+
opts?: MigrateOptions
284+
): Promise<GenerateMigrationResult>
285+
```
286+
287+
**Parameters:**
288+
289+
- `dir`: Path to models directory
290+
- `opts`: Migration options
291+
292+
**Returns:**
293+
294+
- `sql`: Complete SQL string
295+
- `sqlStatements`: Array of individual SQL statements
296+
- `hasChanges`: Whether any changes were detected
297+
- `plan`: Generated migration plan
298+
299+
### executeMigration
300+
301+
```ts
302+
function executeMigration(
303+
migration: GenerateMigrationResult
304+
): Promise<boolean>
305+
```
306+
307+
**Parameters:**
308+
309+
- `migration`: Result from generateMigration
310+
311+
**Returns:**
312+
313+
- `boolean`: Success status
314+
315+
## Related
316+
317+
- [Query Builder](./builder.md) - Build type-safe queries
318+
- [Relations](./relations.md) - Handle model relationships
319+
- [CLI](./cli.md) - Command-line interface
320+
- [Configuration](../config.md) - Global settings and options

0 commit comments

Comments
 (0)