npm package: @jamx-framework/db
Description: JAMX Framework â€” Database ORM
Author: Stiven-21
Latest version: 1.0.0

# @jamx-framework/db

## Descripción
Módulo de base de datos y ORM (Object-Relational Mapping) para JAMX Framework. Proporciona una API tipada yagnóstica para interactuar con diferentes motores de base de datos (SQLite, PostgreSQL, MySQL, etc.) mediante drivers específicos, ofreciendo funcionalidades como:

- **Repository**: Acceso a tablas con operaciones CRUD tipadas
- **Migrations**: Sistema de migraciones de esquema con generación automática de SQL
- **Query Builder**: Construcción segura de consultas con parámetros serializados
- **Transaction Management**: Manejo de transacciones con rollback automático
- **Schema Introspection**: Detección de diferencias entre el esquema definido y la base de datos real

## Cómo funciona
El módulo está estructurado en varios componentes clave que trabajan juntos:

1. **Database**: Punto de entrada principal que crea y gestiona conexiones a drivers de base de datos
2. **Repository**: Acceso a tablas con operaciones CRUD tipadas y gestión de entidades
3. **Migrations**: Sistema para versionar cambios de esquema con `up`/`down` methods
4. **Schema Diff**: Detecta diferencias entre el esquema definido y la base de datos real
5. **Query Builder**: Construcción segura de consultas con serialización de parámetros
6. **Drivers**: Implementaciones específicas para cada motor (SQLite, MySQL, PostgreSQL, etc.)

## Componentes principales
- **src/database.ts**: Clase `Database` que crea y gestiona conexiones a drivers
- **src/repository.ts**: Clase genérica `Repository<T>` con operaciones CRUD
- **src/migrations/runner.ts**: Clase `MigrationRunner` que ejecuta y rastrea migraciones
- **src/migrations/schema-diff.ts**: Clase `SchemaDiff` que detecta diferencias de esquema
- **src/query/builder.ts**: Clase base `BaseQuery` con lógica compartida de consultas
- **src/drivers/sqlite.ts**: Driver para SQLite (y otros drivers en `src/drivers/`)
- **src/schema/table.ts**: Definiciones de tablas y columnas con tipado fuerte
- **src/schema/column.ts**: Definiciones de columnas con tipos y restricciones
- **src/types/***: Tipos compartidos como `PaginatedResult`, `Result`, `Brand`, etc.

## Uso básico
```typescript
import { Database } from '@jamx-framework/db';
import { defineTable, column, integer, text } from '@jamx-framework/db/schema';

// Definir la tabla de usuarios
export const usersTable = defineTable(
  'users',
  {
    id: column.text('id').primaryKey(),
    name: column.text('name').notNull(),
    email: column.text('email').unique(),
    createdAt: column.integer('created_at').default(0),
  }
);

// Crear instancia de la base de datos
const db = new Database({
  driver: 'sqlite',
  url: './data.db',
});

// Conectar y crear tabla si no existe
await db.connect();
await db.createTable(usersTable);

// Insertar un usuario
await db.repository(usersTable).insert({
  id: '1',
  name: 'Juan Pérez',
  email: 'juan@example.com',
  createdAt: Date.now(),
});

// Consultar usuarios
const users = await db.repository(usersTable).findAll();
console.log('Usuarios:', users);
```

## Ejemplos
### Operaciones CRUD básicas
```typescript
// Crear tabla
await db.createTable(usersTable);

// Insertar registro
await db.repository(usersTable).insert({
  id: '2',
  name: 'Ana Gómez',
  email: 'ana@example.com',
});

// Buscar por ID
const user = await db.repository(usersTable).findById('1');
console.log('Usuario encontrado:', user);

// Actualizar registro
await db.repository(usersTable).update('1', { name: 'Juan Pérez Updated' });

// Eliminar registro
await db.repository(usersTable).delete('1');
```

### Migraciones automáticas
```bash
# Generar migración a partir de cambios en el esquema
jamx db:generate-migration --name add_posts_table

# Aplicar migraciones pendientes
jamx db:migrate

# Revertir última migración
jamx db:rollback
```

### Uso avanzado con transacciones
```typescript
await db.transaction(async (txDb) => {
  // Todas las operaciones dentro de esta función se ejecutan en una transacción
  await txDb.repository(usersTable).insert({ id: '3', name: 'Pedro', email: 'pedro@example.com' });
  await txDb.repository(usersTable).update('2', { email: 'ana.actualizada@example.com' });
});
```

### Paginación y resultados seguros
```typescript
const result = await db.repository(usersTable)
  .select()
  .paginate({ page: 1, limit: 10 });

console.log(`Página 1 de ${result.totalPages} con ${result.total} usuarios`);
console.log('Datos:', result.data);
```

## Flujo interno
1. **Inicialización**: `Database` crea el driver apropiado según la configuración (`sqlite`, `postgres`, etc.)
2. **Conexión**: Se establece la conexión con la base de datos mediante `driver.connect()`
3. **Definición de esquema**: Las tablas se definen usando `defineTable()` y `column()` con tipos y restricciones
4. **Operaciones CRUD**: `Repository` ejecuta consultas mediante `BaseQuery` y sus subclasses (`SelectQuery`, `InsertQuery`, etc.)
5. **Serialización de parámetros**: Los valores se serializan adecuadamente según el tipo de columna (ej: boolean → 0/1, JSON → stringificado)
6. **Transacciones**: Cuando se usa `transaction()`, todas las operaciones se ejecutan dentro de una transacción con rollback automático en caso de error
7. **Migraciones**: `MigrationRunner` mantiene una tabla interna `__jamx_migrations` para rastrear qué migraciones se han ejecutado
8. **Detección de diferencias**: `SchemaDiff` compara el esquema definido con la base de datos real para generar migraciones automáticas
9. **Resultados tipados**: Los métodos devuelven resultados tipados que pueden ser manejados con `Result.ok()`/`Result.err()` para manejo explícito de errores

## API Reference (Resumen)
### Database
- `new Database(config)`: Crea una nueva instancia
- `connect()`: Establece la conexión
- `disconnect()`: Cierra la conexión
- `repository(table)`: Obtiene un `Repository` para una tabla
- `raw(sql, params?)`: Ejecuta SQL crudo

### Repository
- `findAll()`: Obtiene todos los registros
- `findById(id)`: Busca por ID
- `findOne(where)`: Busca el primer registro que coincida
- `findMany(where)`: Busca múltiples registros
- `insert(entity)`: Inserta un nuevo registro
- `update(id, data)`: Actualiza un registro existente
- `delete(id)`: Elimina un registro
- `paginate(options)`: Paginación con metadatos

### Migrations
- `MigrationRunner.initialize()`: Inicializa la tabla de migraciones
- `MigrationRunner.run(migrations)`: Ejecuta migraciones pendientes
- `MigrationRunner.rollback(migrations, steps?)`: Revierte migraciones
- `MigrationRunner.status(migrations)`: Obtiene el estado de todas las migraciones

### Schema Definition
- `defineTable(name, columns)`: Define una tabla con sus columnas
- `column(name, type)`: Define una columna con tipo y restricciones
- Tipos de columnas: `text()`, `integer()`, `real()`, `boolean()`, `blob()`, `json()`

## Performance Considerations
- **Prepared Statements**: Todos los drivers usan consultas preparadas para prevenir SQL injection
- **Batch Operations**: `insertMany()` y operaciones similares están optimizadas para inserciones en lote
- **Connection Pooling**: Los drivers implementan pooling de conexiones para reutilizar conexiones activas
- **Lazy Loading**: Las tablas y relaciones se cargan solo cuando se accede a ellas

## Compatibility
- Compatible con Node.js 18+ y TypeScript 5.x
- Soporta SQLite (por defecto), PostgreSQL, MySQL, y otros motores mediante drivers adicionales
- Funciona en Windows, macOS y Linux
- No requiere dependencias globales; todas las herramientas se instalan como devDependencies

## Plugin Development
Para crear un driver personalizado:

1. Extiende `DatabaseDriver` e implementa los métodos abstractos (`connect`, `disconnect`, `query`, `transaction`)
2. Registra el driver en la configuración del `Database`
3. Implementa métodos de transacción si tu motor los soporta

Ejemplo mínimo de driver:
```typescript
import { DatabaseDriver } from '@jamx-framework/db';

export class MyCustomDriver implements DatabaseDriver {
  async connect() { /* lógica de conexión */ }
  async disconnect() { /* lógica de desconexión */ }
  async query(sql: string, params: unknown[]) { /* lógica de consulta */ }
  async transaction(fn: (db: Database) => Promise<unknown>) { /* lógica de transacción */ }
}
```

## Testing
El proyecto incluye tests unitarios en `packages/db/tests/unit/`. Para ejecutarlos:

```bash
pnpm test
# o
npm run test
```

Los tests cubren:
- Conexión y operaciones básicas con SQLite
- CRUD completo mediante Repository
- Sistema de migraciones y rollback
- Detección de diferencias de esquema
- Manejo de transacciones
- Serialización segura de parámetros

## Configuration Options
```typescript
new Database({
  driver: 'sqlite' | 'postgres' | 'mysql' | 'mariadb' | 'mongodb',
  url: string,           // Cadena de conexión (ej: 'sqlite:./data.db')
  entities: TableDefinition[], // Opcional: tablas a registrar automáticamente
  // Opciones específicas por driver:
  //   sqlite: { url: string }
  //   postgres: { host, port, database, user, password }
  //   mysql: { host, port, database, user, password }
});
```

## CLI Commands (Jamx)
- `jamx db:generate-migration --name <nombre>`: Genera una migración basada en cambios de esquema
- `jamx db:migrate`: Aplica todas las migraciones pendientes
- `jamx db:rollback`: Revierte la última migración ejecutada
- `jamx db:status`: Muestra el estado actual de las migraciones
- `jamx db:push`: Genera y aplica migraciones automáticamente

This database module provides a robust, type-safe foundation for database interactions in JAMX applications, enabling developers to work with multiple database engines through a unified and expressive API while maintaining full control over schema evolution and data operations.