MySQL Promise Extension
This module decorates the objects: connection and pool, from the mysql module, with more functionality and support to ES6 promises. It was written with the goal to define queries and transactions with less effort.
Installation
It's available through the NPM package:
npm install --save mysql (peer dependency)
npm install --save mysql-promise-extension
Usage
This module exports two factory functions. One for connections: createConnection(options)
, and another for the pool: pool(options)
. The options are the same as the options from the mysql module.
connection
The connection object returned by the factory function createConnection(options)
is the same as the connection object from the mysql module, but with the extended functionality provided by this module. So, you have access to all original properties and functions from the mysql module in the case you need it.
The principal extended functions are:
execute(query)
executeTransaction(queryFunctions)
These functions: execute
and executeTransaction
, provide a simple way to perform queries in the database with less verbose code like: establish and terminate connections or handle the transactions commit/rollback.
The query object is the same as the used in the mysql module.
Also, provides the promisified version of the core functions:
connectP()
: Wrap function forconnection.connect()
endP()
: Wrap function forconnection.end()
queryP(query)
: Wrap function forconnection.query(query)
beginTransactionP()
: Wrap function forconnection.beginTransaction()
commitTransactionP()
: Wrap function forconnection.commit()
rollbackP()
: Wrap function forconnection.rollback()
Examples with async/await
First of all, lets see how the execute
and executeTransaction
are used:
const createConnection = createConnectionconst options = ... const getHobbiesAndUsers = async { const queryHobbies = 'select name from HOBBY' const queryUsers = 'select name from USER' const hobbies users = await return hobbies users } const getHobbiesFromUser = async { const queryHobbies = sql: 'select hobby_name as name from USER_HOBBY where user_id=?' values: 1 const hobbies = await return hobbies} const createUserAndHobby = async { const queryCreateUser = sql: 'insert into USER (name) values(?);' values: 'bob' const queryCreateAssociationWithHobby = sql: 'insert into USER_HOBBY (user_id, hobby_name) values(?,?);' values: previousQueryResultinsertId 'soccer' const result = await return resultaffectedRows}
With the execute
function, we only need to define the queries to pass as a argument and can be more than one.
The executeTransaction
function is slightly different. As we can see, it receives an array of functions. Those functions can receive one argument, which is the result of the previous query. It's useful for cases where we need the result of the previous query. The functions return a query object identical to the object used in the execute
function.
The executeTransaction
uses the waterfall implementation approach to preserve the sequential order.
If any error is thrown during the transaction, then rollback will be done automatically.
Now, lets see with the promisified functions:
const createConnection = createConnectionconst options = ... const getHobbiesAndUsers = async { const connection = try await connection const hobbies users = await Promiseallconnection connection return hobbies users finally await connection return null} const getHobbiesFromUser = async { const connection = try await connection const hobbies = await connection return hobbies finally await connection return null} const createUserAndHobby = async { const connection = await connection try await connection const createUser = await connection const createHobby = await connection await connection return createHobyaffectedRows catcherr await connection finally await connection return 0}
pool
If you want to use a pool of connections, you can get it through the factory function pool(options)
.
The factory function returns an object identical to the MySql module's pool object, but, like the connection, is extended with more functionality.
The extended functions are:
getConnectionP()
: Wrap function forpool.getConnection()
queryP(query)
: Wrap function forpool.query(query)
execute(query)
executeTransaction(queryFunctions)
Where the functions with suffix "P" are the promisified functions, and the last two functions: execute
and executeTransaction
, provide the same functionality as the functions, with same names, from the connection object.
Examples
With the execute
and executeTransaction
functions (the same use as in the connection):
const options = ... const pool = const getHobbiesAndUsers = async { const queryHobbies = 'select name from HOBBY' const queryUsers = 'select name from USER' const hobbies users = await pool return hobbies users } const getHobbiesFromUser = async { const queryHobbies = sql: 'select hobby_name as name from USER_HOBBY where user_id=?' values: 1 const hobbies = await pool return hobbies} const createUserAndHobby = async { const queryCreateUser = sql: 'insert into USER (name) values(?);' values: 'bob' const queryCreateAssociationWithHobby = sql: 'insert into USER_HOBBY (user_id, hobby_name) values(?,?);' values: previousQueryResultinsertId 'soccer' const result = await pool return resultaffectedRows}
With the promisified functions:
const options = ... const pool = const getHobbiesAndUsers = async { const hobbies users = await pool return hobbies users } const getHobbiesFromUser = async { // Use the connection directly from the pool const connection = await pool try const hobbies = await connection return hobbies finally // Don't forget to release it connection return null} const createUserAndHobby = async { const connection = await pool try await connection const createUser = await connection const createHobby = await connection await connection return createHobbyaffectedRows catcherr await connection finally connection return 0}
Bugs/Requests
Todo List:
- Create the proper documentation.
- Able to extend the PoolCluster functionality.