# Database Configuration

<div align="center">
  <img src="../../logos/rustelo_dev-logo-h.svg" alt="RUSTELO" width="300" />
</div>

This guide covers how to configure and use databases in RUSTELO. The application supports both **PostgreSQL** and **SQLite** databases through SQLx's unified interface, with automatic database type detection based on the connection URL.

## Quick Start

### SQLite (Recommended for Development)
```toml
[database]
url = "sqlite://database.db"
```

### PostgreSQL (Recommended for Production)
```toml
[database]
url = "postgresql://username:password@localhost:5432/database_name"
```

## Database URL Formats

### SQLite URLs
- `sqlite://database.db` - Relative path to database file
- `sqlite:///path/to/database.db` - Absolute path to database file
- `sqlite::memory:` - In-memory database (testing only)

### PostgreSQL URLs
- `postgresql://user:password@host:port/database`
- `postgres://user:password@host:port/database`

## Environment Variables

You can override the database URL using environment variables:

```bash
export DATABASE_URL="sqlite//:my_database.db"
# or
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
```

## Database-Specific Features

### SQLite
- **Pros:**
  - Zero configuration setup
  - Single file database
  - Perfect for development and testing
  - No separate server process required
  - ACID compliant

- **Cons:**
  - Limited concurrent writes
  - No network access
  - Fewer advanced features
  - File-based storage

### PostgreSQL
- **Pros:**
  - Full ACID compliance
  - Excellent concurrent access
  - Advanced features (JSONB, arrays, etc.)
  - Network accessible
  - Production-ready scalability

- **Cons:**
  - Requires PostgreSQL server
  - More complex setup
  - Resource overhead

## Configuration Examples

### Development Configuration
```toml
# config.dev.toml
[database]
url = "sqlite://dev_database.db"
max_connections = 5
min_connections = 1
connect_timeout = 30
idle_timeout = 300
max_lifetime = 1800
```

### Production Configuration
```toml
# config.prod.toml
[database]
url = "postgresql://prod_user:${DATABASE_PASSWORD}@db.example.com:5432/prod_database"
max_connections = 20
min_connections = 5
connect_timeout = 30
idle_timeout = 600
max_lifetime = 3600
```

## Connection Pool Settings

| Setting | Description | SQLite | PostgreSQL |
|---------|-------------|--------|------------|
| `max_connections` | Maximum pool size | 1 (recommended) | 10-50 |
| `min_connections` | Minimum pool size | 1 | 1-5 |
| `connect_timeout` | Connection timeout (seconds) | 30 | 30 |
| `idle_timeout` | Idle connection timeout (seconds) | 300 | 600 |
| `max_lifetime` | Maximum connection lifetime (seconds) | 1800 | 3600 |

## Database Setup

### SQLite Setup
No setup required! The database file will be created automatically when the application starts.

### PostgreSQL Setup

#### Using Docker
```bash
# Start PostgreSQL container
docker run -d \
  --name postgres \
  -e POSTGRES_PASSWORD=password \
  -e POSTGRES_DB=myapp \
  -p 5432:5432 \
  postgres:15

# Connect to database
docker exec -it postgres psql -U postgres -d myapp
```

#### Using Local Installation

**macOS (Homebrew):**
```bash
brew install postgresql
brew services start postgresql
createdb myapp
```

**Ubuntu/Debian:**
```bash
sudo apt-get install postgresql postgresql-contrib
sudo systemctl start postgresql
sudo -u postgres createdb myapp
```

## Migration Support

The application automatically creates the necessary tables for both database types:

### SQLite Tables
- Uses `TEXT` for IDs (UUID format)
- Uses `DATETIME` for timestamps
- Uses `TEXT` for JSON storage
- Uses `BOOLEAN` for boolean values

### PostgreSQL Tables
- Uses `UUID` for IDs with `gen_random_uuid()`
- Uses `TIMESTAMPTZ` for timestamps
- Uses `JSONB` for JSON storage
- Uses `BOOLEAN` for boolean values

## Switching Between Databases

You can switch between databases by simply changing the `DATABASE_URL`:

```bash
# Switch to SQLite
export DATABASE_URL="sqlite://database.db"

# Switch to PostgreSQL
export DATABASE_URL="postgresql://user:pass@localhost:5432/mydb"
```

The application will automatically:
1. Detect the database type
2. Use appropriate SQL syntax
3. Create compatible table schemas
4. Handle data type differences

## Performance Considerations

### SQLite
- **Best for:**
  - Single-user applications
  - Development and testing
  - Small to medium datasets
  - Read-heavy workloads

- **Optimization tips:**
  - Use WAL mode: `PRAGMA journal_mode=WAL`
  - Set appropriate timeout: `PRAGMA busy_timeout=5000`
  - Use transactions for bulk operations

### PostgreSQL
- **Best for:**
  - Multi-user applications
  - Production environments
  - Large datasets
  - High concurrency requirements

- **Optimization tips:**
  - Configure appropriate connection pool size
  - Use indexes on frequently queried columns
  - Monitor and tune PostgreSQL configuration
  - Use connection pooling (PgBouncer) for high traffic

## Troubleshooting

### Common SQLite Issues
- **Database locked**: Check for long-running transactions
- **File permissions**: Ensure write access to database file and directory
- **Disk space**: Verify sufficient disk space for database growth

### Common PostgreSQL Issues
- **Connection refused**: Check PostgreSQL server status
- **Authentication failed**: Verify username/password and pg_hba.conf
- **Too many connections**: Adjust max_connections or use connection pooling

### Debug Connection Issues
```bash
# Test SQLite connection
sqlite3 database.db "SELECT 1;"

# Test PostgreSQL connection
psql "postgresql://user:pass@localhost:5432/mydb" -c "SELECT 1;"
```

## Environment-Specific Configuration

### Development
```bash
# .env.development
DATABASE_URL=sqlite://dev_database.db
```

### Testing
```bash
# .env.test
DATABASE_URL=sqlite::memory:
```

### Production
```bash
# .env.production
DATABASE_URL=postgresql://user:${DATABASE_PASSWORD}@db.internal:5432/prod_db
```

## Security Considerations

### SQLite Security
- Protect database file permissions (600 or 640)
- Backup database files securely
- Consider encryption for sensitive data

### PostgreSQL Security
- Use strong passwords
- Enable SSL/TLS connections
- Restrict network access
- Regular security updates
- Use connection pooling with authentication

## Backup and Recovery

### SQLite Backup
```bash
# Simple file copy
cp database.db database_backup.db

# Using SQLite backup command
sqlite3 database.db ".backup database_backup.db"
```

### PostgreSQL Backup
```bash
# Database dump
pg_dump myapp > myapp_backup.sql

# Restore from dump
psql myapp < myapp_backup.sql
```

## Monitoring and Maintenance

### SQLite Maintenance
```sql
-- Analyze database
ANALYZE;

-- Vacuum database
VACUUM;

-- Check integrity
PRAGMA integrity_check;
```

### PostgreSQL Maintenance
```sql
-- Analyze tables
ANALYZE;

-- Vacuum tables
VACUUM;

-- Check database size
SELECT pg_size_pretty(pg_database_size('myapp'));
```

## Best Practices

1. **Use environment variables** for database URLs in production
2. **Configure appropriate connection pools** based on your workload
3. **Monitor database performance** and adjust settings as needed
4. **Regular backups** are essential for production databases
5. **Test migrations** on both database types if supporting both
6. **Use transactions** for data consistency
7. **Index frequently queried columns** for better performance
8. **Monitor connection pool usage** to prevent exhaustion

## Feature Compatibility Matrix

| Feature | SQLite | PostgreSQL |
|---------|--------|------------|
| ACID Transactions | ✅ | ✅ |
| Concurrent Reads | ✅ | ✅ |
| Concurrent Writes | ⚠️ Limited | ✅ |
| JSON Support | ✅ (TEXT) | ✅ (JSONB) |
| Full-text Search | ✅ (FTS) | ✅ (Built-in) |
| Network Access | ❌ | ✅ |
| Replication | ❌ | ✅ |
| Partitioning | ❌ | ✅ |
| Custom Functions | ✅ | ✅ |
| Triggers | ✅ | ✅ |
| Views | ✅ | ✅ |
| Stored Procedures | ❌ | ✅ |

## Next Steps

- [Database Migrations](../developers/features/migrations.md)
- [Performance Optimization](../performance/database.md)
- [Security Best Practices](../security/data-protection.md)
- [Backup Strategies](../deployment/backup.md)

This guide should help you choose and configure the right database for your needs. Both options are fully supported and the application will work seamlessly with either choice.
