@starbemtech/star-db-query-builder
Version:
A query builder to be used with mysql or postgres
189 lines • 7.47 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createMysqlClient = void 0;
const promise_retry_1 = __importDefault(require("promise-retry"));
const monitor_1 = require("../monitor/monitor");
const transientErrorCodes = new Set([
'ECONNRESET',
'ETIMEDOUT',
'PROTOCOL_CONNECTION_LOST',
'ECONNREFUSED',
]);
/**
* Checks if the given error is a transient error that can be retried
*
* Transient errors are temporary network or connection issues that typically
* resolve themselves and can be safely retried. This function checks if the
* error code matches known transient error patterns for MySQL connections.
*
* @param error - The error object to check
* @returns boolean - True if the error is transient and can be retried, false otherwise
*
* @example
* try {
* const result = await pool.execute(sql, params);
* } catch (error) {
* if (isTransientError(error)) {
* // Retry the operation
* console.log('Transient error detected, retrying...');
* } else {
* // Handle permanent error
* throw error;
* }
* }
*/
function isTransientError(error) {
return error && error.code && transientErrorCodes.has(error.code);
}
/**
* Creates a MySQL database client
*
* This function initializes a MySQL database client with the provided pool configuration
* and optional retry options. It sets up monitoring for connection events and query operations.
*
* @param pool - The MySQL pool instance
* @param retryOptions - Optional retry options for failed queries
* @returns IDatabaseClient - The MySQL database client instance
*
* @example
* const mysqlClient = createMysqlClient(pool, { retries: 3, factor: 2, minTimeout: 1000 });
*
* @example
* const mysqlClient = createMysqlClient(pool, { retries: 3, factor: 2, minTimeout: 1000 });
*
* @example
* const mysqlClient = createMysqlClient(pool, { retries: 3, factor: 2, minTimeout: 1000 });
*
* @example
* const mysqlClient = createMysqlClient(pool, { retries: 3, factor: 2, minTimeout: 1000 });
*/
const createMysqlClient = (pool, retryOptions) => {
monitor_1.monitor.emit(monitor_1.MonitorEvents.CONNECTION_CREATED, {
clientType: 'mysql',
poolOptions: pool.config,
});
return {
clientType: 'mysql',
query: async (sql, params) => {
return (0, promise_retry_1.default)(async (retry, attempt) => {
const startTime = Date.now();
try {
monitor_1.monitor.emit(monitor_1.MonitorEvents.QUERY_START, {
clientType: 'mysql',
sql,
params,
attempt,
});
const [rows] = await pool.execute(sql, params);
const elapsedTime = Date.now() - startTime;
monitor_1.monitor.emit(monitor_1.MonitorEvents.QUERY_END, {
clientType: 'mysql',
sql,
params,
attempt,
elapsedTime,
});
return rows;
}
catch (error) {
const elapsedTime = Date.now() - startTime;
monitor_1.monitor.emit(monitor_1.MonitorEvents.QUERY_ERROR, {
clientType: 'mysql',
sql,
params,
attempt,
elapsedTime,
error,
});
if (isTransientError(error)) {
console.warn(`MySQL query attempt ${attempt} failed, retrying...`, error);
monitor_1.monitor.emit(monitor_1.MonitorEvents.RETRY_ATTEMPT, {
clientType: 'mysql',
sql,
params,
attempt,
error,
});
return retry(error);
}
throw error;
}
}, retryOptions);
},
beginTransaction: async () => {
const connection = await pool.getConnection();
try {
await connection.beginTransaction();
return {
query: async (sql, params) => {
const startTime = Date.now();
try {
monitor_1.monitor.emit(monitor_1.MonitorEvents.QUERY_START, {
clientType: 'mysql',
sql,
params,
attempt: 1,
inTransaction: true,
});
const [rows] = await connection.execute(sql, params);
const elapsedTime = Date.now() - startTime;
monitor_1.monitor.emit(monitor_1.MonitorEvents.QUERY_END, {
clientType: 'mysql',
sql,
params,
attempt: 1,
elapsedTime,
inTransaction: true,
});
return rows;
}
catch (error) {
const elapsedTime = Date.now() - startTime;
monitor_1.monitor.emit(monitor_1.MonitorEvents.QUERY_ERROR, {
clientType: 'mysql',
sql,
params,
attempt: 1,
elapsedTime,
error,
inTransaction: true,
});
throw error;
}
},
commit: async () => {
try {
await connection.commit();
monitor_1.monitor.emit(monitor_1.MonitorEvents.TRANSACTION_COMMIT, {
clientType: 'mysql',
});
}
finally {
connection.release();
}
},
rollback: async () => {
try {
await connection.rollback();
monitor_1.monitor.emit(monitor_1.MonitorEvents.TRANSACTION_ROLLBACK, {
clientType: 'mysql',
});
}
finally {
connection.release();
}
},
};
}
catch (error) {
connection.release();
throw error;
}
},
};
};
exports.createMysqlClient = createMysqlClient;
//# sourceMappingURL=mysqlClient.js.map