@jamx-framework/db
v1.0.0
Published
JAMX Framework — Database ORM
Maintainers
Readme
@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:
- Database: Punto de entrada principal que crea y gestiona conexiones a drivers de base de datos
- Repository: Acceso a tablas con operaciones CRUD tipadas y gestión de entidades
- Migrations: Sistema para versionar cambios de esquema con
up/downmethods - Schema Diff: Detecta diferencias entre el esquema definido y la base de datos real
- Query Builder: Construcción segura de consultas con serialización de parámetros
- Drivers: Implementaciones específicas para cada motor (SQLite, MySQL, PostgreSQL, etc.)
Componentes principales
- src/database.ts: Clase
Databaseque crea y gestiona conexiones a drivers - src/repository.ts: Clase genérica
Repository<T>con operaciones CRUD - src/migrations/runner.ts: Clase
MigrationRunnerque ejecuta y rastrea migraciones - src/migrations/schema-diff.ts: Clase
SchemaDiffque detecta diferencias de esquema - src/query/builder.ts: Clase base
BaseQuerycon 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
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: '[email protected]',
createdAt: Date.now(),
});
// Consultar usuarios
const users = await db.repository(usersTable).findAll();
console.log('Usuarios:', users);Ejemplos
Operaciones CRUD básicas
// Crear tabla
await db.createTable(usersTable);
// Insertar registro
await db.repository(usersTable).insert({
id: '2',
name: 'Ana Gómez',
email: '[email protected]',
});
// 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
# 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:rollbackUso avanzado con transacciones
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: '[email protected]' });
await txDb.repository(usersTable).update('2', { email: '[email protected]' });
});Paginación y resultados seguros
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
- Inicialización:
Databasecrea el driver apropiado según la configuración (sqlite,postgres, etc.) - Conexión: Se establece la conexión con la base de datos mediante
driver.connect() - Definición de esquema: Las tablas se definen usando
defineTable()ycolumn()con tipos y restricciones - Operaciones CRUD:
Repositoryejecuta consultas medianteBaseQueryy sus subclasses (SelectQuery,InsertQuery, etc.) - Serialización de parámetros: Los valores se serializan adecuadamente según el tipo de columna (ej: boolean → 0/1, JSON → stringificado)
- Transacciones: Cuando se usa
transaction(), todas las operaciones se ejecutan dentro de una transacción con rollback automático en caso de error - Migraciones:
MigrationRunnermantiene una tabla interna__jamx_migrationspara rastrear qué migraciones se han ejecutado - Detección de diferencias:
SchemaDiffcompara el esquema definido con la base de datos real para generar migraciones automáticas - 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 instanciaconnect(): Establece la conexióndisconnect(): Cierra la conexiónrepository(table): Obtiene unRepositorypara una tablaraw(sql, params?): Ejecuta SQL crudo
Repository
findAll(): Obtiene todos los registrosfindById(id): Busca por IDfindOne(where): Busca el primer registro que coincidafindMany(where): Busca múltiples registrosinsert(entity): Inserta un nuevo registroupdate(id, data): Actualiza un registro existentedelete(id): Elimina un registropaginate(options): Paginación con metadatos
Migrations
MigrationRunner.initialize(): Inicializa la tabla de migracionesMigrationRunner.run(migrations): Ejecuta migraciones pendientesMigrationRunner.rollback(migrations, steps?): Revierte migracionesMigrationRunner.status(migrations): Obtiene el estado de todas las migraciones
Schema Definition
defineTable(name, columns): Define una tabla con sus columnascolumn(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:
- Extiende
DatabaseDrivere implementa los métodos abstractos (connect,disconnect,query,transaction) - Registra el driver en la configuración del
Database - Implementa métodos de transacción si tu motor los soporta
Ejemplo mínimo de driver:
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:
pnpm test
# o
npm run testLos 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
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 esquemajamx db:migrate: Aplica todas las migraciones pendientesjamx db:rollback: Revierte la última migración ejecutadajamx db:status: Muestra el estado actual de las migracionesjamx 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.
