const Bluebird = require('bluebird'); const { isUndefined } = require('lodash'); const Client = require('knex/lib/dialects/mysql'); const Transaction = require('knex/lib/transaction'); const inherits = require('inherits'); const sqlstring = require('sqlstring'); class RDSDataAPITransaction extends Transaction { commit(conn, value) { this._completed = true; return conn .commitTransaction({ transactionId: conn.__knexTxId, }) .then(() => this._resolver(value)); } rollback(conn, err) { const self = this; this._completed = true; return conn .rollbackTransaction({ transactionId: conn.__knexTxId, }) .then((status) => { if (isUndefined(err)) { if (self.doNotRejectOnRollback) { self._resolver(); return; } err = new Error(`Transaction rejected with non-error: ${err}`); self._rejecter(err); return; } if (status.transactionStatus === 'Rollback Complete') { self._rejecter(err); return; } err = new Error(status.transactionStatus); self._rejecter(err); }); } acquireConnection() { const self = this; return new Bluebird(((resolve, reject) => { self.client .acquireConnection() .then((cnx) => { cnx.beginTransaction(self.client.connectionSettings).then((result) => { cnx.__knexTxId = result.transactionId; cnx.isTransaction = true; resolve(cnx); }); resolve(cnx); }) .catch(reject); })); } } function ClientRDSDataAPI(config) { Client.call(this, config); } inherits(ClientRDSDataAPI, Client); Object.assign(ClientRDSDataAPI.prototype, { driverName: 'rds-data', _driver() { return require('data-api-client'); }, transaction() { return new RDSDataAPITransaction(this, ...arguments); }, acquireConnection() { const connection = this.driver(this.connectionSettings); return Bluebird.resolve(connection); }, // Runs the query on the specified connection, providing the bindings // and any other necessary prep work. _query(connection, obj) { if (!obj || typeof obj === 'string') obj = { sql: obj }; return new Bluebird((async (resolver) => { if (!obj.sql) { resolver(); return; } const result = await connection.query({ sql: sqlstring.format(obj.sql, obj.bindings), continueAfterTimeout: true, transactionId: obj.__knexTxId, }); obj.response = result; resolver(obj); })); }, // Process the response as returned from the query. processResponse(obj) { return obj.response.records; }, }); module.exports = ClientRDSDataAPI;