* Connect with MySQL database based on config, Handle any errors in connection * Set the pool handlers on connection.error * Also set proper timezone once connection is connected. * * @param {object} config * @returns {Promise<Connection>} * @private
(config)
| 51 | * @private |
| 52 | */ |
| 53 | async connect(config) { |
| 54 | const connectionConfig = { |
| 55 | host: config.host, |
| 56 | port: config.port, |
| 57 | user: config.username, |
| 58 | flags: '-FOUND_ROWS', |
| 59 | password: config.password, |
| 60 | database: config.database, |
| 61 | timezone: this.sequelize.options.timezone, |
| 62 | typeCast: ConnectionManager._typecast.bind(this), |
| 63 | bigNumberStrings: false, |
| 64 | supportBigNumbers: true, |
| 65 | ...config.dialectOptions |
| 66 | }; |
| 67 | |
| 68 | try { |
| 69 | const connection = await new Promise((resolve, reject) => { |
| 70 | const connection = this.lib.createConnection(connectionConfig); |
| 71 | |
| 72 | const errorHandler = e => { |
| 73 | // clean up connect & error event if there is error |
| 74 | connection.removeListener('connect', connectHandler); |
| 75 | connection.removeListener('error', connectHandler); |
| 76 | reject(e); |
| 77 | }; |
| 78 | |
| 79 | const connectHandler = () => { |
| 80 | // clean up error event if connected |
| 81 | connection.removeListener('error', errorHandler); |
| 82 | resolve(connection); |
| 83 | }; |
| 84 | |
| 85 | // don't use connection.once for error event handling here |
| 86 | // mysql2 emit error two times in case handshake was failed |
| 87 | // first error is protocol_lost and second is timeout |
| 88 | // if we will use `once.error` node process will crash on 2nd error emit |
| 89 | connection.on('error', errorHandler); |
| 90 | connection.once('connect', connectHandler); |
| 91 | }); |
| 92 | |
| 93 | debug('connection acquired'); |
| 94 | connection.on('error', error => { |
| 95 | switch (error.code) { |
| 96 | case 'ESOCKET': |
| 97 | case 'ECONNRESET': |
| 98 | case 'EPIPE': |
| 99 | case 'PROTOCOL_CONNECTION_LOST': |
| 100 | this.pool.destroy(connection); |
| 101 | } |
| 102 | }); |
| 103 | |
| 104 | if (!this.sequelize.config.keepDefaultTimezone) { |
| 105 | // set timezone for this connection |
| 106 | // but named timezone are not directly supported in mysql, so get its offset first |
| 107 | let tzOffset = this.sequelize.options.timezone; |
| 108 | tzOffset = /\//.test(tzOffset) ? momentTz.tz(tzOffset).format('Z') : tzOffset; |
| 109 | await promisify(cb => connection.query(`SET time_zone = '${tzOffset}'`, cb))(); |
| 110 | } |