@starbemtech/star-db-query-builder
Version:
A query builder to be used with mysql or postgres
375 lines (374 loc) • 13.5 kB
TypeScript
import { QueryParams, RawQueryParams } from './types';
import { ITransactionClient } from '../db/IDatabaseClient';
/**
* Finds the first record in the specified table
*
* This function retrieves the first record from the specified table based on the provided
* query parameters. It constructs the SQL query, executes it, and returns the result.
*
* @template T - The type of the record to be returned
* @param params - Query parameters including table name, database client, select fields, where conditions, group by, order by, and limit
* @returns Promise<T | null> - The first record or null if no record is found
*
* @throws {Error} When table name is not provided
* @throws {Error} When database client is not provided
*
* @example
* const firstRecord = await findFirst({
* tableName: 'users',
* dbClient: dbClient,
* select: ['id', 'name', 'email'],
* where: { status: 'active' },
* groupBy: ['status'],
* orderBy: [{ field: 'created_at', direction: 'DESC' }],
* })
*
* @example
* const firstRecord = await findFirst({
* tableName: 'users',
* dbClient: dbClient,
* select: ['id', 'name', 'email'],
* where: { status: 'active' },
* groupBy: ['status'],
* orderBy: [{ field: 'created_at', direction: 'DESC' }],
* })
*/
export declare const findFirst: <T>({ tableName, dbClient, select, where, groupBy, orderBy, }: QueryParams<T>) => Promise<T | null>;
/**
* Finds multiple records in the specified table
*
* This function retrieves multiple records from the specified table based on the provided
* query parameters. It constructs the SQL query, executes it, and returns the result.
*
* @template T - The type of the records to be returned
* @param params - Query parameters including table name, database client, select fields, where conditions, group by, order by, limit, and offset
* @returns Promise<T[]> - The records found in the table
*
* @throws {Error} When table name is not provided
* @throws {Error} When database client is not provided
*
* @example
* const records = await findMany({
* tableName: 'users',
* dbClient: dbClient,
* select: ['id', 'name', 'email'],
* where: { status: 'active' },
* groupBy: ['status'],
* orderBy: [{ field: 'created_at', direction: 'DESC' }],
* limit: 10,
* offset: 0,
* unaccent: true,
* })
*/
export declare const findMany: <T>({ tableName, dbClient, select, where, groupBy, orderBy, limit, offset, unaccent, }: QueryParams<T>) => Promise<T[]>;
/**
* Inserts a new record into the specified table
*
* This function inserts a new record into the specified table based on the provided
* query parameters. It constructs the SQL query, executes it, and returns the result.
*
* @template P - The type of the data to be inserted
* @template R - The type of the record to be returned
* @param params - Query parameters including table name, database client, data to be inserted, and optional returning fields
* @returns Promise<R> - The inserted record
*
* @throws {Error} When table name is not provided
* @throws {Error} When database client is not provided
* @throws {Error} When data object is not provided
*
* @example
* const insertedRecord = await insert({
* tableName: 'users',
* dbClient: dbClient,
* data: { name: 'John Doe', email: 'john.doe@example.com' },
* returning: ['id', 'name', 'email'],
* })
*/
export declare const insert: <P, R>({ tableName, dbClient, data, returning, }: QueryParams<R> & {
data: P;
returning?: string[];
}) => Promise<R>;
/**
* Inserts multiple records into the specified table
*
* This function inserts multiple records into the specified table based on the provided
* query parameters. It constructs the SQL query, executes it, and returns the result.
*
* @template P - The type of the data to be inserted
* @template R - The type of the record to be returned
* @param params - Query parameters including table name, database client, data to be inserted, and optional returning fields
* @returns Promise<R[]> - The inserted records
*
* @throws {Error} When table name is not provided
* @throws {Error} When database client is not provided
* @throws {Error} When data array is not provided or empty
*
* @example
* const insertedRecords = await insertMany({
* tableName: 'users',
* dbClient: dbClient,
* data: [{ name: 'John Doe', email: 'john.doe@example.com' }, { name: 'Jane Doe', email: 'jane.doe@example.com' }],
* returning: ['id', 'name', 'email'],
* })
*/
export declare const insertMany: <P, R>({ tableName, dbClient, data, returning, }: QueryParams<R> & {
data: P[];
returning?: string[];
}) => Promise<R[]>;
/**
* Updates a record in the specified table
*
* This function updates a record in the specified table based on the provided
* query parameters. It constructs the SQL query, executes it, and returns the result.
*
* @template P - The type of the data to be updated
* @template R - The type of the record to be returned
* @param params - Query parameters including table name, database client, ID of the record to be updated, data to be updated, and optional returning fields
* @returns Promise<R | void> - The updated record or void if no record is found
*
* @throws {Error} When table name is not provided
* @throws {Error} When database client is not provided
* @throws {Error} When ID is not provided
*
* @example
* const updatedRecord = await update({
* tableName: 'users',
* dbClient: dbClient,
* id: '123',
* data: { name: 'John Doe', email: 'john.doe@example.com' },
* returning: ['id', 'name', 'email'],
* })
*/
export declare const update: <P, R>({ tableName, dbClient, id, data, returning, }: QueryParams<R> & {
data: P;
returning?: string[];
}) => Promise<R | void>;
/**
* Updates multiple records in the specified table
*
* This function updates multiple records in the specified table based on the provided
* query parameters. It constructs the SQL query, executes it, and returns the result.
*
* @template P - The type of the data to be updated
* @template R - The type of the record to be returned
* @param params - Query parameters including table name, database client, data to be updated, where conditions, and optional returning fields
* @returns Promise<R[]> - The updated records
*
* @throws {Error} When table name is not provided
* @throws {Error} When database client is not provided
* @throws {Error} When data object is not provided
* @throws {Error} When where condition is not provided
*
* @example
* const updatedRecords = await updateMany({
* tableName: 'users',
* dbClient: dbClient,
* data: { name: 'John Doe', email: 'john.doe@example.com' },
* where: { status: 'active' },
* returning: ['id', 'name', 'email'],
* })
*/
export declare const updateMany: <P, R>({ tableName, dbClient, data, where, returning, }: QueryParams<R> & {
data: P;
returning?: string[];
}) => Promise<R[]>;
/**
* Deletes a record from the specified table
*
* This function deletes a record from the specified table based on the provided
* query parameters. It constructs the SQL query, executes it, and returns the result.
*
* @template T - The type of the record to be deleted
* @param params - Query parameters including table name, database client, ID of the record to be deleted, and optional permanently flag
* @returns Promise<void> - Resolves when the record is deleted
*
* @throws {Error} When table name is not provided
* @throws {Error} When database client is not provided
* @throws {Error} When ID is not provided
*
* @example
* await deleteOne({
* tableName: 'users',
* dbClient: dbClient,
* id: '123',
* permanently: true,
* })
*/
export declare const deleteOne: <T>({ tableName, dbClient, id, permanently, }: QueryParams<T> & {
permanently?: boolean;
}) => Promise<void>;
/**
* Deletes multiple records from the specified table
*
* This function deletes multiple records from the specified table based on the provided
* query parameters. It constructs the SQL query, executes it, and returns the result.
*
* @template T - The type of the record to be deleted
* @param params - Query parameters including table name, database client, IDs of the records to be deleted, field to be used for deletion, and optional permanently flag
* @returns Promise<void> - Resolves when the records are deleted
*
* @throws {Error} When table name is not provided
* @throws {Error} When database client is not provided
* @throws {Error} When IDs are not provided or empty
* @throws {Error} When field is not provided
*
* @example
* await deleteMany({
* tableName: 'users',
* dbClient: dbClient,
* ids: ['123', '456', '789'],
* field: 'id',
* permanently: true,
* })
*/
export declare const deleteMany: <T>({ tableName, dbClient, ids, field, permanently, }: QueryParams<T> & {
ids: string[] | number[];
field?: string;
permanently?: boolean;
}) => Promise<void>;
/**
* Joins multiple tables in the specified table
*
* This function joins multiple tables in the specified table based on the provided
* query parameters. It constructs the SQL query, executes it, and returns the result.
*
* @template T - The type of the record to be joined
* @param params - Query parameters including table name, database client, select fields, joins, where conditions, group by, order by, limit, and offset
* @returns Promise<T[]> - The records found in the joined tables
*
* @throws {Error} When table name is not provided
* @throws {Error} When database client is not provided
* @throws {Error} When select fields are not provided
* @throws {Error} When joins are not provided
*
* @example
* const records = await joins({
* tableName: 'users',
* dbClient: dbClient,
* select: ['id', 'name', 'email'],
* joins: [{ type: 'INNER', table: 'orders', on: 'users.id = orders.user_id' }],
* where: { status: 'active' },
* groupBy: ['status'],
* orderBy: [{ field: 'created_at', direction: 'DESC' }],
* limit: 10,
* offset: 0,
* unaccent: true,
* })
*/
export declare const joins: <T>({ tableName, dbClient, select, joins, where, groupBy, orderBy, limit, offset, unaccent, }: QueryParams<T>) => Promise<T[]>;
/**
* Executa uma query SQL raw diretamente no banco de dados
* @param params - Parâmetros da query raw
* @returns Promise com o resultado da query
*
* @example
* // Query simples sem parâmetros
* const users = await rawQuery({
* dbClient,
* sql: 'SELECT * FROM users WHERE active = true'
* })
*
* @example
* // Query com parâmetros
* const user = await rawQuery({
* dbClient,
* sql: 'SELECT * FROM users WHERE id = ? AND email = ?',
* params: ['user-id', 'user@example.com']
* })
*
* @example
* // Query de agregação
* const stats = await rawQuery({
* dbClient,
* sql: `
* SELECT
* COUNT(*) as total_users,
* AVG(age) as avg_age,
* MAX(created_at) as last_created
* FROM users
* WHERE created_at >= ?
* `,
* params: [new Date('2023-01-01')]
* })
*/
export declare const rawQuery: <T = any>({ dbClient, sql, params, }: RawQueryParams) => Promise<T>;
/**
* Executes a function within a database transaction
* @param dbClient - Database client instance
* @param transactionFn - Function to execute within the transaction
* @returns Promise with the result of the transaction function
*
* @example
* // Simple transaction
* const result = await withTransaction(dbClient, async (tx) => {
* const user = await insert({
* tableName: 'users',
* dbClient: tx,
* data: { name: 'John', email: 'john@example.com' }
* })
*
* await insert({
* tableName: 'user_profiles',
* dbClient: tx,
* data: { user_id: user.id, bio: 'Hello world' }
* })
*
* return user
* })
*
* @example
* // Transaction with error handling
* try {
* const result = await withTransaction(dbClient, async (tx) => {
* // Multiple operations that must succeed or fail together
* const order = await insert({
* tableName: 'orders',
* dbClient: tx,
* data: { user_id: 'user-123', total: 100 }
* })
*
* await update({
* tableName: 'users',
* dbClient: tx,
* id: 'user-123',
* data: { last_order_id: order.id }
* })
*
* return order
* })
* } catch (error) {
* // Transaction was automatically rolled back
* console.error('Transaction failed:', error)
* }
*/
export declare const withTransaction: <T>(dbClient: any, transactionFn: (tx: ITransactionClient) => Promise<T>) => Promise<T>;
/**
* Creates a transaction client for manual transaction management
* @param dbClient - Database client instance
* @returns Promise with the transaction client
*
* @example
* // Manual transaction management
* const transaction = await beginTransaction(dbClient)
*
* try {
* const user = await insert({
* tableName: 'users',
* dbClient: transaction,
* data: { name: 'John', email: 'john@example.com' }
* })
*
* await insert({
* tableName: 'user_profiles',
* dbClient: transaction,
* data: { user_id: user.id, bio: 'Hello world' }
* })
*
* await transaction.commit()
* return user
* } catch (error) {
* await transaction.rollback()
* throw error
* }
*/
export declare const beginTransaction: (dbClient: any) => Promise<ITransactionClient>;