Add comprehensive documentation for decorators, migration, and relationships in DebrosFramework #5
106
docs/docs/advanced/automatic-pinning.md
Normal file
106
docs/docs/advanced/automatic-pinning.md
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
# Automatic Pinning
|
||||||
|
|
||||||
|
Automatic pinning optimizes data availability by keeping frequently accessed data readily available across the network.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
DebrosFramework includes automatic pinning functionality that intelligently pins important data to improve performance and availability.
|
||||||
|
|
||||||
|
## Pinning Strategies
|
||||||
|
|
||||||
|
### Fixed Pinning
|
||||||
|
|
||||||
|
Pin specific content permanently:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore',
|
||||||
|
pinning: {
|
||||||
|
strategy: 'fixed',
|
||||||
|
maxPins: 1000
|
||||||
|
}
|
||||||
|
})
|
||||||
|
class ImportantData extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Popularity-based Pinning
|
||||||
|
|
||||||
|
Pin content based on access frequency:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore',
|
||||||
|
pinning: {
|
||||||
|
strategy: 'popularity',
|
||||||
|
factor: 2,
|
||||||
|
ttl: 3600000 // 1 hour
|
||||||
|
}
|
||||||
|
})
|
||||||
|
class PopularContent extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Tiered Pinning
|
||||||
|
|
||||||
|
Use multiple tiers for different pin priorities:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore',
|
||||||
|
pinning: {
|
||||||
|
strategy: 'tiered',
|
||||||
|
maxPins: 500,
|
||||||
|
factor: 1.5
|
||||||
|
}
|
||||||
|
})
|
||||||
|
class TieredData extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Pinning Configuration
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface PinningConfig {
|
||||||
|
strategy: 'fixed' | 'popularity' | 'tiered';
|
||||||
|
factor?: number;
|
||||||
|
maxPins?: number;
|
||||||
|
ttl?: number;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Framework-level Configuration
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const framework = new DebrosFramework({
|
||||||
|
automaticPinning: {
|
||||||
|
enabled: true,
|
||||||
|
strategy: 'popularity',
|
||||||
|
maxPins: 1000
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benefits
|
||||||
|
|
||||||
|
1. **Improved Performance** - Faster access to frequently used data
|
||||||
|
2. **Better Availability** - Reduced risk of data unavailability
|
||||||
|
3. **Automatic Management** - No manual intervention required
|
||||||
|
4. **Scalable** - Adapts to usage patterns
|
||||||
|
|
||||||
|
## Related Topics
|
||||||
|
|
||||||
|
- [Database Management](../core-concepts/database-management) - Database handling
|
||||||
|
- [Performance Optimization](./performance) - General performance tips
|
93
docs/docs/advanced/migrations.md
Normal file
93
docs/docs/advanced/migrations.md
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
# Migrations
|
||||||
|
|
||||||
|
Migrations provide a way to evolve your database schema over time while preserving data integrity.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
DebrosFramework includes a migration system that allows you to:
|
||||||
|
|
||||||
|
- Add, remove, or modify fields
|
||||||
|
- Transform existing data
|
||||||
|
- Handle schema evolution
|
||||||
|
- Maintain data integrity
|
||||||
|
|
||||||
|
## Creating Migrations
|
||||||
|
|
||||||
|
### Basic Migration
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const migration = createMigration('add_user_bio', '1.1.0')
|
||||||
|
.addField('User', 'bio', { type: 'string', required: false })
|
||||||
|
.addField('User', 'profilePicture', { type: 'string', required: false });
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Transformation
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const migration = createMigration('update_user_display_name', '1.2.0')
|
||||||
|
.transformData('User', (user) => ({
|
||||||
|
...user,
|
||||||
|
displayName: user.displayName || user.username
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
### Field Modifications
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const migration = createMigration('modify_user_email', '1.3.0')
|
||||||
|
.modifyField('User', 'email', { type: 'string', required: true, unique: true })
|
||||||
|
.addValidator('email_format', async (context) => {
|
||||||
|
// Custom validation logic
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running Migrations
|
||||||
|
|
||||||
|
### Manual Execution
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const migrationManager = new MigrationManager(databaseManager, configManager);
|
||||||
|
await migrationManager.runMigration(migration);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Automatic Execution
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const framework = new DebrosFramework({
|
||||||
|
migrations: {
|
||||||
|
autoRun: true,
|
||||||
|
directory: './migrations'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Migration Types
|
||||||
|
|
||||||
|
### Schema Changes
|
||||||
|
|
||||||
|
- Add fields
|
||||||
|
- Remove fields
|
||||||
|
- Modify field types
|
||||||
|
- Add indexes
|
||||||
|
|
||||||
|
### Data Transformations
|
||||||
|
|
||||||
|
- Update existing records
|
||||||
|
- Migrate data formats
|
||||||
|
- Clean up invalid data
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Test migrations** thoroughly before production
|
||||||
|
2. **Backup data** before running migrations
|
||||||
|
3. **Use transactions** where possible
|
||||||
|
4. **Plan rollback strategies**
|
||||||
|
|
||||||
|
## Related Classes
|
||||||
|
|
||||||
|
- [`MigrationManager`](../api/migration-manager) - Migration execution
|
||||||
|
- [`MigrationBuilder`](../api/migration-builder) - Migration creation
|
187
docs/docs/advanced/performance.md
Normal file
187
docs/docs/advanced/performance.md
Normal file
@ -0,0 +1,187 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
# Performance Optimization
|
||||||
|
|
||||||
|
This guide covers performance optimization techniques for DebrosFramework applications.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
DebrosFramework includes several built-in performance features and provides guidelines for writing efficient applications.
|
||||||
|
|
||||||
|
## Built-in Performance Features
|
||||||
|
|
||||||
|
### Query Optimization
|
||||||
|
|
||||||
|
DebrosFramework automatically optimizes queries:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Automatic query optimization
|
||||||
|
const posts = await Post.query()
|
||||||
|
.where('userId', userId)
|
||||||
|
.with(['user'])
|
||||||
|
.orderBy('createdAt', 'desc')
|
||||||
|
.limit(50)
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Caching
|
||||||
|
|
||||||
|
Enable caching for frequently accessed data:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Cache query results for 5 minutes
|
||||||
|
const cachedPosts = await Post.query()
|
||||||
|
.where('isPublished', true)
|
||||||
|
.cache(300)
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// Framework-level caching
|
||||||
|
const framework = new DebrosFramework({
|
||||||
|
cache: {
|
||||||
|
enabled: true,
|
||||||
|
maxSize: 1000,
|
||||||
|
ttl: 300000
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connection Pooling
|
||||||
|
|
||||||
|
Database connections are automatically pooled:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Connection pooling is handled automatically
|
||||||
|
const db = await databaseManager.getDatabaseForModel(User);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Best Practices
|
||||||
|
|
||||||
|
### Query Optimization
|
||||||
|
|
||||||
|
1. **Use indexes** - Ensure commonly queried fields are indexed
|
||||||
|
2. **Limit results** - Use `limit()` to avoid loading unnecessary data
|
||||||
|
3. **Use eager loading** - Load relationships efficiently with `with()`
|
||||||
|
4. **Avoid N+1 queries** - Load related data in batches
|
||||||
|
|
||||||
|
### Memory Management
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Proper resource cleanup
|
||||||
|
try {
|
||||||
|
const results = await someQuery();
|
||||||
|
// Process results
|
||||||
|
} finally {
|
||||||
|
await cleanup();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Batch Operations
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Batch multiple operations
|
||||||
|
const users = await Promise.all([
|
||||||
|
User.findById('user1'),
|
||||||
|
User.findById('user2'),
|
||||||
|
User.findById('user3')
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitoring Performance
|
||||||
|
|
||||||
|
### Metrics Collection
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Enable performance monitoring
|
||||||
|
const framework = new DebrosFramework({
|
||||||
|
monitoring: {
|
||||||
|
enabled: true,
|
||||||
|
logLevel: 'info',
|
||||||
|
enableMetrics: true
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Query Analysis
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Analyze query performance
|
||||||
|
const queryMetrics = await framework.getQueryMetrics();
|
||||||
|
console.log('Average query time:', queryMetrics.averageQueryTime);
|
||||||
|
console.log('Slow queries:', queryMetrics.slowQueries);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Advanced Optimization
|
||||||
|
|
||||||
|
### Sharding
|
||||||
|
|
||||||
|
Use sharding for large datasets:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore',
|
||||||
|
sharding: {
|
||||||
|
strategy: 'hash',
|
||||||
|
count: 8,
|
||||||
|
key: 'userId'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
class LargeDataset extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Automatic Pinning
|
||||||
|
|
||||||
|
Enable automatic pinning for frequently accessed data:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore',
|
||||||
|
pinning: {
|
||||||
|
strategy: 'popularity',
|
||||||
|
factor: 2
|
||||||
|
}
|
||||||
|
})
|
||||||
|
class PopularContent extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Common Performance Issues
|
||||||
|
|
||||||
|
### Large Result Sets
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ Bad - loads all results
|
||||||
|
const allPosts = await Post.query().find();
|
||||||
|
|
||||||
|
// ✅ Good - use pagination
|
||||||
|
const posts = await Post.query()
|
||||||
|
.limit(20)
|
||||||
|
.offset(page * 20)
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Unnecessary Relationship Loading
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// ❌ Bad - loads all relationships
|
||||||
|
const posts = await Post.query()
|
||||||
|
.with(['user', 'comments', 'tags'])
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// ✅ Good - load only needed relationships
|
||||||
|
const posts = await Post.query()
|
||||||
|
.with(['user'])
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Topics
|
||||||
|
|
||||||
|
- [Automatic Pinning](./automatic-pinning) - Data availability optimization
|
||||||
|
- [Database Management](../core-concepts/database-management) - Database handling
|
||||||
|
- [Query System](../query-system/query-builder) - Query construction
|
394
docs/docs/api/database-manager.md
Normal file
394
docs/docs/api/database-manager.md
Normal file
@ -0,0 +1,394 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
# DatabaseManager
|
||||||
|
|
||||||
|
The `DatabaseManager` class is responsible for managing database connections, lifecycle, and operations for both user-scoped and global databases in DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The DatabaseManager provides a unified interface for database operations across different database types and scopes. It handles:
|
||||||
|
|
||||||
|
- Database creation and initialization
|
||||||
|
- Connection management and pooling
|
||||||
|
- User-scoped vs global database routing
|
||||||
|
- Database lifecycle management
|
||||||
|
- Performance optimization and caching
|
||||||
|
|
||||||
|
## Class Definition
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class DatabaseManager {
|
||||||
|
constructor(
|
||||||
|
private orbitDBService: FrameworkOrbitDBService,
|
||||||
|
private shardManager: ShardManager,
|
||||||
|
private configManager: ConfigManager
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Methods
|
||||||
|
|
||||||
|
### Database Creation
|
||||||
|
|
||||||
|
#### `getDatabaseForModel<T>(modelClass, userId?)`
|
||||||
|
|
||||||
|
Gets or creates a database for a specific model.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async getDatabaseForModel<T extends BaseModel>(
|
||||||
|
modelClass: ModelConstructor<T>,
|
||||||
|
userId?: string
|
||||||
|
): Promise<Database>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `modelClass` - The model class to get database for
|
||||||
|
- `userId` - User ID for user-scoped databases
|
||||||
|
|
||||||
|
**Returns:** Promise resolving to the database instance
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
const userDB = await databaseManager.getDatabaseForModel(User, 'user123');
|
||||||
|
const globalDB = await databaseManager.getDatabaseForModel(GlobalConfig);
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `createDatabase(name, type, options)`
|
||||||
|
|
||||||
|
Creates a new database with specified configuration.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async createDatabase(
|
||||||
|
name: string,
|
||||||
|
type: StoreType,
|
||||||
|
options: DatabaseOptions
|
||||||
|
): Promise<Database>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `name` - Database name
|
||||||
|
- `type` - Database type ('docstore', 'eventlog', 'keyvalue', 'counter', 'feed')
|
||||||
|
- `options` - Database configuration options
|
||||||
|
|
||||||
|
### Database Management
|
||||||
|
|
||||||
|
#### `ensureDatabaseExists(name, type)`
|
||||||
|
|
||||||
|
Ensures a database exists, creating it if necessary.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async ensureDatabaseExists(
|
||||||
|
name: string,
|
||||||
|
type: StoreType
|
||||||
|
): Promise<Database>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `closeDatabaseForModel(modelClass, userId?)`
|
||||||
|
|
||||||
|
Closes a database for a specific model.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async closeDatabaseForModel<T extends BaseModel>(
|
||||||
|
modelClass: ModelConstructor<T>,
|
||||||
|
userId?: string
|
||||||
|
): Promise<void>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `closeAllDatabases()`
|
||||||
|
|
||||||
|
Closes all open databases.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async closeAllDatabases(): Promise<void>
|
||||||
|
```
|
||||||
|
|
||||||
|
### User Management
|
||||||
|
|
||||||
|
#### `createUserDatabase(userId, modelClass)`
|
||||||
|
|
||||||
|
Creates a user-specific database.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async createUserDatabase<T extends BaseModel>(
|
||||||
|
userId: string,
|
||||||
|
modelClass: ModelConstructor<T>
|
||||||
|
): Promise<Database>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `getUserDatabases(userId)`
|
||||||
|
|
||||||
|
Gets all databases for a specific user.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async getUserDatabases(userId: string): Promise<Database[]>
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database Types
|
||||||
|
|
||||||
|
### Store Types
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
type StoreType = 'docstore' | 'eventlog' | 'keyvalue' | 'counter' | 'feed';
|
||||||
|
```
|
||||||
|
|
||||||
|
- **docstore** - Document-based storage for structured data
|
||||||
|
- **eventlog** - Append-only log for events and transactions
|
||||||
|
- **keyvalue** - Key-value storage for simple data
|
||||||
|
- **counter** - Conflict-free replicated counters
|
||||||
|
- **feed** - Sequential feed of items
|
||||||
|
|
||||||
|
### Database Options
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface DatabaseOptions {
|
||||||
|
scope: 'user' | 'global';
|
||||||
|
sharding?: ShardingConfig;
|
||||||
|
replication?: ReplicationConfig;
|
||||||
|
indexing?: IndexingConfig;
|
||||||
|
caching?: CachingConfig;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Database Scoping
|
||||||
|
|
||||||
|
### User-Scoped Databases
|
||||||
|
|
||||||
|
User-scoped databases are isolated per user:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// User-scoped model
|
||||||
|
@Model({
|
||||||
|
scope: 'user',
|
||||||
|
type: 'docstore'
|
||||||
|
})
|
||||||
|
class UserPost extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
|
||||||
|
// Each user gets their own database
|
||||||
|
const aliceDB = await databaseManager.getDatabaseForModel(UserPost, 'alice');
|
||||||
|
const bobDB = await databaseManager.getDatabaseForModel(UserPost, 'bob');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Global Databases
|
||||||
|
|
||||||
|
Global databases are shared across all users:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Global model
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore'
|
||||||
|
})
|
||||||
|
class GlobalConfig extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
|
||||||
|
// Single shared database
|
||||||
|
const globalDB = await databaseManager.getDatabaseForModel(GlobalConfig);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Sharding Integration
|
||||||
|
|
||||||
|
The DatabaseManager integrates with the ShardManager for data distribution:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Sharded model
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore',
|
||||||
|
sharding: {
|
||||||
|
strategy: 'hash',
|
||||||
|
count: 4,
|
||||||
|
key: 'id'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
class ShardedModel extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
|
||||||
|
// DatabaseManager automatically routes to correct shard
|
||||||
|
const database = await databaseManager.getDatabaseForModel(ShardedModel);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Features
|
||||||
|
|
||||||
|
### Connection Pooling
|
||||||
|
|
||||||
|
The DatabaseManager maintains a pool of database connections:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Connection pool configuration
|
||||||
|
const poolConfig = {
|
||||||
|
maxConnections: 50,
|
||||||
|
idleTimeout: 30000,
|
||||||
|
connectionTimeout: 5000
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
### Caching
|
||||||
|
|
||||||
|
Database instances are cached for performance:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Cached database access
|
||||||
|
const db1 = await databaseManager.getDatabaseForModel(User, 'user123');
|
||||||
|
const db2 = await databaseManager.getDatabaseForModel(User, 'user123');
|
||||||
|
// db1 and db2 are the same instance
|
||||||
|
```
|
||||||
|
|
||||||
|
## Error Handling
|
||||||
|
|
||||||
|
### Database Errors
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Database creation error
|
||||||
|
try {
|
||||||
|
const db = await databaseManager.getDatabaseForModel(User, 'user123');
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof DatabaseCreationError) {
|
||||||
|
console.error('Failed to create database:', error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Connection Errors
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Connection error handling
|
||||||
|
try {
|
||||||
|
await databaseManager.ensureDatabaseExists('test', 'docstore');
|
||||||
|
} catch (error) {
|
||||||
|
if (error instanceof DatabaseConnectionError) {
|
||||||
|
console.error('Database connection failed:', error.message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Database Configuration
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface DatabaseConfig {
|
||||||
|
maxDatabases: number;
|
||||||
|
defaultType: StoreType;
|
||||||
|
caching: {
|
||||||
|
enabled: boolean;
|
||||||
|
maxSize: number;
|
||||||
|
ttl: number;
|
||||||
|
};
|
||||||
|
sharding: {
|
||||||
|
defaultStrategy: ShardingStrategy;
|
||||||
|
defaultCount: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Environment Configuration
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Configure database behavior
|
||||||
|
const databaseManager = new DatabaseManager(
|
||||||
|
orbitDBService,
|
||||||
|
shardManager,
|
||||||
|
configManager
|
||||||
|
);
|
||||||
|
|
||||||
|
// Set configuration
|
||||||
|
await configManager.set('database', {
|
||||||
|
maxDatabases: 100,
|
||||||
|
defaultType: 'docstore',
|
||||||
|
caching: {
|
||||||
|
enabled: true,
|
||||||
|
maxSize: 1000,
|
||||||
|
ttl: 300000
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Monitoring
|
||||||
|
|
||||||
|
### Database Metrics
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Get database metrics
|
||||||
|
const metrics = await databaseManager.getMetrics();
|
||||||
|
|
||||||
|
console.log('Database Statistics:', {
|
||||||
|
totalDatabases: metrics.totalDatabases,
|
||||||
|
userDatabases: metrics.userDatabases,
|
||||||
|
globalDatabases: metrics.globalDatabases,
|
||||||
|
memoryUsage: metrics.memoryUsage
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Monitoring
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Monitor database performance
|
||||||
|
databaseManager.on('databaseCreated', (event) => {
|
||||||
|
console.log('Database created:', event.name, event.type);
|
||||||
|
});
|
||||||
|
|
||||||
|
databaseManager.on('databaseClosed', (event) => {
|
||||||
|
console.log('Database closed:', event.name);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
### Resource Management
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Always close databases when done
|
||||||
|
try {
|
||||||
|
const db = await databaseManager.getDatabaseForModel(User, 'user123');
|
||||||
|
// Use database
|
||||||
|
} finally {
|
||||||
|
await databaseManager.closeDatabaseForModel(User, 'user123');
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Proper error handling
|
||||||
|
async function safelyGetDatabase<T extends BaseModel>(
|
||||||
|
modelClass: ModelConstructor<T>,
|
||||||
|
userId?: string
|
||||||
|
): Promise<Database | null> {
|
||||||
|
try {
|
||||||
|
return await databaseManager.getDatabaseForModel(modelClass, userId);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Database access failed:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Performance Optimization
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Batch database operations
|
||||||
|
const databases = await Promise.all([
|
||||||
|
databaseManager.getDatabaseForModel(User, 'user1'),
|
||||||
|
databaseManager.getDatabaseForModel(User, 'user2'),
|
||||||
|
databaseManager.getDatabaseForModel(User, 'user3')
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Classes
|
||||||
|
|
||||||
|
- [`ShardManager`](./shard-manager) - Data sharding and distribution
|
||||||
|
- [`DebrosFramework`](./debros-framework) - Main framework class
|
||||||
|
- [`BaseModel`](./base-model) - Base model class
|
||||||
|
- [`QueryExecutor`](./query-executor) - Query execution
|
||||||
|
|
||||||
|
## See Also
|
||||||
|
|
||||||
|
- [Database Management Guide](../core-concepts/database-management)
|
||||||
|
- [Architecture Overview](../core-concepts/architecture)
|
||||||
|
- [Performance Optimization](../advanced/performance)
|
214
docs/docs/api/decorators/field.md
Normal file
214
docs/docs/api/decorators/field.md
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
# @Field Decorator
|
||||||
|
|
||||||
|
The `@Field` decorator is used to define field properties and validation rules in DebrosFramework models.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The `@Field` decorator configures how a model property should be handled, including type validation, required status, default values, and custom validation functions.
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Field(config: FieldConfig)
|
||||||
|
propertyName: PropertyType;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### FieldConfig Interface
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface FieldConfig {
|
||||||
|
type: FieldType;
|
||||||
|
required?: boolean;
|
||||||
|
unique?: boolean;
|
||||||
|
default?: any | (() => any);
|
||||||
|
validate?: (value: any) => boolean;
|
||||||
|
transform?: (value: any) => any;
|
||||||
|
serialize?: boolean;
|
||||||
|
index?: boolean;
|
||||||
|
virtual?: boolean;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Field Types
|
||||||
|
|
||||||
|
### Supported Types
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
type FieldType = 'string' | 'number' | 'boolean' | 'array' | 'object' | 'date';
|
||||||
|
```
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
username: string;
|
||||||
|
|
||||||
|
@Field({ type: 'number', required: false, default: 0 })
|
||||||
|
score: number;
|
||||||
|
|
||||||
|
@Field({ type: 'boolean', default: true })
|
||||||
|
isActive: boolean;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Properties
|
||||||
|
|
||||||
|
### type (required)
|
||||||
|
|
||||||
|
Specifies the data type of the field.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Field({ type: 'string' })
|
||||||
|
name: string;
|
||||||
|
|
||||||
|
@Field({ type: 'number' })
|
||||||
|
age: number;
|
||||||
|
|
||||||
|
@Field({ type: 'boolean' })
|
||||||
|
isActive: boolean;
|
||||||
|
|
||||||
|
@Field({ type: 'array' })
|
||||||
|
tags: string[];
|
||||||
|
|
||||||
|
@Field({ type: 'object' })
|
||||||
|
metadata: Record<string, any>;
|
||||||
|
```
|
||||||
|
|
||||||
|
### required (optional)
|
||||||
|
|
||||||
|
Indicates whether the field is required.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
email: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: false })
|
||||||
|
bio?: string;
|
||||||
|
```
|
||||||
|
|
||||||
|
### unique (optional)
|
||||||
|
|
||||||
|
Ensures field values are unique across all records.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Field({ type: 'string', required: true, unique: true })
|
||||||
|
email: string;
|
||||||
|
```
|
||||||
|
|
||||||
|
### default (optional)
|
||||||
|
|
||||||
|
Sets a default value for the field.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Static default
|
||||||
|
@Field({ type: 'boolean', default: true })
|
||||||
|
isActive: boolean;
|
||||||
|
|
||||||
|
// Dynamic default
|
||||||
|
@Field({ type: 'number', default: () => Date.now() })
|
||||||
|
createdAt: number;
|
||||||
|
```
|
||||||
|
|
||||||
|
### validate (optional)
|
||||||
|
|
||||||
|
Custom validation function for the field.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Field({
|
||||||
|
type: 'string',
|
||||||
|
validate: (value: string) => value.length >= 3 && value.length <= 20
|
||||||
|
})
|
||||||
|
username: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
type: 'string',
|
||||||
|
validate: (email: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
|
||||||
|
})
|
||||||
|
email: string;
|
||||||
|
```
|
||||||
|
|
||||||
|
### transform (optional)
|
||||||
|
|
||||||
|
Transforms the value before storing.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Field({
|
||||||
|
type: 'string',
|
||||||
|
transform: (value: string) => value.toLowerCase().trim()
|
||||||
|
})
|
||||||
|
username: string;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### Basic Field Configuration
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true, unique: true })
|
||||||
|
username: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
unique: true,
|
||||||
|
validate: (email: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
|
||||||
|
})
|
||||||
|
email: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: false })
|
||||||
|
bio?: string;
|
||||||
|
|
||||||
|
@Field({ type: 'boolean', default: true })
|
||||||
|
isActive: boolean;
|
||||||
|
|
||||||
|
@Field({ type: 'number', default: () => Date.now() })
|
||||||
|
createdAt: number;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Complex Field Validation
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class Post extends BaseModel {
|
||||||
|
@Field({
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
validate: (title: string) => title.length >= 3 && title.length <= 100
|
||||||
|
})
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
validate: (content: string) => content.length <= 5000
|
||||||
|
})
|
||||||
|
content: string;
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
type: 'array',
|
||||||
|
default: [],
|
||||||
|
validate: (tags: string[]) => tags.length <= 10
|
||||||
|
})
|
||||||
|
tags: string[];
|
||||||
|
|
||||||
|
@Field({
|
||||||
|
type: 'string',
|
||||||
|
transform: (slug: string) => slug.toLowerCase().replace(/\s+/g, '-')
|
||||||
|
})
|
||||||
|
slug: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Decorators
|
||||||
|
|
||||||
|
- [`@Model`](./model) - Model configuration
|
||||||
|
- [`@BelongsTo`](./relationships#belongsto) - Relationship decorators
|
||||||
|
- [`@HasMany`](./relationships#hasmany) - Relationship decorators
|
229
docs/docs/api/decorators/hooks.md
Normal file
229
docs/docs/api/decorators/hooks.md
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
# Hook Decorators
|
||||||
|
|
||||||
|
DebrosFramework provides hook decorators for defining lifecycle methods that are called at specific points during model operations.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Hook decorators allow you to define methods that are automatically called before or after specific model operations like create, update, delete, and save.
|
||||||
|
|
||||||
|
## Hook Types
|
||||||
|
|
||||||
|
### @BeforeCreate {#beforecreate}
|
||||||
|
|
||||||
|
Called before a model instance is created.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@BeforeCreate
|
||||||
|
async beforeCreate(): Promise<void> {
|
||||||
|
// Pre-creation logic
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
username: string;
|
||||||
|
|
||||||
|
@BeforeCreate
|
||||||
|
async beforeCreate(): Promise<void> {
|
||||||
|
this.username = this.username.toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### @AfterCreate {#aftercreate}
|
||||||
|
|
||||||
|
Called after a model instance is created.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@AfterCreate
|
||||||
|
async afterCreate(): Promise<void> {
|
||||||
|
// Post-creation logic
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@AfterCreate
|
||||||
|
async afterCreate(): Promise<void> {
|
||||||
|
console.log(`User ${this.username} created successfully`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### @BeforeUpdate {#beforeupdate}
|
||||||
|
|
||||||
|
Called before a model instance is updated.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@BeforeUpdate
|
||||||
|
async beforeUpdate(): Promise<void> {
|
||||||
|
// Pre-update logic
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
class Post extends BaseModel {
|
||||||
|
@Field({ type: 'number' })
|
||||||
|
updatedAt: number;
|
||||||
|
|
||||||
|
@BeforeUpdate
|
||||||
|
async beforeUpdate(): Promise<void> {
|
||||||
|
this.updatedAt = Date.now();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### @AfterUpdate {#afterupdate}
|
||||||
|
|
||||||
|
Called after a model instance is updated.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@AfterUpdate
|
||||||
|
async afterUpdate(): Promise<void> {
|
||||||
|
// Post-update logic
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### @BeforeDelete {#beforedelete}
|
||||||
|
|
||||||
|
Called before a model instance is deleted.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@BeforeDelete
|
||||||
|
async beforeDelete(): Promise<void> {
|
||||||
|
// Pre-deletion logic
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@BeforeDelete
|
||||||
|
async beforeDelete(): Promise<void> {
|
||||||
|
// Clean up related data
|
||||||
|
await Post.query().where('userId', this.id).delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### @AfterDelete {#afterdelete}
|
||||||
|
|
||||||
|
Called after a model instance is deleted.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@AfterDelete
|
||||||
|
async afterDelete(): Promise<void> {
|
||||||
|
// Post-deletion logic
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### @BeforeSave {#beforesave}
|
||||||
|
|
||||||
|
Called before a model instance is saved (create or update).
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@BeforeSave
|
||||||
|
async beforeSave(): Promise<void> {
|
||||||
|
// Pre-save logic
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
class Post extends BaseModel {
|
||||||
|
@Field({ type: 'string' })
|
||||||
|
slug: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string' })
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@BeforeSave
|
||||||
|
async beforeSave(): Promise<void> {
|
||||||
|
if (!this.slug) {
|
||||||
|
this.slug = this.title.toLowerCase().replace(/\s+/g, '-');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### @AfterSave {#aftersave}
|
||||||
|
|
||||||
|
Called after a model instance is saved (create or update).
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@AfterSave
|
||||||
|
async afterSave(): Promise<void> {
|
||||||
|
// Post-save logic
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Complete User Model with Hooks
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
username: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
email: string;
|
||||||
|
|
||||||
|
@Field({ type: 'number' })
|
||||||
|
createdAt: number;
|
||||||
|
|
||||||
|
@Field({ type: 'number' })
|
||||||
|
updatedAt: number;
|
||||||
|
|
||||||
|
@BeforeCreate
|
||||||
|
async beforeCreate(): Promise<void> {
|
||||||
|
this.username = this.username.toLowerCase().trim();
|
||||||
|
this.email = this.email.toLowerCase().trim();
|
||||||
|
this.createdAt = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeUpdate
|
||||||
|
async beforeUpdate(): Promise<void> {
|
||||||
|
this.updatedAt = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeSave
|
||||||
|
async beforeSave(): Promise<void> {
|
||||||
|
// Validate email format
|
||||||
|
if (!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(this.email)) {
|
||||||
|
throw new Error('Invalid email format');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterSave
|
||||||
|
async afterSave(): Promise<void> {
|
||||||
|
console.log(`User ${this.username} saved at ${new Date()}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
@BeforeDelete
|
||||||
|
async beforeDelete(): Promise<void> {
|
||||||
|
// Clean up related data
|
||||||
|
await Post.query().where('userId', this.id).delete();
|
||||||
|
await Comment.query().where('userId', this.id).delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
@AfterDelete
|
||||||
|
async afterDelete(): Promise<void> {
|
||||||
|
console.log(`User ${this.username} and related data deleted`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Classes
|
||||||
|
|
||||||
|
- [`BaseModel`](../base-model) - Base model class
|
||||||
|
- [`@Model`](./model) - Model configuration
|
||||||
|
- [`@Field`](./field) - Field configuration
|
130
docs/docs/api/decorators/model.md
Normal file
130
docs/docs/api/decorators/model.md
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
# @Model Decorator
|
||||||
|
|
||||||
|
The `@Model` decorator is used to define model configuration and metadata in DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The `@Model` decorator configures how a model class should be handled by the framework, including database scope, store type, sharding configuration, and other model-specific options.
|
||||||
|
|
||||||
|
## Syntax
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model(config: ModelConfig)
|
||||||
|
class ModelName extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Options
|
||||||
|
|
||||||
|
### ModelConfig Interface
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface ModelConfig {
|
||||||
|
scope: 'user' | 'global';
|
||||||
|
type: StoreType;
|
||||||
|
sharding?: ShardingConfig;
|
||||||
|
pinning?: PinningConfig;
|
||||||
|
pubsub?: PubSubConfig;
|
||||||
|
validation?: ValidationConfig;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Basic Usage
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore'
|
||||||
|
})
|
||||||
|
class User extends BaseModel {
|
||||||
|
// Model properties
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration Properties
|
||||||
|
|
||||||
|
### scope
|
||||||
|
|
||||||
|
Determines the database scope for the model.
|
||||||
|
|
||||||
|
- `'user'` - Each user gets their own database instance
|
||||||
|
- `'global'` - Single shared database for all users
|
||||||
|
|
||||||
|
### type
|
||||||
|
|
||||||
|
Specifies the OrbitDB store type.
|
||||||
|
|
||||||
|
- `'docstore'` - Document-based storage
|
||||||
|
- `'eventlog'` - Append-only event log
|
||||||
|
- `'keyvalue'` - Key-value storage
|
||||||
|
- `'counter'` - Counter storage
|
||||||
|
- `'feed'` - Feed storage
|
||||||
|
|
||||||
|
### sharding (optional)
|
||||||
|
|
||||||
|
Configures data sharding for the model.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore',
|
||||||
|
sharding: {
|
||||||
|
strategy: 'hash',
|
||||||
|
count: 4,
|
||||||
|
key: 'id'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
class ShardedModel extends BaseModel {
|
||||||
|
// Model definition
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
### User-Scoped Model
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'user',
|
||||||
|
type: 'docstore'
|
||||||
|
})
|
||||||
|
class UserPost extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Global Model with Sharding
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore',
|
||||||
|
sharding: {
|
||||||
|
strategy: 'hash',
|
||||||
|
count: 8,
|
||||||
|
key: 'userId'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
class GlobalPost extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
userId: string;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Decorators
|
||||||
|
|
||||||
|
- [`@Field`](./field) - Field configuration
|
||||||
|
- [`@BelongsTo`](./relationships#belongsto) - Relationship decorators
|
||||||
|
- [`@HasMany`](./relationships#hasmany) - Relationship decorators
|
133
docs/docs/api/decorators/relationships.md
Normal file
133
docs/docs/api/decorators/relationships.md
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
# Relationship Decorators
|
||||||
|
|
||||||
|
DebrosFramework provides decorators for defining relationships between models.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Relationship decorators define how models are connected to each other. They support various relationship types including one-to-one, one-to-many, and many-to-many relationships.
|
||||||
|
|
||||||
|
## Relationship Types
|
||||||
|
|
||||||
|
### @BelongsTo {#belongsto}
|
||||||
|
|
||||||
|
Defines a many-to-one relationship.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@BelongsTo(relatedModel: () => ModelClass, foreignKey: string)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
class Post extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'userId')
|
||||||
|
user: User;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### @HasMany {#hasmany}
|
||||||
|
|
||||||
|
Defines a one-to-many relationship.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@HasMany(relatedModel: () => ModelClass, foreignKey: string)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@HasMany(() => Post, 'userId')
|
||||||
|
posts: Post[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### @HasOne {#hasone}
|
||||||
|
|
||||||
|
Defines a one-to-one relationship.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@HasOne(relatedModel: () => ModelClass, foreignKey: string)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@HasOne(() => UserProfile, 'userId')
|
||||||
|
profile: UserProfile;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### @ManyToMany {#manytomany}
|
||||||
|
|
||||||
|
Defines a many-to-many relationship.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@ManyToMany(relatedModel: () => ModelClass, through: string)
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@ManyToMany(() => Role, 'user_roles')
|
||||||
|
roles: Role[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Blog System
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
username: string;
|
||||||
|
|
||||||
|
@HasMany(() => Post, 'userId')
|
||||||
|
posts: Post[];
|
||||||
|
|
||||||
|
@HasMany(() => Comment, 'userId')
|
||||||
|
comments: Comment[];
|
||||||
|
}
|
||||||
|
|
||||||
|
class Post extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'userId')
|
||||||
|
user: User;
|
||||||
|
|
||||||
|
@HasMany(() => Comment, 'postId')
|
||||||
|
comments: Comment[];
|
||||||
|
}
|
||||||
|
|
||||||
|
class Comment extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
content: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
postId: string;
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'userId')
|
||||||
|
user: User;
|
||||||
|
|
||||||
|
@BelongsTo(() => Post, 'postId')
|
||||||
|
post: Post;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Classes
|
||||||
|
|
||||||
|
- [`BaseModel`](../base-model) - Base model class
|
||||||
|
- [`RelationshipManager`](../relationship-manager) - Relationship management
|
68
docs/docs/api/migration-builder.md
Normal file
68
docs/docs/api/migration-builder.md
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 8
|
||||||
|
---
|
||||||
|
|
||||||
|
# MigrationBuilder
|
||||||
|
|
||||||
|
The `MigrationBuilder` provides a fluent API for creating database migrations in DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The MigrationBuilder allows you to define schema changes, data transformations, and migration operations using a fluent, chainable API.
|
||||||
|
|
||||||
|
## Class Definition
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class MigrationBuilder {
|
||||||
|
constructor(
|
||||||
|
private id: string,
|
||||||
|
private version: string,
|
||||||
|
private name: string
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Methods
|
||||||
|
|
||||||
|
### Field Operations
|
||||||
|
|
||||||
|
#### `addField(modelName, fieldName, config)`
|
||||||
|
|
||||||
|
Adds a new field to a model.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
addField(
|
||||||
|
modelName: string,
|
||||||
|
fieldName: string,
|
||||||
|
config: FieldConfig
|
||||||
|
): MigrationBuilder
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `modelName` - Name of the model
|
||||||
|
- `fieldName` - Name of the field to add
|
||||||
|
- `config` - Field configuration
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
const migration = createMigration('add_user_bio', '1.1.0')
|
||||||
|
.addField('User', 'bio', { type: 'string', required: false });
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Transformations
|
||||||
|
|
||||||
|
#### `transformData(modelName, transformer)`
|
||||||
|
|
||||||
|
Transforms existing data during migration.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
transformData(
|
||||||
|
modelName: string,
|
||||||
|
transformer: (data: any) => any
|
||||||
|
): MigrationBuilder
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Classes
|
||||||
|
|
||||||
|
- [`MigrationManager`](./migration-manager) - Migration execution
|
||||||
|
- [`DatabaseManager`](./database-manager) - Database management
|
59
docs/docs/api/migration-manager.md
Normal file
59
docs/docs/api/migration-manager.md
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 7
|
||||||
|
---
|
||||||
|
|
||||||
|
# MigrationManager
|
||||||
|
|
||||||
|
The `MigrationManager` handles database schema migrations and data transformations in DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The MigrationManager provides tools for evolving database schemas over time, handling version control, and performing data transformations during migrations.
|
||||||
|
|
||||||
|
## Class Definition
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class MigrationManager {
|
||||||
|
constructor(
|
||||||
|
private databaseManager: DatabaseManager,
|
||||||
|
private configManager: ConfigManager
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Methods
|
||||||
|
|
||||||
|
### Migration Management
|
||||||
|
|
||||||
|
#### `runMigration(migration)`
|
||||||
|
|
||||||
|
Executes a migration.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async runMigration(migration: Migration): Promise<void>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `migration` - The migration to execute
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
await migrationManager.runMigration(addUserProfileMigration);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Migration History
|
||||||
|
|
||||||
|
#### `getPendingMigrations()`
|
||||||
|
|
||||||
|
Gets all pending migrations.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async getPendingMigrations(): Promise<Migration[]>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Returns:** Promise resolving to array of pending migrations
|
||||||
|
|
||||||
|
## Related Classes
|
||||||
|
|
||||||
|
- [`MigrationBuilder`](./migration-builder) - Migration construction
|
||||||
|
- [`DatabaseManager`](./database-manager) - Database management
|
53
docs/docs/api/query-executor.md
Normal file
53
docs/docs/api/query-executor.md
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
# QueryExecutor
|
||||||
|
|
||||||
|
The `QueryExecutor` is responsible for executing queries across databases and shards in DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The QueryExecutor handles query execution, optimization, and result aggregation. It provides caching and performance monitoring capabilities.
|
||||||
|
|
||||||
|
## Class Definition
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class QueryExecutor {
|
||||||
|
constructor(
|
||||||
|
private databaseManager: DatabaseManager,
|
||||||
|
private shardManager: ShardManager,
|
||||||
|
private queryCache: QueryCache
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Methods
|
||||||
|
|
||||||
|
### Query Execution
|
||||||
|
|
||||||
|
#### `executeQuery<T>(query)`
|
||||||
|
|
||||||
|
Executes a query and returns results.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async executeQuery<T>(query: QueryBuilder<T>): Promise<QueryResult<T>>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `query` - The query to execute
|
||||||
|
|
||||||
|
**Returns:** Promise resolving to query results
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
const results = await queryExecutor.executeQuery(
|
||||||
|
User.query().where('isActive', true)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Classes
|
||||||
|
|
||||||
|
- [`QueryBuilder`](./query-builder) - Query construction
|
||||||
|
- [`DatabaseManager`](./database-manager) - Database management
|
||||||
|
- [`ShardManager`](./shard-manager) - Data sharding
|
54
docs/docs/api/relationship-manager.md
Normal file
54
docs/docs/api/relationship-manager.md
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
# RelationshipManager
|
||||||
|
|
||||||
|
The `RelationshipManager` handles model relationships and data loading in DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The RelationshipManager manages relationships between models, handles lazy and eager loading, and provides relationship caching for performance optimization.
|
||||||
|
|
||||||
|
## Class Definition
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class RelationshipManager {
|
||||||
|
constructor(
|
||||||
|
private databaseManager: DatabaseManager,
|
||||||
|
private queryExecutor: QueryExecutor
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Methods
|
||||||
|
|
||||||
|
### Relationship Loading
|
||||||
|
|
||||||
|
#### `loadRelationship<T>(model, relationship)`
|
||||||
|
|
||||||
|
Loads a relationship for a model instance.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async loadRelationship<T>(
|
||||||
|
model: BaseModel,
|
||||||
|
relationship: string
|
||||||
|
): Promise<T | T[]>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `model` - The model instance
|
||||||
|
- `relationship` - The relationship name to load
|
||||||
|
|
||||||
|
**Returns:** Promise resolving to related model(s)
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
const user = await User.findById('user123');
|
||||||
|
const posts = await relationshipManager.loadRelationship(user, 'posts');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Classes
|
||||||
|
|
||||||
|
- [`BaseModel`](./base-model) - Base model class
|
||||||
|
- [`QueryExecutor`](./query-executor) - Query execution
|
58
docs/docs/api/shard-manager.md
Normal file
58
docs/docs/api/shard-manager.md
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 4
|
||||||
|
---
|
||||||
|
|
||||||
|
# ShardManager
|
||||||
|
|
||||||
|
The `ShardManager` is responsible for managing data sharding and distribution across multiple database instances in DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The ShardManager handles data partitioning and routing to appropriate shards based on configuration and sharding keys. It optimizes query performance and maintains data consistency across shards.
|
||||||
|
|
||||||
|
## Class Definition
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class ShardManager {
|
||||||
|
constructor(
|
||||||
|
private config: ShardConfig
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Core Methods
|
||||||
|
|
||||||
|
### Shard Configuration
|
||||||
|
|
||||||
|
#### `configureSharding(strategy, count, key)`
|
||||||
|
|
||||||
|
Configures sharding strategy.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
configureSharding(
|
||||||
|
strategy: ShardingStrategy,
|
||||||
|
count: number,
|
||||||
|
key: string
|
||||||
|
): void
|
||||||
|
```
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
- `strategy` - One of ('hash', 'range', 'user')
|
||||||
|
- `count` - Number of shards
|
||||||
|
- `key` - Field used for sharding
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
```typescript
|
||||||
|
shardManager.configureSharding('hash', 4, 'id');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Shard Management
|
||||||
|
|
||||||
|
#### `getShardForKey(key)`
|
||||||
|
|
||||||
|
Determines the shard for a given key.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
getShardForKey(key: string): number
|
||||||
|
```
|
||||||
|
|
56
docs/docs/contributing/community.md
Normal file
56
docs/docs/contributing/community.md
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 7
|
||||||
|
---
|
||||||
|
|
||||||
|
# Community
|
||||||
|
|
||||||
|
Welcome to the DebrosFramework community! This page provides information about how to connect with other developers and contributors.
|
||||||
|
|
||||||
|
## Community Channels
|
||||||
|
|
||||||
|
### Git Repository
|
||||||
|
|
||||||
|
- **Repository**: https://git.debros.io/DeBros/network
|
||||||
|
- **Issues**: Report bugs and request features
|
||||||
|
- **Pull Requests**: Submit code contributions
|
||||||
|
|
||||||
|
### Communication
|
||||||
|
|
||||||
|
- **Email**: Contact maintainers directly
|
||||||
|
- **GitHub Discussions**: Technical discussions and Q&A
|
||||||
|
- **Discord** (if available): Real-time chat with the community
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
### Ways to Contribute
|
||||||
|
|
||||||
|
1. **Code Contributions** - Fix bugs, add features
|
||||||
|
2. **Documentation** - Improve guides and examples
|
||||||
|
3. **Testing** - Help with testing and quality assurance
|
||||||
|
4. **Community Support** - Help other developers
|
||||||
|
|
||||||
|
### Getting Started
|
||||||
|
|
||||||
|
1. Read the [Contributing Guide](./overview)
|
||||||
|
2. Set up your [Development Environment](./development-setup)
|
||||||
|
3. Follow our [Code Guidelines](./code-guidelines)
|
||||||
|
4. Check out the [Testing Guide](./testing-guide)
|
||||||
|
|
||||||
|
## Code of Conduct
|
||||||
|
|
||||||
|
We are committed to providing a welcoming and inclusive environment for all contributors. Please be respectful and constructive in all interactions.
|
||||||
|
|
||||||
|
## Recognition
|
||||||
|
|
||||||
|
Contributors are recognized through:
|
||||||
|
- Contributor list in documentation
|
||||||
|
- Release notes credits
|
||||||
|
- Community highlights
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
If you need help:
|
||||||
|
1. Check the documentation
|
||||||
|
2. Search existing issues
|
||||||
|
3. Ask in community channels
|
||||||
|
4. Contact maintainers
|
40
docs/docs/contributing/documentation-guide.md
Normal file
40
docs/docs/contributing/documentation-guide.md
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 5
|
||||||
|
---
|
||||||
|
|
||||||
|
# Documentation Guide
|
||||||
|
|
||||||
|
This guide covers how to contribute to DebrosFramework documentation.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Documentation is crucial for developer experience and adoption. This guide will help you write clear, comprehensive documentation that helps developers succeed with DebrosFramework.
|
||||||
|
|
||||||
|
## Documentation Structure
|
||||||
|
|
||||||
|
### Main Sections
|
||||||
|
|
||||||
|
- **Getting Started** - Initial setup and first steps
|
||||||
|
- **Core Concepts** - Fundamental framework concepts
|
||||||
|
- **API Reference** - Complete API documentation
|
||||||
|
- **Examples** - Practical usage examples
|
||||||
|
- **Contributing** - Guidelines for contributors
|
||||||
|
|
||||||
|
### Writing Style
|
||||||
|
|
||||||
|
- Use clear, concise language
|
||||||
|
- Provide practical examples
|
||||||
|
- Include code samples that work
|
||||||
|
- Use consistent formatting
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Start with the user's perspective** - What are they trying to achieve?
|
||||||
|
2. **Provide complete examples** - Show full working code
|
||||||
|
3. **Explain the why** - Don't just show how, explain why
|
||||||
|
4. **Keep it up to date** - Update docs when code changes
|
||||||
|
|
||||||
|
## Related Resources
|
||||||
|
|
||||||
|
- [Code Guidelines](./code-guidelines) - Coding standards
|
||||||
|
- [Testing Guide](./testing-guide) - Testing practices
|
66
docs/docs/contributing/release-process.md
Normal file
66
docs/docs/contributing/release-process.md
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 6
|
||||||
|
---
|
||||||
|
|
||||||
|
# Release Process
|
||||||
|
|
||||||
|
This document outlines the release process for DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
DebrosFramework follows semantic versioning and has a structured release process to ensure quality and reliability.
|
||||||
|
|
||||||
|
## Version Numbers
|
||||||
|
|
||||||
|
We use semantic versioning (SemVer):
|
||||||
|
- **Major** (X.0.0) - Breaking changes
|
||||||
|
- **Minor** (X.Y.0) - New features, backwards compatible
|
||||||
|
- **Patch** (X.Y.Z) - Bug fixes, backwards compatible
|
||||||
|
|
||||||
|
## Release Types
|
||||||
|
|
||||||
|
### Regular Releases
|
||||||
|
|
||||||
|
Regular releases happen monthly and include:
|
||||||
|
- New features
|
||||||
|
- Bug fixes
|
||||||
|
- Performance improvements
|
||||||
|
- Documentation updates
|
||||||
|
|
||||||
|
### Hotfix Releases
|
||||||
|
|
||||||
|
Hotfix releases address critical issues:
|
||||||
|
- Security vulnerabilities
|
||||||
|
- Major bugs affecting production
|
||||||
|
- Data integrity issues
|
||||||
|
|
||||||
|
## Release Process
|
||||||
|
|
||||||
|
### 1. Preparation
|
||||||
|
|
||||||
|
- Ensure all tests pass
|
||||||
|
- Update documentation
|
||||||
|
- Review breaking changes
|
||||||
|
|
||||||
|
### 2. Version Bump
|
||||||
|
|
||||||
|
- Update version in package.json
|
||||||
|
- Update CHANGELOG.md
|
||||||
|
- Create git tag
|
||||||
|
|
||||||
|
### 3. Deployment
|
||||||
|
|
||||||
|
- Build and test
|
||||||
|
- Publish to npm
|
||||||
|
- Deploy documentation
|
||||||
|
|
||||||
|
## Quality Assurance
|
||||||
|
|
||||||
|
- All releases must pass CI/CD
|
||||||
|
- Manual testing on critical paths
|
||||||
|
- Community feedback integration
|
||||||
|
|
||||||
|
## Related Documents
|
||||||
|
|
||||||
|
- [Code Guidelines](./code-guidelines) - Coding standards
|
||||||
|
- [Testing Guide](./testing-guide) - Testing practices
|
115
docs/docs/contributing/testing-guide.md
Normal file
115
docs/docs/contributing/testing-guide.md
Normal file
@ -0,0 +1,115 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
# Testing Guide
|
||||||
|
|
||||||
|
This document provides guidelines for writing and running tests in DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
DebrosFramework uses Jest as the testing framework for unit tests and a combination of Docker and custom scripts for integration testing.
|
||||||
|
|
||||||
|
## Unit Tests
|
||||||
|
|
||||||
|
### Structure
|
||||||
|
|
||||||
|
Unit tests are located in the `tests/unit/` directory and follow the naming convention `*.test.ts`.
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm run test:unit
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the following command to run specific tests:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx jest tests/unit/path/to/your.test.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
- Ensure comprehensive coverage for all public methods.
|
||||||
|
- Use `describe` blocks to group related tests.
|
||||||
|
- Use `beforeEach` and `afterEach` for setup and teardown logic.
|
||||||
|
|
||||||
|
## Integration Tests
|
||||||
|
|
||||||
|
### Structure
|
||||||
|
|
||||||
|
Integration tests are located in the `tests/real-integration/` directory and simulate real-world scenarios.
|
||||||
|
|
||||||
|
### Running Tests
|
||||||
|
|
||||||
|
Ensure Docker is running before executing:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm run test:real
|
||||||
|
```
|
||||||
|
|
||||||
|
### Best Practices
|
||||||
|
|
||||||
|
- Test real-world use cases that involve multiple components.
|
||||||
|
- Use Docker to simulate network environments and distributed systems.
|
||||||
|
- Validate data consistency and integrity.
|
||||||
|
|
||||||
|
## Writing Tests
|
||||||
|
|
||||||
|
### Unit Test Example
|
||||||
|
|
||||||
|
Here's a simple example of a unit test:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
describe('User Model', () => {
|
||||||
|
it('should create a new user', async () => {
|
||||||
|
const user = await User.create({ username: 'testuser', email: 'test@example.com' });
|
||||||
|
expect(user).toBeDefined();
|
||||||
|
expect(user.username).toBe('testuser');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Integration Test Example
|
||||||
|
|
||||||
|
Here's an example of a simple integration test:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
describe('Blog Scenario Integration', () => {
|
||||||
|
it('should handle complete blog workflow', async () => {
|
||||||
|
const user = await User.create({ username: 'blogger', email: 'blogger@example.com' });
|
||||||
|
const post = await Post.create({ title: 'Test Post', content: 'Test content', userId: user.id });
|
||||||
|
const postWithComments = await Post.query().where('id', post.id).with(['comments']).findOne();
|
||||||
|
|
||||||
|
expect(postWithComments).toBeDefined();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Utilities
|
||||||
|
|
||||||
|
### Shared Test Utilities
|
||||||
|
|
||||||
|
Test utilities are located in `tests/shared/` and provide common functions and mocks for tests.
|
||||||
|
|
||||||
|
### Setup and Teardown
|
||||||
|
|
||||||
|
Use Jest hooks for setup and teardown logic:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
beforeEach(async () => {
|
||||||
|
await setupTestDatabase();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(async () => {
|
||||||
|
await cleanupTestDatabase();
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
- Always aim for high test coverage and meaningful scenarios.
|
||||||
|
- Validate each critical aspect of your code with real-world data.
|
||||||
|
- Continually run tests during development to catch issues early.
|
||||||
|
|
||||||
|
Follow the guidelines above to ensure your contributions maintain the reliability and performance of DebrosFramework.
|
127
docs/docs/core-concepts/database-management.md
Normal file
127
docs/docs/core-concepts/database-management.md
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
# Database Management
|
||||||
|
|
||||||
|
The `DatabaseManager` class in DebrosFramework manages all aspects of database interaction and lifecycle.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
The DatabaseManager handles:
|
||||||
|
|
||||||
|
- Database creation
|
||||||
|
- Connection pooling
|
||||||
|
- User-scoped vs global database routing
|
||||||
|
- Query execution optimization
|
||||||
|
|
||||||
|
## Key Features
|
||||||
|
|
||||||
|
1. **Connection Management** - Manages database connections and pooling.
|
||||||
|
2. **Sharding Support** - Integrates with the ShardManager to support data distribution.
|
||||||
|
3. **Performance** - Caches database instances for efficient access.
|
||||||
|
|
||||||
|
## Classes
|
||||||
|
|
||||||
|
### DatabaseManager
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class DatabaseManager {
|
||||||
|
constructor(
|
||||||
|
private orbitDBService: FrameworkOrbitDBService,
|
||||||
|
private shardManager: ShardManager,
|
||||||
|
private configManager: ConfigManager
|
||||||
|
);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Methods
|
||||||
|
|
||||||
|
### `getDatabaseForModel`
|
||||||
|
|
||||||
|
Finds or creates a suitable database for a given model class, considering user-scope or global-scope.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async getDatabaseForModelcT extends BaseModele(
|
||||||
|
modelClass: ModelConstructorcTe,
|
||||||
|
userId?: string
|
||||||
|
): PromisecDatabasee
|
||||||
|
```
|
||||||
|
|
||||||
|
### `createUserDatabase`
|
||||||
|
|
||||||
|
Creates a user-centric database using sharding strategies.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
async createUserDatabasecT extends BaseModele(
|
||||||
|
userId: string,
|
||||||
|
modelClass: ModelConstructorcTe
|
||||||
|
): PromisecDatabasee
|
||||||
|
```
|
||||||
|
|
||||||
|
## Usage Examples
|
||||||
|
|
||||||
|
### Example: User-scoped Database
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'user',
|
||||||
|
type: 'docstore',
|
||||||
|
sharding: { strategy: 'hash', count: 4, key: 'id' }
|
||||||
|
})
|
||||||
|
class UserProfile extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string' })
|
||||||
|
bio: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage
|
||||||
|
const userDB = await databaseManager.getDatabaseForModel(UserProfile, 'user123');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example: Global Database
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
@Model({
|
||||||
|
scope: 'global',
|
||||||
|
type: 'docstore'
|
||||||
|
})
|
||||||
|
class GlobalStats extends BaseModel {
|
||||||
|
@Field({ type: 'number' })
|
||||||
|
totalUsers: number;
|
||||||
|
|
||||||
|
@Field({ type: 'number' })
|
||||||
|
totalInteractions: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage
|
||||||
|
const globalDB = await databaseManager.getDatabaseForModel(GlobalStats);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Configuration Options
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
interface DatabaseConfig {
|
||||||
|
maxDatabases: number;
|
||||||
|
defaultType: StoreType;
|
||||||
|
caching: {
|
||||||
|
enabled: boolean;
|
||||||
|
maxSize: number;
|
||||||
|
ttl: number;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ShardingConfig {
|
||||||
|
defaultStrategy: ShardingStrategy;
|
||||||
|
defaultCount: number;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Documents
|
||||||
|
|
||||||
|
- [Shard Manager](../api/shard-manager) - Handles data sharding and distribution.
|
||||||
|
- [Query Executor](../api/query-executor) - Handles query execution and optimization.
|
166
docs/docs/examples/complex-queries.md
Normal file
166
docs/docs/examples/complex-queries.md
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
# Complex Queries
|
||||||
|
|
||||||
|
This example demonstrates advanced query patterns and techniques in DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Learn how to build complex queries using DebrosFramework's powerful query system.
|
||||||
|
|
||||||
|
## Query Examples
|
||||||
|
|
||||||
|
### Basic Filtering
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Simple where clause
|
||||||
|
const activeUsers = await User.query()
|
||||||
|
.where('isActive', true)
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// Multiple conditions
|
||||||
|
const recentPosts = await Post.query()
|
||||||
|
.where('createdAt', '>', Date.now() - 7 * 24 * 60 * 60 * 1000)
|
||||||
|
.where('isPublished', true)
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Advanced Filtering
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// OR conditions
|
||||||
|
const popularPosts = await Post.query()
|
||||||
|
.where('viewCount', '>', 1000)
|
||||||
|
.orWhere('likeCount', '>', 100)
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// IN operator
|
||||||
|
const categorizedPosts = await Post.query()
|
||||||
|
.where('category', 'in', ['tech', 'science', 'programming'])
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// LIKE operator for text search
|
||||||
|
const searchResults = await Post.query()
|
||||||
|
.where('title', 'like', '%javascript%')
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Sorting and Pagination
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Sorting
|
||||||
|
const sortedPosts = await Post.query()
|
||||||
|
.orderBy('createdAt', 'desc')
|
||||||
|
.orderBy('title', 'asc')
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// Pagination
|
||||||
|
const paginatedPosts = await Post.query()
|
||||||
|
.orderBy('createdAt', 'desc')
|
||||||
|
.limit(10)
|
||||||
|
.offset(20)
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Relationship Loading
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Eager loading
|
||||||
|
const usersWithPosts = await User.query()
|
||||||
|
.with(['posts'])
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// Nested relationships
|
||||||
|
const usersWithPostsAndComments = await User.query()
|
||||||
|
.with(['posts.comments', 'posts.comments.user'])
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// Conditional relationship loading
|
||||||
|
const activeUsersWithRecentPosts = await User.query()
|
||||||
|
.where('isActive', true)
|
||||||
|
.with(['posts'], (query) =>
|
||||||
|
query.where('createdAt', '>', Date.now() - 30 * 24 * 60 * 60 * 1000)
|
||||||
|
)
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Aggregation
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Count
|
||||||
|
const userCount = await User.query()
|
||||||
|
.where('isActive', true)
|
||||||
|
.count();
|
||||||
|
|
||||||
|
// Group by
|
||||||
|
const postsByCategory = await Post.query()
|
||||||
|
.select('category', 'COUNT(*) as count')
|
||||||
|
.groupBy('category')
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Complex Joins
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Manual join
|
||||||
|
const usersWithPostCount = await User.query()
|
||||||
|
.leftJoin('posts', 'users.id', 'posts.userId')
|
||||||
|
.select('users.username', 'COUNT(posts.id) as postCount')
|
||||||
|
.groupBy('users.id', 'users.username')
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Caching
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Cache for 5 minutes
|
||||||
|
const cachedPosts = await Post.query()
|
||||||
|
.where('isPublished', true)
|
||||||
|
.cache(300)
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// Disable caching
|
||||||
|
const freshPosts = await Post.query()
|
||||||
|
.where('isPublished', true)
|
||||||
|
.cache(false)
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Performance Optimization
|
||||||
|
|
||||||
|
### Query Optimization
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Use indexes
|
||||||
|
const optimizedQuery = await Post.query()
|
||||||
|
.where('userId', userId) // Indexed field
|
||||||
|
.where('createdAt', '>', startDate)
|
||||||
|
.orderBy('createdAt', 'desc')
|
||||||
|
.limit(50)
|
||||||
|
.find();
|
||||||
|
|
||||||
|
// Batch operations
|
||||||
|
const userIds = ['user1', 'user2', 'user3'];
|
||||||
|
const users = await User.query()
|
||||||
|
.where('id', 'in', userIds)
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Parallel Queries
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Execute queries in parallel
|
||||||
|
const [users, posts, comments] = await Promise.all([
|
||||||
|
User.query().where('isActive', true).find(),
|
||||||
|
Post.query().where('isPublished', true).find(),
|
||||||
|
Comment.query().where('isModerated', true).find()
|
||||||
|
]);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Topics
|
||||||
|
|
||||||
|
- [Query Builder](../query-system/query-builder) - Query construction
|
||||||
|
- [Relationships](../query-system/relationships) - Model relationships
|
||||||
|
- [Performance](../advanced/performance) - Performance optimization
|
93
docs/docs/examples/migrations.md
Normal file
93
docs/docs/examples/migrations.md
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 3
|
||||||
|
---
|
||||||
|
|
||||||
|
# Migration Examples
|
||||||
|
This example demonstrates various migration scenarios using DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Explore different migration techniques to evolve your database schema over time.
|
||||||
|
|
||||||
|
## Migration Scenarios
|
||||||
|
|
||||||
|
### Adding Fields
|
||||||
|
|
||||||
|
Add new fields to an existing model:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const migration = createMigration('add_user_address', '1.4.0')
|
||||||
|
.addField('User', 'address', { type: 'string', required: false })
|
||||||
|
.addField('User', 'phone', { type: 'string', required: false });
|
||||||
|
```
|
||||||
|
|
||||||
|
### Removing Fields
|
||||||
|
|
||||||
|
Remove obsolete fields from a model:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const migration = createMigration('remove_user_legacy', '1.5.0')
|
||||||
|
.removeField('User', 'legacyField');
|
||||||
|
```
|
||||||
|
|
||||||
|
### Modifying Fields
|
||||||
|
|
||||||
|
Modify field properties without data loss:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const migration = createMigration('modify_email_format', '1.6.0')
|
||||||
|
.modifyField('User', 'email', {
|
||||||
|
type: 'string',
|
||||||
|
required: true,
|
||||||
|
unique: true,
|
||||||
|
validate: (email: string) =\u003e /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(email),
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Data Transformation
|
||||||
|
|
||||||
|
Use data transformers to update field values during migration:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const migration = createMigration('transform_display_names', '1.7.0')
|
||||||
|
.transformData('User', (user) =\u003e ({
|
||||||
|
...user,
|
||||||
|
displayName: `${user.firstName} ${user.lastName}`.trim()
|
||||||
|
}));
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running Migrations
|
||||||
|
|
||||||
|
### Manual Execution
|
||||||
|
|
||||||
|
Execute migrations manually using the MigrationManager:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const migrationManager = new MigrationManager(databaseManager, configManager);
|
||||||
|
await migrationManager.runMigration(migration);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Automatic Execution
|
||||||
|
|
||||||
|
Enable automatic migration execution:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const framework = new DebrosFramework({
|
||||||
|
migrations: {
|
||||||
|
autoRun: true,
|
||||||
|
directory: './migrations'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Best Practices
|
||||||
|
|
||||||
|
1. **Test Thoroughly** - Validate migrations in a test environment before applying to production.
|
||||||
|
2. **Backup Data** - Ensure data backups before running critical migrations.
|
||||||
|
3. **Use Transactions** - Where possible, use transactions for atomic operations.
|
||||||
|
4. **Have Rollback Plans** - Prepare rollback scripts for critical changes.
|
||||||
|
|
||||||
|
## Related Topics
|
||||||
|
|
||||||
|
- [MigrationManager](../api/migration-manager) - Migration execution
|
||||||
|
- [MigrationBuilder](../api/migration-builder) - Migration creation
|
223
docs/docs/examples/social-platform.md
Normal file
223
docs/docs/examples/social-platform.md
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 1
|
||||||
|
---
|
||||||
|
|
||||||
|
# Social Platform Example
|
||||||
|
|
||||||
|
This example demonstrates how to build a simple social media platform using DebrosFramework.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
In this example, you'll build a social media application featuring users, posts, and comments.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```plaintext
|
||||||
|
src/
|
||||||
|
├── models/
|
||||||
|
│ ├── User.ts
|
||||||
|
│ ├── Post.ts
|
||||||
|
│ ├── Comment.ts
|
||||||
|
│ └── index.ts
|
||||||
|
├── services/
|
||||||
|
│ ├── ipfs.ts
|
||||||
|
│ ├── orbitdb.ts
|
||||||
|
│ └── index.ts
|
||||||
|
└── index.ts
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setting Up the Environment
|
||||||
|
|
||||||
|
### Install Dependencies
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm install @debros/network
|
||||||
|
npm install --save-dev typescript @types/node
|
||||||
|
```
|
||||||
|
|
||||||
|
### Configure TypeScript
|
||||||
|
|
||||||
|
Create a `tsconfig.json` file:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "ES2020",
|
||||||
|
"module": "commonjs",
|
||||||
|
"lib": ["ES2020"],
|
||||||
|
"experimentalDecorators": true,
|
||||||
|
"emitDecoratorMetadata": true,
|
||||||
|
"strict": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"declaration": true,
|
||||||
|
"outDir": "./dist",
|
||||||
|
"rootDir": "./src"
|
||||||
|
},
|
||||||
|
"include": ["src/**/*"],
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Building the Application
|
||||||
|
|
||||||
|
### 1. User Model
|
||||||
|
|
||||||
|
Create `src/models/User.ts`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { BaseModel, Model, Field, HasMany } from 'debros-framework';
|
||||||
|
import { Post } from './Post';
|
||||||
|
import { Comment } from './Comment';
|
||||||
|
|
||||||
|
@Model({
|
||||||
|
scope: 'global', // Global model
|
||||||
|
type: 'docstore'
|
||||||
|
})
|
||||||
|
export class User extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true, unique: true })
|
||||||
|
username: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true, unique: true })
|
||||||
|
email: string;
|
||||||
|
|
||||||
|
@HasMany(() => Post, 'userId')
|
||||||
|
posts: Post[];
|
||||||
|
|
||||||
|
@HasMany(() => Comment, 'userId')
|
||||||
|
comments: Comment[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Post Model
|
||||||
|
|
||||||
|
Create `src/models/Post.ts`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { BaseModel, Model, Field, BelongsTo, HasMany } from 'debros-framework';
|
||||||
|
import { User } from './User';
|
||||||
|
import { Comment } from './Comment';
|
||||||
|
|
||||||
|
@Model({
|
||||||
|
scope: 'user', // User-scoped model
|
||||||
|
type: 'docstore'
|
||||||
|
})
|
||||||
|
export class Post extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
title: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
content: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'userId')
|
||||||
|
user: User;
|
||||||
|
|
||||||
|
@HasMany(() => Comment, 'postId')
|
||||||
|
comments: Comment[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Comment Model
|
||||||
|
|
||||||
|
Create `src/models/Comment.ts`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { BaseModel, Model, Field, BelongsTo } from 'debros-framework';
|
||||||
|
import { User } from './User';
|
||||||
|
import { Post } from './Post';
|
||||||
|
|
||||||
|
@Model({
|
||||||
|
scope: 'user', // User-scoped model
|
||||||
|
type: 'docstore'
|
||||||
|
})
|
||||||
|
export class Comment extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
content: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
postId: string;
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'userId')
|
||||||
|
user: User;
|
||||||
|
|
||||||
|
@BelongsTo(() => Post, 'postId')
|
||||||
|
post: Post;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. IPFS and OrbitDB Service
|
||||||
|
|
||||||
|
Create `src/services/ipfs.ts` and `src/services/orbitdb.ts` following similar patterns to the setup in earlier examples.
|
||||||
|
|
||||||
|
### 5. Main Application
|
||||||
|
|
||||||
|
Create `src/index.ts`:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
import { DebrosFramework } from 'debros-framework';
|
||||||
|
import { IPFSService } from './services/ipfs';
|
||||||
|
import { OrbitDBService } from './services/orbitdb';
|
||||||
|
import { User, Post, Comment } from './models';
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
// Initialize services
|
||||||
|
const ipfsService = new IPFSService();
|
||||||
|
await ipfsService.init();
|
||||||
|
|
||||||
|
const orbitDBService = new OrbitDBService(ipfsService);
|
||||||
|
await orbitDBService.init();
|
||||||
|
|
||||||
|
// Initialize DebrosFramework
|
||||||
|
const framework = new DebrosFramework();
|
||||||
|
await framework.initialize(orbitDBService, ipfsService);
|
||||||
|
|
||||||
|
console.log('🚀 Social Platform initialized successfully!');
|
||||||
|
|
||||||
|
// Example: Create a user and post
|
||||||
|
const user = await User.create({
|
||||||
|
username: 'alice',
|
||||||
|
email: 'alice@example.com'
|
||||||
|
});
|
||||||
|
|
||||||
|
const post = await Post.create({
|
||||||
|
title: 'Hello, World!',
|
||||||
|
content: 'This is my first post.',
|
||||||
|
userId: user.id
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log('✅ User and Post created successfully!');
|
||||||
|
|
||||||
|
// Clean up
|
||||||
|
await framework.stop();
|
||||||
|
console.log('👋 Framework stopped successfully');
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch(console.error);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running the Application
|
||||||
|
|
||||||
|
### Build and Run
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run build
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
### Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
In this example, you have seen how to leverage DebrosFramework to build a basic social media application. You can enhance it by adding more features, such as user authentication, friend networks, or media uploads.
|
96
docs/docs/query-system/relationships.md
Normal file
96
docs/docs/query-system/relationships.md
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
---
|
||||||
|
sidebar_position: 2
|
||||||
|
---
|
||||||
|
|
||||||
|
# Relationships
|
||||||
|
|
||||||
|
DebrosFramework provides powerful relationship management capabilities for connecting models.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
Relationships define how models are connected to each other and provide mechanisms for loading related data efficiently.
|
||||||
|
|
||||||
|
## Relationship Types
|
||||||
|
|
||||||
|
### BelongsTo
|
||||||
|
|
||||||
|
A many-to-one relationship where the current model belongs to another model.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class Post extends BaseModel {
|
||||||
|
@Field({ type: 'string', required: true })
|
||||||
|
userId: string;
|
||||||
|
|
||||||
|
@BelongsTo(() => User, 'userId')
|
||||||
|
user: User;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### HasMany
|
||||||
|
|
||||||
|
A one-to-many relationship where the current model has many related models.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@HasMany(() => Post, 'userId')
|
||||||
|
posts: Post[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### HasOne
|
||||||
|
|
||||||
|
A one-to-one relationship where the current model has one related model.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@HasOne(() => UserProfile, 'userId')
|
||||||
|
profile: UserProfile;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### ManyToMany
|
||||||
|
|
||||||
|
A many-to-many relationship using a pivot table.
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
class User extends BaseModel {
|
||||||
|
@ManyToMany(() => Role, 'user_roles')
|
||||||
|
roles: Role[];
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Loading Relationships
|
||||||
|
|
||||||
|
### Eager Loading
|
||||||
|
|
||||||
|
Load relationships when querying:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const usersWithPosts = await User.query()
|
||||||
|
.with(['posts'])
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Lazy Loading
|
||||||
|
|
||||||
|
Load relationships on-demand:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const user = await User.findById('user123');
|
||||||
|
const posts = await user.loadRelationship('posts');
|
||||||
|
```
|
||||||
|
|
||||||
|
## Nested Relationships
|
||||||
|
|
||||||
|
Load nested relationships:
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
const usersWithPostsAndComments = await User.query()
|
||||||
|
.with(['posts.comments', 'posts.comments.user'])
|
||||||
|
.find();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Related Classes
|
||||||
|
|
||||||
|
- [`RelationshipManager`](../api/relationship-manager) - Manages relationships
|
||||||
|
- [`BaseModel`](../api/base-model) - Base model class
|
Reference in New Issue
Block a user