├── tslint.json ├── .gitignore ├── .editorconfig ├── tsconfig.json ├── typings.json ├── .travis.yml ├── test ├── tsconfig.json ├── promise.ts └── test.ts ├── LICENSE.txt ├── package.json ├── README.md ├── promise.d.ts └── index.d.ts /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tslint-config-typings" 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bundle.d.ts 2 | node_modules/ 3 | .vscode/ 4 | *.js 5 | typedoc/ 6 | typings/ 7 | typedoc/ 8 | package-lock.json 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | 2 | [*] 3 | end_of_line = lf 4 | insert_final_newline = true 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 4 8 | trim_trailing_whitespace = true 9 | 10 | [*.{json,yml}] 11 | indent_size = 2 12 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "noImplicitAny": true, 4 | "strictNullChecks": true, 5 | "target": "es2015", 6 | "module": "commonjs", 7 | "typeRoots": [ 8 | "./typings/globals" 9 | ] 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mysql2", 3 | "version": "1.1.1", 4 | "homepage": "https://github.com/types/npm-mysql2", 5 | "main": "index.d.ts", 6 | "globalDependencies": { 7 | "node": "registry:env/node#6.0.0+20170213133316" 8 | }, 9 | "dependencies": { 10 | "mysql": "registry:npm/mysql#2.11.1+20161114232222" 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '6' 4 | - '8' 5 | - '10' 6 | - '12' 7 | - 'node' 8 | install: 9 | - npm install 10 | - typings install 11 | script: 12 | - npm run lint 13 | - npm run build 14 | - npm test 15 | # before_deploy: 16 | # - npm run typedoc 17 | # deploy: 18 | # skip_cleanup: true 19 | # provider: surge 20 | # project: ./typedoc/ 21 | # domain: typed-mysql.surge.sh 22 | -------------------------------------------------------------------------------- /test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2015", 4 | "noImplicitAny": true, 5 | "strictNullChecks": true, 6 | "noEmit": true, 7 | "module": "commonjs", 8 | "typeRoots": [ 9 | "../typings/globals", 10 | "../typings/modules" 11 | ] 12 | }, 13 | "include": [ 14 | "./*.ts", 15 | "./bundle.d.ts", 16 | "../typings/index.d.ts" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | ISC License 2 | 3 | Copyright (c) 2016, Felix Frederick Becker 4 | 5 | Permission to use, copy, modify, and/or distribute this software for any 6 | purpose with or without fee is hereby granted, provided that the above 7 | copyright notice and this permission notice appear in all copies. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@types/mysql2", 3 | "version": "1.0.0", 4 | "description": "Typings for mysql2", 5 | "scripts": { 6 | "build": "typings bundle -o test/bundle.d.ts", 7 | "test": "tsc -p test", 8 | "lint": "tslint -c tslint.json \"lib/**/*.d.ts\" index.d.ts", 9 | "typedoc": "typedoc --includeDeclarations --excludeExternals --name mysql --mode file --readme none --out typedoc lib index.d.ts typings/index.d.ts" 10 | }, 11 | "author": "Felix Becker ", 12 | "license": "ISC", 13 | "devDependencies": { 14 | "mysql2": "^1.0.0", 15 | "tslint": "^5.0.0", 16 | "tslint-config-typings": "^0.3.1", 17 | "typedoc": "^0.7.0", 18 | "typescript": "^2.2.1", 19 | "typings": "^2.0.0" 20 | }, 21 | "dependencies": { 22 | "@types/mysql": "types/mysql" 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Typed mysql2 2 | 3 | [![Greenkeeper badge](https://badges.greenkeeper.io/types/mysql2.svg)](https://greenkeeper.io/) 4 | [![Build Status](https://travis-ci.org/types/mysql2.svg?branch=master)](https://travis-ci.org/types/mysql2) 5 | 6 | Typescript Typings for [mysql2](https://www.npmjs.com/package/mysql2). 7 | 8 | ## Installation 9 | ```sh 10 | typings install --save mysql2 11 | ``` 12 | or 13 | ```sh 14 | npm install --save-dev types/mysql2#semver:version 15 | ``` 16 | 17 | ## Usage 18 | 19 | ```ts 20 | import {createConnection, QueryError, RowDataPacket} from 'mysql2'; 21 | 22 | const connection = createConnection(process.env['DB']); 23 | 24 | connection.query('SELECT 1 + 1 AS solution', (err: QueryError, rows: RowDataPacket[]) => { 25 | console.log('The solution is: ', rows[0]['solution']); 26 | }); 27 | 28 | connection.execute('UPDATE posts SET title = ? WHERE id = ?', ['Hello World', 1], (err: QueryError, result: OkPacket) => { 29 | console.log(result.affectedRows); 30 | }); 31 | ``` 32 | 33 | [More examples](./test) 34 | 35 | 36 | ## Contributing 37 | You can run them the tests with `npm run build` and `npm run test`. 38 | 39 | -------------------------------------------------------------------------------- /test/promise.ts: -------------------------------------------------------------------------------- 1 | 2 | import * as mysql from 'mysql2/promise'; 3 | 4 | // Connections 5 | async function testConnections() { 6 | let connection = await mysql.createConnection({ 7 | host: 'localhost', 8 | user: 'me', 9 | password: 'secret' 10 | }); 11 | 12 | connection.connect() 13 | .then(() => connection.query('SELECT 1 + 1 AS solution')) 14 | .then(([rows, fields]) => { 15 | console.log('The solution is: ', rows[0]['solution']); 16 | }); 17 | 18 | connection.connect() 19 | .then(() => connection.execute('SELECT 1 + 1 AS solution')) 20 | .then(([rows, fields]) => { 21 | console.log('The solution is: ', rows[0]['solution']); 22 | }); 23 | } 24 | 25 | /// Pools 26 | 27 | let poolConfig = { 28 | connectionLimit: 10, 29 | host: 'example.org', 30 | user: 'bob', 31 | password: 'secret' 32 | }; 33 | 34 | let pool = mysql.createPool(poolConfig); 35 | 36 | pool.query('SELECT 1 + 1 AS solution') 37 | .then(([rows, fields]) => { 38 | console.log('The solution is: ', rows[0]['solution']); 39 | }); 40 | 41 | pool.execute('SELECT 1 + 1 AS solution') 42 | .then(([rows, fields]) => { 43 | console.log('The solution is: ', rows[0]['solution']); 44 | }); 45 | 46 | async function test() { 47 | const connection = await pool.getConnection(); 48 | // Use the connection 49 | await connection.ping(); 50 | const rows = await connection.query('SELECT something FROM sometable'); 51 | // And done with the connection. 52 | connection.release(); 53 | } 54 | -------------------------------------------------------------------------------- /promise.d.ts: -------------------------------------------------------------------------------- 1 | 2 | import {RowDataPacket, OkPacket, ResultSetHeader, FieldPacket, QueryOptions, ConnectionOptions, PoolOptions, Connection as BaseConnection} from './index'; 3 | import {EventEmitter} from 'events'; 4 | export * from './index'; 5 | 6 | export interface Connection extends EventEmitter { 7 | 8 | config: ConnectionOptions; 9 | threadId: number; 10 | 11 | connect(): Promise; 12 | ping(): Promise; 13 | 14 | beginTransaction(): Promise; 15 | commit(): Promise; 16 | rollback(): Promise; 17 | 18 | changeUser(options: ConnectionOptions): Promise; 19 | 20 | query(sql: string): Promise<[T, FieldPacket[]]>; 21 | query(sql: string, values: any | any[] | { [param: string]: any }): Promise<[T, FieldPacket[]]>; 22 | query(options: QueryOptions): Promise<[T, FieldPacket[]]>; 23 | query(options: QueryOptions, values: any | any[] | { [param: string]: any }): Promise<[T, FieldPacket[]]>; 24 | 25 | execute(sql: string): Promise<[T, FieldPacket[]]>; 26 | execute(sql: string, values: any | any[] | { [param: string]: any }): Promise<[T, FieldPacket[]]>; 27 | execute(options: QueryOptions): Promise<[T, FieldPacket[]]>; 28 | execute(options: QueryOptions, values: any | any[] | { [param: string]: any }): Promise<[T, FieldPacket[]]>; 29 | 30 | unprepare(sql: string): void; 31 | 32 | end(options?: any): Promise; 33 | 34 | destroy(): void; 35 | 36 | pause(): void; 37 | 38 | resume(): void; 39 | 40 | escape(value: any): string; 41 | 42 | escapeId(value: string): string; 43 | escapeId(values: string[]): string; 44 | 45 | format(sql: string, values?: any | any[] | { [param: string]: any }): string; 46 | } 47 | 48 | export interface PoolConnection extends Connection { 49 | connection: BaseConnection; 50 | release(): void; 51 | } 52 | 53 | export interface Pool extends EventEmitter { 54 | query(sql: string): Promise<[T, FieldPacket[]]>; 55 | query(sql: string, values: any | any[] | { [param: string]: any }): Promise<[T, FieldPacket[]]>; 56 | query(options: QueryOptions): Promise<[T, FieldPacket[]]>; 57 | query(options: QueryOptions, values: any | any[] | { [param: string]: any }): Promise<[T, FieldPacket[]]>; 58 | 59 | execute(sql: string): Promise<[T, FieldPacket[]]>; 60 | execute(sql: string, values: any | any[] | { [param: string]: any }): Promise<[T, FieldPacket[]]>; 61 | execute(options: QueryOptions): Promise<[T, FieldPacket[]]>; 62 | execute(options: QueryOptions, values: any | any[] | { [param: string]: any }): Promise<[T, FieldPacket[]]>; 63 | 64 | getConnection(): Promise; 65 | on(event: 'connection', listener: (connection: PoolConnection) => any): this; 66 | on(event: 'acquire', listener: (connection: PoolConnection) => any): this; 67 | on(event: 'release', listener: (connection: PoolConnection) => any): this; 68 | on(event: 'enqueue', listener: () => any): this; 69 | end(): Promise; 70 | } 71 | 72 | export function createConnection(connectionUri: string): Promise; 73 | export function createConnection(config: ConnectionOptions): Promise; 74 | export function createPool(config: PoolOptions): Pool; 75 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | 2 | import { Connection as PromiseConnection, Pool as PromisePool, PoolConnection as PromisePoolConnection } from './promise'; 3 | import * as mysql from 'mysql'; 4 | export * from 'mysql'; 5 | 6 | export interface Connection extends mysql.Connection { 7 | execute(sql: string, callback?: (err: mysql.QueryError | null, result: T, fields: mysql.FieldPacket[]) => any): mysql.Query; 8 | execute(sql: string, values: any | any[] | { [param: string]: any }, callback?: (err: mysql.QueryError | null, result: T, fields: mysql.FieldPacket[]) => any): mysql.Query; 9 | execute(options: mysql.QueryOptions, callback?: (err: mysql.QueryError | null, result: T, fields?: mysql.FieldPacket[]) => any): mysql.Query; 10 | execute(options: mysql.QueryOptions, values: any | any[] | { [param: string]: any }, callback?: (err: mysql.QueryError | null, result: T, fields: mysql.FieldPacket[]) => any): mysql.Query; 11 | ping(callback?: (err: mysql.QueryError | null) => any): void; 12 | promise(promiseImpl?: PromiseConstructor): PromiseConnection; 13 | } 14 | 15 | export interface PoolConnection extends mysql.PoolConnection, Connection { 16 | promise(promiseImpl?: PromiseConstructor): PromisePoolConnection; 17 | } 18 | 19 | export interface Pool extends mysql.Connection { 20 | execute(sql: string, callback?: (err: mysql.QueryError | null, result: T, fields: mysql.FieldPacket[]) => any): mysql.Query; 21 | execute(sql: string, values: any | any[] | { [param: string]: any }, callback?: (err: mysql.QueryError | null, result: T, fields: mysql.FieldPacket[]) => any): mysql.Query; 22 | execute(options: mysql.QueryOptions, callback?: (err: mysql.QueryError | null, result: T, fields?: mysql.FieldPacket[]) => any): mysql.Query; 23 | execute(options: mysql.QueryOptions, values: any | any[] | { [param: string]: any }, callback?: (err: mysql.QueryError | null, result: T, fields: mysql.FieldPacket[]) => any): mysql.Query; 24 | getConnection(callback: (err: NodeJS.ErrnoException, connection: PoolConnection) => any): void; 25 | releaseConnection(connection: PoolConnection): void; 26 | end(callback?: (err: mysql.QueryError) => any): void; 27 | on(event: 'connection', listener: (connection: PoolConnection) => any): this; 28 | on(event: 'acquire', listener: (connection: PoolConnection) => any): this; 29 | on(event: 'release', listener: (connection: PoolConnection) => any): this; 30 | on(event: 'enqueue', listener: () => any): this; 31 | promise(promiseImpl?: PromiseConstructor): PromisePool; 32 | } 33 | 34 | export interface ConnectionOptions extends mysql.ConnectionOptions { 35 | charsetNumber?: number; 36 | compress?: boolean; 37 | authSwitchHandler?: (data: any, callback: () => void) => any; 38 | connectAttributes?: { [param: string]: any }; 39 | decimalNumbers?: boolean; 40 | isServer?: boolean; 41 | maxPreparedStatements?: number; 42 | namedPlaceholders?: boolean; 43 | nestTables?: boolean | string; 44 | passwordSha1?: string; 45 | pool?: any; 46 | rowsAsArray?: boolean; 47 | stream?: any; 48 | uri?: string; 49 | connectionLimit?: number; 50 | Promise?: any; 51 | queueLimit?: number; 52 | waitForConnections?: boolean; 53 | } 54 | 55 | export interface PoolOptions extends mysql.PoolOptions, ConnectionOptions {} 56 | 57 | export interface FieldPacket extends mysql.FieldPacket { 58 | columnType: number 59 | columnLength: number 60 | schema: string 61 | characterSet: number 62 | } 63 | 64 | type authPlugins = 65 | (pluginMetadata: { connection: Connection; command: string }) => 66 | (pluginData: Buffer) => Promise; 67 | 68 | export interface ConnectionOptions extends mysql.ConnectionOptions { 69 | authPlugins?: { 70 | [key: string]: authPlugins; 71 | }; 72 | } 73 | 74 | export interface PoolOptions extends mysql.PoolOptions { 75 | authPlugins?: { 76 | [key: string]: authPlugins; 77 | }; 78 | } 79 | 80 | export function createConnection(connectionUri: string): Connection; 81 | export function createConnection(config: ConnectionOptions): Connection; 82 | export function createPool(config: PoolOptions | string): Pool; 83 | -------------------------------------------------------------------------------- /test/test.ts: -------------------------------------------------------------------------------- 1 | 2 | import * as fs from 'fs'; 3 | import * as mysql from 'mysql2'; 4 | import * as stream from 'stream'; 5 | 6 | // Connections 7 | let connection = mysql.createConnection({ 8 | host: 'localhost', 9 | user: 'me', 10 | password: 'secret' 11 | }); 12 | 13 | connection.connect(); 14 | connection.ping(); 15 | 16 | connection.query('SELECT 1 + 1 AS solution', function (err: mysql.QueryError, rows: mysql.RowDataPacket[], fields: mysql.FieldPacket) { 17 | if (err) { 18 | throw err; 19 | } 20 | 21 | console.log('The solution is: ', rows[0]['solution']); 22 | }); 23 | 24 | connection.execute('SELECT 1 + 1 AS solution', function (err: mysql.QueryError, rows: mysql.RowDataPacket[], fields: mysql.FieldPacket) { 25 | if (err) { 26 | throw err; 27 | } 28 | 29 | console.log('The solution is: ', rows[0]['solution']); 30 | }); 31 | 32 | // multipleStatements 33 | 34 | connection.query('SELECT 1 AS x; SELECT 1 AS x; SELECT 1 AS x', function (err: mysql.QueryError, rows: mysql.RowDataPacket[][], fields: mysql.FieldPacket) { 35 | if (err) { 36 | throw err; 37 | } 38 | 39 | console.log(rows[0][0]['x']); 40 | console.log(rows[1][0]['x']); 41 | console.log(rows[2][0]['x']); 42 | }); 43 | 44 | connection.end(); 45 | 46 | connection = mysql.createConnection({ 47 | host: 'example.org', 48 | user: 'bob', 49 | password: 'secret' 50 | }); 51 | 52 | connection.connect(function (err) { 53 | if (err) { 54 | console.error('error connecting: ' + err.stack); 55 | return; 56 | } 57 | 58 | console.log('connected as id ' + connection.threadId); 59 | }); 60 | 61 | connection.query('SELECT 1', function (err, rows) { 62 | // connected! (unless `err` is set) 63 | }); 64 | 65 | connection = mysql.createConnection({ 66 | host: 'localhost', 67 | ssl: { 68 | ca: '' 69 | } 70 | }); 71 | 72 | connection = mysql.createConnection({ 73 | host: 'localhost', 74 | ssl: { 75 | // DO NOT DO THIS 76 | // set up your ca correctly to trust the connection 77 | rejectUnauthorized: false 78 | } 79 | }); 80 | 81 | connection.end(function (err) { 82 | // The connection is terminated now 83 | }); 84 | 85 | connection.destroy(); 86 | 87 | connection.changeUser({ user: 'john' }, function (err) { 88 | if (err) { 89 | throw err; 90 | } 91 | }); 92 | 93 | let userId = 'some user provided value'; 94 | let sql = 'SELECT * FROM users WHERE id = ' + connection.escape(userId); 95 | connection.query(sql, function (err, results) { 96 | // ... 97 | }); 98 | connection.query('SELECT * FROM users WHERE id = ?', [userId], function (err, results) { 99 | // ... 100 | }); 101 | 102 | let post = { id: 1, title: 'Hello MySQL' }; 103 | let query = connection.query('INSERT INTO posts SET ?', post, function (err, result) { 104 | // Neat! 105 | }); 106 | console.log(query.sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL' 107 | 108 | let queryStr = 'SELECT * FROM posts WHERE title=' + mysql.escape('Hello MySQL'); 109 | 110 | console.log(queryStr); // SELECT * FROM posts WHERE title='Hello MySQL' 111 | 112 | let sorter = 'date'; 113 | sql = 'SELECT * FROM posts ORDER BY ' + connection.escapeId(sorter); 114 | connection.query(sql, function (err, results) { 115 | // ... 116 | }); 117 | 118 | sql = 'SELECT * FROM posts ORDER BY ' + connection.escapeId('posts.' + sorter); 119 | connection.query(sql, function (err, results) { 120 | // ... 121 | }); 122 | 123 | let userIdNum = 1; 124 | let columns = ['username', 'email']; 125 | query = connection.query('SELECT ?? FROM ?? WHERE id = ?', [columns, 'users', userIdNum], function (err, results) { 126 | // ... 127 | }); 128 | 129 | console.log(query.sql); // SELECT `username`, `email` FROM `users` WHERE id = 1 130 | 131 | sql = 'SELECT * FROM ?? WHERE ?? = ?'; 132 | let inserts = ['users', 'id', userId]; 133 | sql = mysql.format(sql, inserts); 134 | 135 | sql = 'INSERT INTO posts SET ?'; 136 | post = { id: 1, title: 'Hello MySQL' }; 137 | sql = mysql.format(sql, post); 138 | 139 | connection.config.queryFormat = function (query, values) { 140 | if (!values) { 141 | return query; 142 | } 143 | return query.replace(/\:(\w+)/g, function (txt: string, key: string) { 144 | if (values.hasOwnProperty(key)) { 145 | return this.escape(values[key]); 146 | } 147 | return txt; 148 | }.bind(this)); 149 | }; 150 | 151 | connection.query('UPDATE posts SET title = :title', { title: 'Hello MySQL' }); 152 | 153 | let s: stream.Readable = connection.query('UPDATE posts SET title = :title', { title: 'Hello MySQL' }).stream({ highWaterMark: 5 }); 154 | 155 | connection.query('INSERT INTO posts SET ?', { title: 'test' }, function (err: mysql.QueryError, result: mysql.OkPacket) { 156 | console.log(result.insertId); 157 | }); 158 | 159 | connection.query('DELETE FROM posts WHERE title = "wrong"', function (err: mysql.QueryError, result: mysql.OkPacket) { 160 | console.log('deleted ' + result.affectedRows + ' rows'); 161 | }); 162 | 163 | connection.query('UPDATE posts SET ...', function (err: mysql.QueryError, result: mysql.OkPacket) { 164 | console.log('changed ' + result.changedRows + ' rows'); 165 | }); 166 | 167 | connection.connect(function (err) { 168 | console.log('connected as id ' + connection.threadId); 169 | }); 170 | 171 | /// Pools 172 | 173 | let poolConfig = { 174 | connectionLimit: 10, 175 | host: 'example.org', 176 | user: 'bob', 177 | password: 'secret' 178 | }; 179 | 180 | let pool = mysql.createPool(poolConfig); 181 | 182 | pool.query('SELECT 1 + 1 AS solution', function (err: mysql.QueryError, rows: mysql.RowDataPacket[], fields: mysql.FieldPacket) { 183 | if (err) { 184 | throw err; 185 | } 186 | 187 | console.log('The solution is: ', rows[0]['solution']); 188 | }); 189 | 190 | pool.execute('SELECT 1 + 1 AS solution', function (err: mysql.QueryError, rows: mysql.RowDataPacket[], fields: mysql.FieldPacket) { 191 | if (err) { 192 | throw err; 193 | } 194 | 195 | console.log('The solution is: ', rows[0]['solution']); 196 | }); 197 | 198 | pool = mysql.createPool({ 199 | host: 'example.org', 200 | user: 'bob', 201 | password: 'secret' 202 | }); 203 | 204 | pool.getConnection(function (err, connection) { 205 | // connected! (unless `err` is set) 206 | }); 207 | 208 | pool.on('connection', function (connection) { 209 | connection.query('SET SESSION auto_increment_increment=1'); 210 | }); 211 | 212 | pool.getConnection(function (err, connection) { 213 | // Use the connection 214 | connection.query('SELECT something FROM sometable', function (err, rows) { 215 | // And done with the connection. 216 | connection.release(); 217 | 218 | // Don't use the connection here, it has been returned to the pool. 219 | }); 220 | }); 221 | 222 | pool = mysql.createPool('https://example.org/mysql/db'); 223 | 224 | pool.getConnection(function (err, connection) { 225 | // connected! (unless `err` is set) 226 | }); 227 | 228 | pool.on('connection', function (connection) { 229 | connection.query('SET SESSION auto_increment_increment=1'); 230 | }); 231 | 232 | pool.getConnection(function (err, connection) { 233 | // Use the connection 234 | connection.query('SELECT something FROM sometable', function (err, rows) { 235 | // And done with the connection. 236 | connection.release(); 237 | 238 | // Don't use the connection here, it has been returned to the pool. 239 | }); 240 | }); 241 | 242 | /// PoolClusters 243 | 244 | // create 245 | let poolCluster = mysql.createPoolCluster(); 246 | 247 | let poolClusterConfig = { 248 | canRetry: true, 249 | removeNodeErrorCount: 2, 250 | restoreNodeTimeout: 3, 251 | defaultSelector: 'RANDOM' 252 | }; 253 | 254 | poolCluster.add(poolClusterConfig); // anonymous group 255 | poolCluster.add('MASTER', poolClusterConfig); 256 | poolCluster.add('SLAVE1', poolClusterConfig); 257 | poolCluster.add('SLAVE2', poolClusterConfig); 258 | 259 | // Target Group : ALL(anonymous, MASTER, SLAVE1-2), Selector : round-robin(default) 260 | poolCluster.getConnection(function (err, connection) { }); 261 | 262 | // Target Group : MASTER, Selector : round-robin 263 | poolCluster.getConnection('MASTER', function (err, connection) { }); 264 | 265 | // Target Group : SLAVE1-2, Selector : order 266 | // If can't connect to SLAVE1, return SLAVE2. (remove SLAVE1 in the cluster) 267 | poolCluster.on('remove', function (nodeId) { 268 | console.log('REMOVED NODE : ' + nodeId); // nodeId = SLAVE1 269 | }); 270 | 271 | poolCluster.getConnection('SLAVE*', 'ORDER', function (err, connection) { }); 272 | 273 | // of namespace : of(pattern, selector) 274 | poolCluster.of('*').getConnection(function (err, connection) { }); 275 | 276 | const cluster = poolCluster.of('SLAVE*', 'RANDOM'); 277 | pool.getConnection(function (err, connection) { }); 278 | pool.getConnection(function (err, connection) { }); 279 | 280 | let poolClusterWithOptions = mysql.createPoolCluster({ 281 | canRetry: true, 282 | removeNodeErrorCount: 3, 283 | restoreNodeTimeout: 1000, 284 | defaultSelector: 'RR' 285 | }); 286 | 287 | // destroy 288 | poolCluster.end(); 289 | 290 | // Queries 291 | 292 | query = connection.query('SELECT * FROM posts'); 293 | query 294 | .on('error', function (err: NodeJS.ErrnoException) { 295 | // Handle error, an 'end' event will be emitted after this as well 296 | }) 297 | .on('fields', function (fields: any) { 298 | // the field packets for the rows to follow 299 | }) 300 | .on('result', function (row: any) { 301 | // Pausing the connnection is useful if your processing involves I/O 302 | connection.pause(); 303 | 304 | let processRow = (row: any, cb: () => void) => { 305 | cb(); 306 | }; 307 | 308 | processRow(row, function () { 309 | connection.resume(); 310 | }); 311 | }) 312 | .on('end', function () { 313 | // all rows have been received 314 | }); 315 | 316 | let writable = fs.createWriteStream('file.txt'); 317 | connection.query('SELECT * FROM posts') 318 | .stream({ highWaterMark: 5 }) 319 | .pipe(writable); 320 | 321 | connection = mysql.createConnection({ multipleStatements: true }); 322 | 323 | connection.query('SELECT 1; SELECT 2', function (err: mysql.QueryError, results: mysql.RowDataPacket) { 324 | // `results` is an array with one element for every statement in the query: 325 | console.log(results[0]); // [{1: 1}] 326 | console.log(results[1]); // [{2: 2}] 327 | }); 328 | 329 | query = connection.query('SELECT 1; SELECT 2'); 330 | 331 | query 332 | .on('fields', function (fields, index) { 333 | // the fields for the result rows that follow 334 | }) 335 | .on('result', function (row, index) { 336 | // index refers to the statement this result belongs to (starts at 0) 337 | }); 338 | 339 | let options = { sql: '...', nestTables: true }; 340 | 341 | connection.query(options, function (err, results) { 342 | /* results will be an array like this now: 343 | [{ 344 | table1: { 345 | fieldA: '...', 346 | fieldB: '...', 347 | }, 348 | table2: { 349 | fieldA: '...', 350 | fieldB: '...', 351 | }, 352 | }, ...] 353 | */ 354 | }); 355 | 356 | connection.beginTransaction(function (err) { 357 | let title = 'title'; 358 | 359 | if (err) { throw err; } 360 | connection.query('INSERT INTO posts SET title=?', title, function (err: mysql.QueryError, result: mysql.OkPacket) { 361 | if (err) { 362 | connection.rollback(function () { 363 | throw err; 364 | }); 365 | } 366 | 367 | let log = 'Post ' + result.insertId + ' added'; 368 | 369 | connection.query('INSERT INTO log SET data=?', log, function (err, result) { 370 | if (err) { 371 | connection.rollback(function () { 372 | throw err; 373 | }); 374 | } 375 | connection.commit(function (err) { 376 | if (err) { 377 | connection.rollback(function () { 378 | throw err; 379 | }); 380 | } 381 | console.log('success!'); 382 | }); 383 | }); 384 | }); 385 | }); 386 | 387 | // Kill query after 60s 388 | connection.query({ sql: 'SELECT COUNT(*) AS count FROM big_table', timeout: 60000 }, function (err: mysql.QueryError, rows: mysql.RowDataPacket[]) { 389 | if (err && err.code === 'PROTOCOL_SEQUENCE_TIMEOUT') { 390 | throw new Error('too long to count table rows!'); 391 | } 392 | 393 | if (err) { 394 | throw err; 395 | } 396 | 397 | console.log(rows[0]['count'] + ' rows'); 398 | }); 399 | 400 | connection = mysql.createConnection({ 401 | port: 84943 // WRONG PORT 402 | }); 403 | 404 | connection.connect(function (err) { 405 | if (err) { 406 | console.log(err.code); // 'ECONNREFUSED' 407 | console.log(err.fatal); // true 408 | } 409 | }); 410 | 411 | connection.query('SELECT 1', function (err) { 412 | if (err) { 413 | console.log(err.code); // 'ECONNREFUSED' 414 | console.log(err.fatal); // true 415 | } 416 | }); 417 | 418 | connection.query('USE name_of_db_that_does_not_exist', function (err, rows) { 419 | if (err) { 420 | console.log(err.code); // 'ER_BAD_DB_ERROR' 421 | } 422 | }); 423 | 424 | connection.query('SELECT 1', function (err: mysql.QueryError | null, rows: mysql.RowDataPacket[]) { 425 | console.log(err); // null 426 | console.log(rows.length); // 1 427 | }); 428 | 429 | connection.on('error', function (err: NodeJS.ErrnoException | null) { 430 | if (err) { 431 | console.log(err.code); // 'ER_BAD_DB_ERROR' 432 | } 433 | }); 434 | 435 | connection.query('USE name_of_db_that_does_not_exist'); 436 | 437 | // I am Chuck Norris: 438 | connection.on('error', function () { 439 | // ignore 440 | }); 441 | 442 | connection = mysql.createConnection({ typeCast: false }); 443 | 444 | query = connection.query({ sql: '...', typeCast: false }, function (err, results) { 445 | // 446 | }); 447 | 448 | connection.query({ 449 | sql: '...', 450 | typeCast: function (field: any, next: Function) { 451 | if (field.type === 'TINY' && field.length === 1) { 452 | return (field.string() === '1'); // 1 = true, 0 = false 453 | } 454 | return next(); 455 | } 456 | }); 457 | 458 | connection = mysql.createConnection('mysql://localhost/test?flags=-FOUND_ROWS'); 459 | connection = mysql.createConnection({ debug: true }); 460 | connection = mysql.createConnection({ debug: ['ComQueryPacket', 'RowDataPacket'] }); 461 | --------------------------------------------------------------------------------