
Security News
PodRocket Podcast: Inside the Recent npm Supply Chain Attacks
Socket CEO Feross Aboukhadijeh discusses the recent npm supply chain attacks on PodRocket, covering novel attack vectors and how developers can protect themselves.
@dbcube/query-builder
Advanced tools
The DBCube Query Builder is a lightweight, flexible, and fluent library for building queries across multiple database engines, including MySQL, PostgreSQL, SQLite, and MongoDB, using JavaScript/Node.js. Its agnostic design allows you to generate data man
@dbcube/query-builder
is a lightweight, flexible, and fluent Node.js library designed to build queries across multiple database engines, including MySQL, PostgreSQL, SQLite, and MongoDB, using JavaScript/TypeScript.
Its agnostic design allows you to generate data manipulation (DML) and data definition (DDL) operations with a clean, chainable syntax—without sacrificing power or expressiveness. It's designed to work seamlessly in both SQL and NoSQL environments, providing a consistent abstraction layer across different storage technologies while still leveraging the native capabilities of each engine.
Key differentiator: Unlike other query builders that focus on a single database type, DBCube Query Builder provides a unified API that works across SQL and NoSQL databases, making it perfect for modern polyglot architectures.
npm install @dbcube/query-builder
DBCube Query Builder works with the DBCube ecosystem. Make sure you have the proper database configuration through @dbcube/core.
// No explicit configuration needed - works through DBCube core
import { Database } from "@dbcube/query-builder";
The connection is automatically managed through the DBCube core system.
import { Database } from "@dbcube/query-builder";
// Create a database instance
const db = new Database("my_database");
// Get a table reference
const usersTable = db.table("users");
DBCube Query Builder focuses on data operations. Table creation and schema management are handled by other DBCube components.
// Access table for operations
const usersTable = db.table("users");
Use the insert
method to add new records to a table.
// Insert single record
const newUser = await usersTable.insert([
{ name: "Alice", email: "alice@example.com", age: 28 }
]);
// Insert multiple records
const newUsers = await usersTable.insert([
{ name: "Alice", email: "alice@example.com", age: 28 },
{ name: "Bob", email: "bob@example.com", age: 32 },
{ name: "Charlie", email: "charlie@example.com", age: 35 }
]);
console.log(newUsers);
// Returns the inserted records with generated IDs
Use the select
method to specify columns and get()
to retrieve data.
// Select all columns
const allUsers = await usersTable.get();
// Select specific columns
const users = await usersTable
.select(["id", "name", "email"])
.get();
// Select with conditions
const activeUsers = await usersTable
.select(["name", "email"])
.where("status", "=", "active")
.orderBy("created_at", "DESC")
.limit(10)
.get();
console.log(users);
// [{ id: 1, name: 'Alice', email: 'alice@example.com' }, ...]
Use the update
method to modify existing records. Requires WHERE conditions.
// Update single field
await usersTable
.where("id", "=", 1)
.update({ age: 29 });
// Update multiple fields
await usersTable
.where("email", "=", "alice@example.com")
.update({
name: "Alice Smith",
age: 29,
updated_at: new Date()
});
// Update with complex conditions
await usersTable
.where("age", ">", 30)
.where("status", "=", "inactive")
.update({ status: "archived" });
Use the delete
method to remove records. Requires WHERE conditions.
// Delete specific record
await usersTable
.where("id", "=", 2)
.delete();
// Delete with conditions
await usersTable
.where("status", "=", "deleted")
.where("created_at", "<", "2023-01-01")
.delete();
Filter records using the where
method with various operators.
// Basic comparisons
const adultUsers = await usersTable.where("age", ">", 18).get();
const exactMatch = await usersTable.where("name", "=", "Alice").get();
const notEqual = await usersTable.where("status", "!=", "deleted").get();
// String operations
const emailUsers = await usersTable.where("email", "LIKE", "%@gmail.com").get();
console.log(adultUsers);
// [{ id: 1, name: 'Alice', age: 28 }, ...]
Use orWhere
to add OR conditions to your query.
const users = await usersTable
.where("age", ">", 25)
.orWhere("name", "=", "Alice")
.get();
// Complex OR conditions
const premiumUsers = await usersTable
.where("subscription", "=", "premium")
.orWhere("total_purchases", ">", 1000)
.orWhere("member_since", "<", "2020-01-01")
.get();
console.log(users);
// [{ id: 1, name: 'Alice', age: 28 }, ...]
Group conditions using whereGroup
for complex logic.
// (age > 25 OR name = 'Jane') AND status = 'active'
const users = await usersTable
.whereGroup((query) => {
query.where("age", ">", 25).orWhere("name", "=", "Jane");
})
.where("status", "=", "active")
.get();
// Nested groups
const complexQuery = await usersTable
.whereGroup((query) => {
query.where("country", "=", "US").orWhere("country", "=", "CA");
})
.where("active", "=", true)
.whereGroup((query) => {
query.where("age", ">=", 21).orWhere("verified", "=", true);
})
.get();
Search for values within a range using whereBetween
.
// Age between 25 and 35
const users = await usersTable.whereBetween("age", [25, 35]).get();
// Date ranges
const recentUsers = await usersTable
.whereBetween("created_at", ["2024-01-01", "2024-12-31"])
.get();
console.log(users);
// [{ id: 1, name: 'Alice', age: 28 }, { id: 2, name: 'Bob', age: 32 }]
Search for values that match a set of values using whereIn
.
// Specific IDs
const users = await usersTable.whereIn("id", [1, 3, 5]).get();
// Multiple statuses
const filteredUsers = await usersTable
.whereIn("status", ["active", "pending", "verified"])
.get();
// String values
const emailDomains = await usersTable
.whereIn("email_domain", ["gmail.com", "yahoo.com", "hotmail.com"])
.get();
console.log(users);
// [{ id: 1, name: 'Alice', age: 28 }, { id: 3, name: 'Charlie', age: 35 }]
Search for null or non-null values using whereNull
and whereNotNull
.
// Users without email
const usersWithoutEmail = await usersTable.whereNull("email").get();
// Users with email
const usersWithEmail = await usersTable.whereNotNull("email").get();
// Combine with other conditions
const incompleteProfiles = await usersTable
.whereNull("phone")
.orWhere("avatar", "IS NULL")
.whereNotNull("email")
.get();
Join tables using the join
method for INNER JOIN.
// Basic INNER JOIN
const usersWithOrders = await usersTable
.join("orders", "users.id", "=", "orders.user_id")
.select(["users.name", "orders.order_id", "orders.total"])
.get();
// Multiple JOINs
const detailedOrders = await usersTable
.join("orders", "users.id", "=", "orders.user_id")
.join("order_items", "orders.id", "=", "order_items.order_id")
.join("products", "order_items.product_id", "=", "products.id")
.select(["users.name", "orders.order_id", "products.name AS product_name"])
.get();
console.log(usersWithOrders);
// [{ name: 'Alice', order_id: 101, total: 150.00 }, ...]
Perform a left join using the leftJoin
method.
// Include users even if they have no orders
const usersWithOrders = await usersTable
.leftJoin("orders", "users.id", "=", "orders.user_id")
.select(["users.name", "orders.order_id"])
.get();
// Left join with aggregation
const usersOrderCount = await usersTable
.leftJoin("orders", "users.id", "=", "orders.user_id")
.select(["users.name"])
.count("orders.id")
.groupBy("users.id")
.get();
console.log(usersWithOrders);
// [{ name: 'Alice', order_id: 101 }, { name: 'Bob', order_id: null }, ...]
Perform a right join using the rightJoin
method.
// Include orders even if user data is missing
const ordersWithUsers = await usersTable
.rightJoin("orders", "users.id", "=", "orders.user_id")
.select(["users.name", "orders.order_id"])
.get();
console.log(ordersWithUsers);
// [{ name: 'Alice', order_id: 101 }, { name: null, order_id: 102 }, ...]
Sort results using the orderBy
method.
// Single column sorting
const sortedUsers = await usersTable
.orderBy("name", "ASC")
.get();
// Multiple column sorting
const complexSort = await usersTable
.orderBy("country", "ASC")
.orderBy("age", "DESC")
.orderBy("name", "ASC")
.get();
// Sort with conditions
const recentActiveUsers = await usersTable
.where("status", "=", "active")
.orderBy("last_login", "DESC")
.limit(20)
.get();
console.log(sortedUsers);
// [{ id: 1, name: 'Alice', ... }, { id: 2, name: 'Bob', ... }]
Limit the number of results and implement pagination using limit
and page
.
// Simple limit
const firstTenUsers = await usersTable.limit(10).get();
// Pagination
const firstPage = await usersTable.limit(5).page(1).get();
const secondPage = await usersTable.limit(5).page(2).get();
// Pagination with sorting
const paginatedUsers = await usersTable
.orderBy("created_at", "DESC")
.limit(10)
.page(3) // Skip first 20 records (pages 1-2)
.get();
console.log(firstPage); // Records 1-5
console.log(secondPage); // Records 6-10
Group results using the groupBy
method.
// Simple grouping
const usersByAge = await usersTable
.select(["age"])
.count("*")
.groupBy("age")
.get();
// Multiple grouping columns
const usersByCountryAndAge = await usersTable
.select(["country", "age"])
.count("*")
.groupBy("country")
.groupBy("age")
.get();
console.log(usersByAge);
// [{ age: 28, count: 2 }, { age: 32, count: 1 }]
Retrieve unique records using the distinct
method.
// Distinct values
const uniqueCountries = await usersTable
.distinct()
.select(["country"])
.get();
// Distinct with conditions
const activeUserCountries = await usersTable
.distinct()
.select(["country"])
.where("status", "=", "active")
.get();
console.log(uniqueCountries);
// [{ country: 'USA' }, { country: 'Canada' }, { country: 'UK' }]
Count the number of records.
// Count all records
const totalUsers = await usersTable.count().first();
console.log(totalUsers); // { count: 150 }
// Count specific column
const usersWithEmail = await usersTable.count("email").first();
// Count with conditions
const activeUsers = await usersTable
.where("status", "=", "active")
.count()
.first();
Calculate the sum of a column.
// Sum of ages
const totalAge = await usersTable.sum("age").first();
console.log(totalAge); // { sum: 4250 }
// Sum with conditions
const premiumRevenue = await usersTable
.join("orders", "users.id", "=", "orders.user_id")
.where("users.subscription", "=", "premium")
.sum("orders.total")
.first();
Calculate the average of a column.
// Average age
const averageAge = await usersTable.avg("age").first();
console.log(averageAge); // { avg: 28.33 }
// Average with grouping
const avgAgeByCountry = await usersTable
.select(["country"])
.avg("age")
.groupBy("country")
.get();
Find the maximum value in a column.
// Oldest user
const maxAge = await usersTable.max("age").first();
console.log(maxAge); // { max: 65 }
// Most recent registration
const latestUser = await usersTable.max("created_at").first();
Find the minimum value in a column.
// Youngest user
const minAge = await usersTable.min("age").first();
console.log(minAge); // { min: 18 }
// Earliest registration
const firstUser = await usersTable.min("created_at").first();
Find a record by a specific column value (defaults to 'id').
// Find by ID (default)
const user = await usersTable.find(1);
console.log(user);
// { id: 1, name: 'Alice', email: 'alice@example.com', age: 28 }
// Find by specific column
const userByEmail = await usersTable.find("alice@example.com", "email");
// Find returns null if not found
const nonExistent = await usersTable.find(999);
console.log(nonExistent); // null
Get only the first record that meets the conditions.
// First user matching condition
const firstUser = await usersTable
.where("age", ">", 25)
.orderBy("created_at", "ASC")
.first();
// First user in general
const oldestAccount = await usersTable
.orderBy("created_at", "ASC")
.first();
console.log(firstUser);
// { id: 1, name: 'Alice', age: 28, ... } or null if no match
DBCube Query Builder supports computed fields and triggers for advanced data processing.
// Enable computed fields (processed automatically)
await db.useComputes();
// Enable triggers
await db.useTriggers();
// Triggers and computed fields are configured through other DBCube components
For complex queries that require raw SQL, use the underlying engine.
// Access the underlying engine for raw queries
// (Implementation depends on your specific DBCube core setup)
// Note: Raw SQL queries bypass the query builder's abstraction layer
// and are database-specific
The library provides comprehensive error handling with descriptive messages.
try {
// This will throw an error - UPDATE requires WHERE conditions
await usersTable.update({ name: "Updated" });
} catch (error) {
console.error(error.message);
// "You must specify at least one WHERE condition to perform an update."
}
try {
// This will throw an error - invalid data format
await usersTable.insert("invalid data");
} catch (error) {
console.error(error.message);
// "The insert method requires an array of objects with key-value pairs."
}
// Connection and database errors are also properly handled
try {
const result = await usersTable.get();
} catch (error) {
// Database connection or query execution errors
console.error("Database error:", error);
}
new Database(name: string)
Creates a new database connection instance.
const db = new Database("my_database");
table(tableName: string): Table
Returns a Table instance for building queries on the specified table.
const usersTable = db.table("users");
useComputes(): Promise<void>
Enables computed fields processing for the database.
await db.useComputes();
useTriggers(): Promise<void>
Enables trigger processing for the database.
await db.useTriggers();
connect(): Promise<void>
Establishes database connection (handled automatically).
disconnect(): Promise<void>
Closes database connection.
select(fields?: string[]): Table
Specify columns to select.
usersTable.select(["id", "name", "email"]);
where(column, operator, value): Table
Add a WHERE condition.
usersTable.where("age", ">", 25);
usersTable.where("email", "IS NOT NULL");
orWhere(column, operator, value): Table
Add an OR WHERE condition.
usersTable.orWhere("name", "=", "Jane");
whereGroup(callback): Table
Grouped WHERE conditions.
usersTable.whereGroup((query) => {
query.where("age", ">", 25).orWhere("name", "=", "Jane");
});
whereBetween(column, [min, max]): Table
WHERE BETWEEN condition.
usersTable.whereBetween("age", [25, 35]);
whereIn(column, values): Table
WHERE IN condition.
usersTable.whereIn("id", [1, 3, 5]);
whereNull(column): Table
/ whereNotNull(column): Table
NULL checks.
usersTable.whereNull("deleted_at");
usersTable.whereNotNull("email");
join(table, column1, operator, column2): Table
INNER JOIN.
usersTable.join("orders", "users.id", "=", "orders.user_id");
leftJoin(table, column1, operator, column2): Table
LEFT JOIN.
rightJoin(table, column1, operator, column2): Table
RIGHT JOIN.
orderBy(column, direction): Table
ORDER BY clause.
usersTable.orderBy("name", "ASC");
groupBy(column): Table
GROUP BY clause.
distinct(): Table
DISTINCT clause.
limit(number): Table
LIMIT clause.
page(number): Table
Pagination (requires limit).
count(column?): Table
COUNT aggregation.
sum(column): Table
SUM aggregation.
avg(column): Table
AVG aggregation.
max(column): Table
MAX aggregation.
min(column): Table
MIN aggregation.
get(): Promise<DatabaseRecord[]>
Execute and return all matching rows.
first(): Promise<DatabaseRecord | null>
Execute and return the first matching row.
find(value, column?): Promise<DatabaseRecord | null>
Find a row by column value (default: id).
insert(data): Promise<DatabaseRecord[]>
Insert one or more rows.
update(data): Promise<any>
Update rows matching the conditions.
delete(): Promise<any>
Delete rows matching the conditions.
DBCube Query Builder works with multiple database engines:
// MySQL
const mysqlDb = new Database("mysql_database");
// PostgreSQL
const postgresDb = new Database("postgres_database");
// SQLite
const sqliteDb = new Database("sqlite_database");
// MongoDB
const mongoDb = new Database("mongo_database");
// Same API works across all databases
const users = await mysqlDb.table("users").get();
const posts = await postgresDb.table("posts").get();
const logs = await sqliteDb.table("logs").get();
const analytics = await mongoDb.table("analytics").get();
// Complex business query
const monthlyReport = await db.table("orders")
.join("users", "orders.user_id", "=", "users.id")
.join("order_items", "orders.id", "=", "order_items.order_id")
.join("products", "order_items.product_id", "=", "products.id")
.select([
"users.country",
"products.category"
])
.sum("order_items.quantity * order_items.price")
.where("orders.status", "=", "completed")
.whereBetween("orders.created_at", ["2024-01-01", "2024-01-31"])
.groupBy("users.country")
.groupBy("products.category")
.orderBy("sum", "DESC")
.limit(10)
.get();
All query builder methods return the Table instance, enabling fluent method chaining:
const result = await db
.table("users")
.select(["name", "email", "country"])
.where("active", "=", true)
.whereNotNull("email_verified_at")
.whereGroup((query) => {
query.where("subscription", "=", "premium")
.orWhere("total_orders", ">", 10);
})
.join("user_profiles", "users.id", "=", "user_profiles.user_id")
.orderBy("users.created_at", "DESC")
.limit(50)
.page(1)
.get();
This project is licensed under the MIT License - see the LICENSE file for details.
@dbcube/query-builder
es una biblioteca de Node.js ligera, flexible y fluida diseñada para construir consultas a través de múltiples motores de base de datos, incluyendo MySQL, PostgreSQL, SQLite y MongoDB, usando JavaScript/TypeScript.
Su diseño agnóstico te permite generar operaciones de manipulación de datos (DML) y definición de datos (DDL) con una sintaxis limpia y encadenable, sin sacrificar potencia o expresividad. Está diseñada para trabajar perfectamente en entornos SQL y NoSQL, proporcionando una capa de abstracción consistente a través de diferentes tecnologías de almacenamiento mientras aprovecha las capacidades nativas de cada motor.
Diferenciador clave: A diferencia de otros constructores de consultas que se enfocan en un solo tipo de base de datos, DBCube Query Builder proporciona una API unificada que funciona a través de bases de datos SQL y NoSQL, haciéndola perfecta para arquitecturas políglotas modernas.
npm install @dbcube/query-builder
DBCube Query Builder funciona con el ecosistema DBCube. Asegúrate de tener la configuración adecuada de base de datos a través de @dbcube/core.
// No se necesita configuración explícita - funciona a través de DBCube core
import { Database } from "@dbcube/query-builder";
La conexión se gestiona automáticamente a través del sistema core de DBCube.
import { Database } from "@dbcube/query-builder";
// Crear una instancia de base de datos
const db = new Database("mi_base_de_datos");
// Obtener una referencia de tabla
const tablaUsuarios = db.table("usuarios");
DBCube Query Builder se enfoca en operaciones de datos. La creación de tablas y gestión de esquemas se maneja por otros componentes de DBCube.
// Acceder a tabla para operaciones
const tablaUsuarios = db.table("usuarios");
Utiliza el método insert
para añadir nuevos registros a una tabla.
// Insertar un solo registro
const nuevoUsuario = await tablaUsuarios.insert([
{ nombre: "Alicia", email: "alicia@ejemplo.com", edad: 28 }
]);
// Insertar múltiples registros
const nuevosUsuarios = await tablaUsuarios.insert([
{ nombre: "Alicia", email: "alicia@ejemplo.com", edad: 28 },
{ nombre: "Roberto", email: "roberto@ejemplo.com", edad: 32 },
{ nombre: "Carlos", email: "carlos@ejemplo.com", edad: 35 }
]);
console.log(nuevosUsuarios);
// Devuelve los registros insertados con IDs generados
Utiliza el método select
para especificar columnas y get()
para recuperar datos.
// Seleccionar todas las columnas
const todosUsuarios = await tablaUsuarios.get();
// Seleccionar columnas específicas
const usuarios = await tablaUsuarios
.select(["id", "nombre", "email"])
.get();
// Seleccionar con condiciones
const usuariosActivos = await tablaUsuarios
.select(["nombre", "email"])
.where("estado", "=", "activo")
.orderBy("fecha_creacion", "DESC")
.limit(10)
.get();
console.log(usuarios);
// [{ id: 1, nombre: 'Alicia', email: 'alicia@ejemplo.com' }, ...]
Utiliza el método update
para modificar registros existentes. Requiere condiciones WHERE.
// Actualizar un campo
await tablaUsuarios
.where("id", "=", 1)
.update({ edad: 29 });
// Actualizar múltiples campos
await tablaUsuarios
.where("email", "=", "alicia@ejemplo.com")
.update({
nombre: "Alicia García",
edad: 29,
actualizado_en: new Date()
});
// Actualizar con condiciones complejas
await tablaUsuarios
.where("edad", ">", 30)
.where("estado", "=", "inactivo")
.update({ estado: "archivado" });
Utiliza el método delete
para eliminar registros. Requiere condiciones WHERE.
// Eliminar registro específico
await tablaUsuarios
.where("id", "=", 2)
.delete();
// Eliminar con condiciones
await tablaUsuarios
.where("estado", "=", "eliminado")
.where("fecha_creacion", "<", "2023-01-01")
.delete();
Filtra registros utilizando el método where
con varios operadores.
// Comparaciones básicas
const usuariosAdultos = await tablaUsuarios.where("edad", ">", 18).get();
const coincidenciaExacta = await tablaUsuarios.where("nombre", "=", "Alicia").get();
const noIgual = await tablaUsuarios.where("estado", "!=", "eliminado").get();
// Operaciones con strings
const usuariosGmail = await tablaUsuarios.where("email", "LIKE", "%@gmail.com").get();
console.log(usuariosAdultos);
// [{ id: 1, nombre: 'Alicia', edad: 28 }, ...]
Utiliza orWhere
para añadir condiciones OR a tu consulta.
const usuarios = await tablaUsuarios
.where("edad", ">", 25)
.orWhere("nombre", "=", "Alicia")
.get();
// Condiciones OR complejas
const usuariosPremium = await tablaUsuarios
.where("suscripcion", "=", "premium")
.orWhere("compras_totales", ">", 1000)
.orWhere("miembro_desde", "<", "2020-01-01")
.get();
console.log(usuarios);
// [{ id: 1, nombre: 'Alicia', edad: 28 }, ...]
Agrupa condiciones utilizando whereGroup
para lógica compleja.
// (edad > 25 OR nombre = 'Juana') AND estado = 'activo'
const usuarios = await tablaUsuarios
.whereGroup((query) => {
query.where("edad", ">", 25).orWhere("nombre", "=", "Juana");
})
.where("estado", "=", "activo")
.get();
// Grupos anidados
const consultaCompleja = await tablaUsuarios
.whereGroup((query) => {
query.where("pais", "=", "ES").orWhere("pais", "=", "MX");
})
.where("activo", "=", true)
.whereGroup((query) => {
query.where("edad", ">=", 21).orWhere("verificado", "=", true);
})
.get();
Busca valores dentro de un rango utilizando whereBetween
.
// Edad entre 25 y 35
const usuarios = await tablaUsuarios.whereBetween("edad", [25, 35]).get();
// Rangos de fechas
const usuariosRecientes = await tablaUsuarios
.whereBetween("fecha_creacion", ["2024-01-01", "2024-12-31"])
.get();
console.log(usuarios);
// [{ id: 1, nombre: 'Alicia', edad: 28 }, { id: 2, nombre: 'Roberto', edad: 32 }]
Busca valores que coincidan con un conjunto de valores utilizando whereIn
.
// IDs específicos
const usuarios = await tablaUsuarios.whereIn("id", [1, 3, 5]).get();
// Múltiples estados
const usuariosFiltrados = await tablaUsuarios
.whereIn("estado", ["activo", "pendiente", "verificado"])
.get();
// Valores string
const dominiosEmail = await tablaUsuarios
.whereIn("dominio_email", ["gmail.com", "yahoo.com", "hotmail.com"])
.get();
console.log(usuarios);
// [{ id: 1, nombre: 'Alicia', edad: 28 }, { id: 3, nombre: 'Carlos', edad: 35 }]
Busca valores nulos o no nulos utilizando whereNull
y whereNotNull
.
// Usuarios sin email
const usuariosSinEmail = await tablaUsuarios.whereNull("email").get();
// Usuarios con email
const usuariosConEmail = await tablaUsuarios.whereNotNull("email").get();
// Combinar con otras condiciones
const perfilesIncompletos = await tablaUsuarios
.whereNull("telefono")
.orWhere("avatar", "IS NULL")
.whereNotNull("email")
.get();
Une tablas utilizando el método join
para INNER JOIN.
// INNER JOIN básico
const usuariosConPedidos = await tablaUsuarios
.join("pedidos", "usuarios.id", "=", "pedidos.usuario_id")
.select(["usuarios.nombre", "pedidos.pedido_id", "pedidos.total"])
.get();
// Múltiples JOINs
const pedidosDetallados = await tablaUsuarios
.join("pedidos", "usuarios.id", "=", "pedidos.usuario_id")
.join("items_pedido", "pedidos.id", "=", "items_pedido.pedido_id")
.join("productos", "items_pedido.producto_id", "=", "productos.id")
.select(["usuarios.nombre", "pedidos.pedido_id", "productos.nombre AS nombre_producto"])
.get();
console.log(usuariosConPedidos);
// [{ nombre: 'Alicia', pedido_id: 101, total: 150.00 }, ...]
Realiza un left join utilizando el método leftJoin
.
// Incluir usuarios aunque no tengan pedidos
const usuariosConPedidos = await tablaUsuarios
.leftJoin("pedidos", "usuarios.id", "=", "pedidos.usuario_id")
.select(["usuarios.nombre", "pedidos.pedido_id"])
.get();
// Left join con agregación
const contadorPedidosUsuarios = await tablaUsuarios
.leftJoin("pedidos", "usuarios.id", "=", "pedidos.usuario_id")
.select(["usuarios.nombre"])
.count("pedidos.id")
.groupBy("usuarios.id")
.get();
console.log(usuariosConPedidos);
// [{ nombre: 'Alicia', pedido_id: 101 }, { nombre: 'Roberto', pedido_id: null }, ...]
Realiza un right join utilizando el método rightJoin
.
// Incluir pedidos aunque falten datos del usuario
const pedidosConUsuarios = await tablaUsuarios
.rightJoin("pedidos", "usuarios.id", "=", "pedidos.usuario_id")
.select(["usuarios.nombre", "pedidos.pedido_id"])
.get();
console.log(pedidosConUsuarios);
// [{ nombre: 'Alicia', pedido_id: 101 }, { nombre: null, pedido_id: 102 }, ...]
Ordena resultados utilizando el método orderBy
.
// Ordenamiento de una columna
const usuariosOrdenados = await tablaUsuarios
.orderBy("nombre", "ASC")
.get();
// Ordenamiento de múltiples columnas
const ordenComplejo = await tablaUsuarios
.orderBy("pais", "ASC")
.orderBy("edad", "DESC")
.orderBy("nombre", "ASC")
.get();
// Ordenar con condiciones
const usuariosActivosRecientes = await tablaUsuarios
.where("estado", "=", "activo")
.orderBy("ultimo_acceso", "DESC")
.limit(20)
.get();
console.log(usuariosOrdenados);
// [{ id: 1, nombre: 'Alicia', ... }, { id: 2, nombre: 'Roberto', ... }]
Limita el número de resultados e implementa paginación utilizando limit
y page
.
// Límite simple
const primerosDiezUsuarios = await tablaUsuarios.limit(10).get();
// Paginación
const primeraPagina = await tablaUsuarios.limit(5).page(1).get();
const segundaPagina = await tablaUsuarios.limit(5).page(2).get();
// Paginación con ordenamiento
const usuariosPaginados = await tablaUsuarios
.orderBy("fecha_creacion", "DESC")
.limit(10)
.page(3) // Omitir los primeros 20 registros (páginas 1-2)
.get();
console.log(primeraPagina); // Registros 1-5
console.log(segundaPagina); // Registros 6-10
Agrupa resultados utilizando el método groupBy
.
// Agrupamiento simple
const usuariosPorEdad = await tablaUsuarios
.select(["edad"])
.count("*")
.groupBy("edad")
.get();
// Múltiples columnas de agrupamiento
const usuariosPorPaisYEdad = await tablaUsuarios
.select(["pais", "edad"])
.count("*")
.groupBy("pais")
.groupBy("edad")
.get();
console.log(usuariosPorEdad);
// [{ edad: 28, count: 2 }, { edad: 32, count: 1 }]
Recupera registros únicos utilizando el método distinct
.
// Valores únicos
const paisesUnicos = await tablaUsuarios
.distinct()
.select(["pais"])
.get();
// Distinct con condiciones
const paisesUsuariosActivos = await tablaUsuarios
.distinct()
.select(["pais"])
.where("estado", "=", "activo")
.get();
console.log(paisesUnicos);
// [{ pais: 'España' }, { pais: 'México' }, { pais: 'Argentina' }]
Cuenta el número de registros.
// Contar todos los registros
const totalUsuarios = await tablaUsuarios.count().first();
console.log(totalUsuarios); // { count: 150 }
// Contar columna específica
const usuariosConEmail = await tablaUsuarios.count("email").first();
// Contar con condiciones
const usuariosActivos = await tablaUsuarios
.where("estado", "=", "activo")
.count()
.first();
Calcula la suma de una columna.
// Suma de edades
const edadTotal = await tablaUsuarios.sum("edad").first();
console.log(edadTotal); // { sum: 4250 }
// Suma con condiciones
const ingresosPremium = await tablaUsuarios
.join("pedidos", "usuarios.id", "=", "pedidos.usuario_id")
.where("usuarios.suscripcion", "=", "premium")
.sum("pedidos.total")
.first();
Calcula el promedio de una columna.
// Edad promedio
const edadPromedio = await tablaUsuarios.avg("edad").first();
console.log(edadPromedio); // { avg: 28.33 }
// Promedio con agrupamiento
const edadPromedioPorPais = await tablaUsuarios
.select(["pais"])
.avg("edad")
.groupBy("pais")
.get();
Encuentra el valor máximo en una columna.
// Usuario más viejo
const edadMaxima = await tablaUsuarios.max("edad").first();
console.log(edadMaxima); // { max: 65 }
// Registro más reciente
const usuarioMasReciente = await tablaUsuarios.max("fecha_creacion").first();
Encuentra el valor mínimo en una columna.
// Usuario más joven
const edadMinima = await tablaUsuarios.min("edad").first();
console.log(edadMinima); // { min: 18 }
// Primer registro
const primerUsuario = await tablaUsuarios.min("fecha_creacion").first();
Encuentra un registro por un valor específico de columna (por defecto 'id').
// Buscar por ID (por defecto)
const usuario = await tablaUsuarios.find(1);
console.log(usuario);
// { id: 1, nombre: 'Alicia', email: 'alicia@ejemplo.com', edad: 28 }
// Buscar por columna específica
const usuarioPorEmail = await tablaUsuarios.find("alicia@ejemplo.com", "email");
// Find devuelve null si no se encuentra
const noExistente = await tablaUsuarios.find(999);
console.log(noExistente); // null
Obtiene solo el primer registro que cumple con las condiciones.
// Primer usuario que cumple la condición
const primerUsuario = await tablaUsuarios
.where("edad", ">", 25)
.orderBy("fecha_creacion", "ASC")
.first();
// Primer usuario en general
const cuentaMasAntigua = await tablaUsuarios
.orderBy("fecha_creacion", "ASC")
.first();
console.log(primerUsuario);
// { id: 1, nombre: 'Alicia', edad: 28, ... } o null si no hay coincidencia
DBCube Query Builder soporta campos calculados y triggers para procesamiento avanzado de datos.
// Habilitar campos calculados (procesados automáticamente)
await db.useComputes();
// Habilitar triggers
await db.useTriggers();
// Los triggers y campos calculados se configuran a través de otros componentes DBCube
Para consultas complejas que requieren SQL crudo, utiliza el motor subyacente.
// Acceder al motor subyacente para consultas crudas
// (La implementación depende de tu configuración específica de DBCube core)
// Nota: Las consultas SQL crudas evitan la capa de abstracción del query builder
// y son específicas de la base de datos
La biblioteca proporciona manejo comprehensivo de errores con mensajes descriptivos.
try {
// Esto arrojará un error - UPDATE requiere condiciones WHERE
await tablaUsuarios.update({ nombre: "Actualizado" });
} catch (error) {
console.error(error.message);
// "Debes especificar al menos una condición WHERE para realizar una actualización."
}
try {
// Esto arrojará un error - formato de datos inválido
await tablaUsuarios.insert("datos inválidos");
} catch (error) {
console.error(error.message);
// "El método insert requiere un array de objetos con pares clave-valor."
}
// Los errores de conexión y base de datos también se manejan apropiadamente
try {
const resultado = await tablaUsuarios.get();
} catch (error) {
// Errores de conexión a base de datos o ejecución de consultas
console.error("Error de base de datos:", error);
}
new Database(name: string)
Crea una nueva instancia de conexión a base de datos.
const db = new Database("mi_base_de_datos");
table(tableName: string): Table
Devuelve una instancia Table para construir consultas en la tabla especificada.
const tablaUsuarios = db.table("usuarios");
useComputes(): Promise<void>
Habilita el procesamiento de campos calculados para la base de datos.
await db.useComputes();
useTriggers(): Promise<void>
Habilita el procesamiento de triggers para la base de datos.
await db.useTriggers();
connect(): Promise<void>
Establece conexión a base de datos (manejado automáticamente).
disconnect(): Promise<void>
Cierra conexión a base de datos.
Los métodos de la clase Table siguen la misma API que se documentó en la sección en inglés, con la funcionalidad idéntica.
DBCube Query Builder funciona con múltiples motores de base de datos:
// MySQL
const mysqlDb = new Database("base_datos_mysql");
// PostgreSQL
const postgresDb = new Database("base_datos_postgres");
// SQLite
const sqliteDb = new Database("base_datos_sqlite");
// MongoDB
const mongoDb = new Database("base_datos_mongo");
// La misma API funciona a través de todas las bases de datos
const usuarios = await mysqlDb.table("usuarios").get();
const posts = await postgresDb.table("posts").get();
const logs = await sqliteDb.table("logs").get();
const analiticas = await mongoDb.table("analiticas").get();
// Consulta de negocio compleja
const reporteMensual = await db.table("pedidos")
.join("usuarios", "pedidos.usuario_id", "=", "usuarios.id")
.join("items_pedido", "pedidos.id", "=", "items_pedido.pedido_id")
.join("productos", "items_pedido.producto_id", "=", "productos.id")
.select([
"usuarios.pais",
"productos.categoria"
])
.sum("items_pedido.cantidad * items_pedido.precio")
.where("pedidos.estado", "=", "completado")
.whereBetween("pedidos.fecha_creacion", ["2024-01-01", "2024-01-31"])
.groupBy("usuarios.pais")
.groupBy("productos.categoria")
.orderBy("sum", "DESC")
.limit(10)
.get();
Todos los métodos del query builder devuelven la instancia Table, habilitando el encadenamiento fluido de métodos:
const resultado = await db
.table("usuarios")
.select(["nombre", "email", "pais"])
.where("activo", "=", true)
.whereNotNull("email_verificado_en")
.whereGroup((query) => {
query.where("suscripcion", "=", "premium")
.orWhere("pedidos_totales", ">", 10);
})
.join("perfiles_usuario", "usuarios.id", "=", "perfiles_usuario.usuario_id")
.orderBy("usuarios.fecha_creacion", "DESC")
.limit(50)
.page(1)
.get();
Este proyecto está licenciado bajo la Licencia MIT - consulta el archivo LICENSE para más detalles.
FAQs
The DBCube Query Builder is a lightweight, flexible, and fluent library for building queries across multiple database engines, including MySQL, PostgreSQL, SQLite, and MongoDB, using JavaScript/Node.js. Its agnostic design allows you to generate data man
We found that @dbcube/query-builder demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Socket CEO Feross Aboukhadijeh discusses the recent npm supply chain attacks on PodRocket, covering novel attack vectors and how developers can protect themselves.
Security News
Maintainers back GitHub’s npm security overhaul but raise concerns about CI/CD workflows, enterprise support, and token management.
Product
Socket Firewall is a free tool that blocks malicious packages at install time, giving developers proactive protection against rising supply chain attacks.