*`user`: The name of the new user (defaults to the previous one).
*`password`: The password of the new user (defaults to the previous one).
*`charset`: The new charset (defaults to the previous one).
*`database`: The new database (defaults to the previous one).
A sometimes useful side effect of this functionality is that this function also
resets any connection state (variables, transactions, etc.).
Errors encountered during this operation are treated as fatal connection errors
by this module.
## Server disconnects
You may lose the connection to a MySQL server due to network problems, the
server timing you out, the server being restarted, or crashing. All of these
events are considered fatal errors, and will have the `err.code =
'PROTOCOL_CONNECTION_LOST'`. See the [Error Handling](#error-handling) section
for more information.
Re-connecting a connection is done by establishing a new connection. Once
terminated, an existing connection object cannot be re-connected by design.
With Pool, disconnected connections will be removed from the pool freeing up
space for a new connection to be created on the next getConnection call.
## Escaping query values
In order to avoid SQL Injection attacks, you should always escape any user
provided data before using it inside a SQL query. You can do so using the
`connection.escape()` or `pool.escape()` methods:
```js
var userId = 'some user provided value';
var sql = 'SELECT * FROM users WHERE id = ' + connection.escape(userId);
connection.query(sql, function(err, results) {
// ...
});
```
Alternatively, you can use `?` characters as placeholders for values you would
like to have escaped like this:
```js
connection.query('SELECT * FROM users WHERE id = ?', [userId], function(err, results) {
// ...
});
```
This looks similar to prepared statements in MySQL, however it really just uses
the same `connection.escape()` method internally.
**Caution** This also differs from prepared statements in that all `?` are
replaced, even those contained in comments and strings.
Different value types are escaped differently, here is how:
* Numbers are left untouched
* Booleans are converted to `true` / `false` strings
* Date objects are converted to `'YYYY-mm-dd HH:ii:ss'` strings
* Buffers are converted to hex strings, e.g. `X'0fa5'`
* Strings are safely escaped
* Arrays are turned into list, e.g. `['a', 'b']` turns into `'a', 'b'`
* Nested arrays are turned into grouped lists (for bulk inserts), e.g. `[['a',
'b'], ['c', 'd']]` turns into `('a', 'b'), ('c', 'd')`
* Objects are turned into `key = 'val'` pairs. Nested objects are cast to
strings.
*`undefined` / `null` are converted to `NULL`
*`NaN` / `Infinity` are left as-is. MySQL does not support these, and trying
to insert them as values will trigger MySQL errors until they implement
support.
If you paid attention, you may have noticed that this escaping allows you
to do neat things like this:
```js
var post = {id: 1, title: 'Hello MySQL'};
var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
// Neat!
});
console.log(query.sql); // INSERT INTO posts SET `id` = 1, `title` = 'Hello MySQL'
```
If you feel the need to escape queries by yourself, you can also use the escaping
function directly:
```js
var query = "SELECT * FROM posts WHERE title=" + mysql.escape("Hello MySQL");
console.log(query); // SELECT * FROM posts WHERE title='Hello MySQL'
```
## Escaping query identifiers
If you can't trust an SQL identifier (database / table / column name) because it is
provided by a user, you should escape it with `mysql.escapeId(identifier)`,
`connection.escapeId(identifier)` or `pool.escapeId(identifier)` like this:
```js
var sorter = 'date';
var sql = 'SELECT * FROM posts ORDER BY ' + connection.escapeId(sorter);
connection.query(sql, function(err, results) {
// ...
});
```
It also supports adding qualified identifiers. It will escape both parts.
```js
var sorter = 'date';
var sql = 'SELECT * FROM posts ORDER BY ' + connection.escapeId('posts.' + sorter);
connection.query(sql, function(err, results) {
// ...
});
```
Alternatively, you can use `??` characters as placeholders for identifiers you would
like to have escaped like this:
```js
var userId = 1;
var columns = ['username', 'email'];
var query = connection.query('SELECT ?? FROM ?? WHERE id = ?', [columns, 'users', userId], function(err, results) {
// ...
});
console.log(query.sql); // SELECT `username`, `email` FROM `users` WHERE id = 1
```
**Please note that this last character sequence is experimental and syntax might change**
When you pass an Object to `.escape()` or `.query()`, `.escapeId()` is used to avoid SQL injection in object keys.
### Preparing Queries
You can use mysql.format to prepare a query with multiple insertion points, utilizing the proper escaping for ids and values. A simple example of this follows:
```js
var sql = "SELECT * FROM ?? WHERE ?? = ?";
var inserts = ['users', 'id', userId];
sql = mysql.format(sql, inserts);
```
Following this you then have a valid, escaped query that you can then send to the database safely. This is useful if you are looking to prepare the query before actually sending it to the database. As mysql.format is exposed from SqlString.format you also have the option (but are not required) to pass in stringifyObject and timezone, allowing you provide a custom means of turning objects into strings, as well as a location-specific/timezone-aware Date.
### Custom format
If you prefer to have another type of query escape format, there's a connection configuration option you can use to define a custom format function. You can access the connection object if you want to use the built-in `.escape()` or any other connection function.
Here's an example of how to implement another format:
```js
connection.config.queryFormat = function (query, values) {
if (!values) return query;
return query.replace(/\:(\w+)/g, function (txt, key) {
if (values.hasOwnProperty(key)) {
return this.escape(values[key]);
}
return txt;
}.bind(this));
};
connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });
```
## Getting the id of an inserted row
If you are inserting a row into a table with an auto increment primary key, you
can retrieve the insert id like this:
```js
connection.query('INSERT INTO posts SET ?', {title: 'test'}, function(err, result) {
if (err) throw err;
console.log(result.insertId);
});
```
When dealing with big numbers (above JavaScript Number precision limit), you should
consider enabling `supportBigNumbers` option to be able to read the insert id as a
string, otherwise it will throw.
This option is also required when fetching big numbers from the database, otherwise
you will get values rounded to hundreds or thousands due to the precision limit.
## Getting the number of affected rows.
You can get the number of affected rows from an insert, update or delete statement.
```js
connection.query('DELETE FROM posts WHERE title = "wrong"', function (err, result) {
__WARNING: YOU MUST INVOKE the parser using one of these three field functions in your custom typeCast callback. They can only be called once.( see #539 for discussion)__
```
field.string()
field.buffer()
field.geometry()
```
are aliases for
```
parser.parseLengthCodedString()
parser.parseLengthCodedBuffer()
parser.parseGeometryValue()
```
__You can find which field function you need to use by looking at: [RowDataPacket.prototype._typeCast](https://github.com/felixge/node-mysql/blob/master/lib/protocol/packets/RowDataPacket.js#L41)__
## Connection Flags
If, for any reason, you would like to change the default connection flags, you
can use the connection option `flags`. Pass a string with a comma separated list
of items to add to the default flags. If you don't want a default flag to be used
prepend the flag with a minus sign. To add a flag that is not in the default list,
just write the flag name, or prefix it with a plus (case insensitive).
**Please note that some available flags that are not not supported (e.g.: Compression),
are still not allowed to be specified.**
### Example
The next example blacklists FOUND_ROWS flag from default connection flags.
```js
var connection = mysql.createConnection("mysql://localhost/test?flags=-FOUND_ROWS");
```
### Default Flags
The following flags are sent by default on a new connection:
-`CONNECT_WITH_DB` - Ability to specify the database on connection.
-`FOUND_ROWS` - Send the found rows instead of the affected rows as `affectedRows`.
-`IGNORE_SIGPIPE` - Old; no effect.
-`IGNORE_SPACE` - Let the parser ignore spaces before the `(` in queries.
-`LOCAL_FILES` - Can use `LOAD DATA LOCAL`.
-`LONG_FLAG`
-`LONG_PASSWORD` - Use the improved version of Old Password Authentication.
-`MULTI_RESULTS` - Can handle multiple resultsets for COM_QUERY.
-`ODBC` Old; no effect.
-`PROTOCOL_41` - Uses the 4.1 protocol.
-`PS_MULTI_RESULTS` - Can handle multiple resultsets for COM_STMT_EXECUTE.
-`RESERVED` - Old flag for the 4.1 protocol.
-`SECURE_CONNECTION` - Support native 4.1 authentication.
-`TRANSACTIONS` - Asks for the transaction status flags.
In addition, the following flag will be sent if the option `multipleStatements`
is set to `true`:
-`MULTI_STATEMENTS` - The client may send multiple statement per query or
statement prepare.
### Other Available Flags
There are other flags available. They may or may not function, but are still
available to specify.
- COMPRESS
- INTERACTIVE
- NO_SCHEMA
- PLUGIN_AUTH
- REMEMBER_OPTIONS
- SSL
- SSL_VERIFY_SERVER_CERT
## Debugging and reporting problems
If you are running into problems, one thing that may help is enabling the
`debug` mode for the connection:
```js
var connection = mysql.createConnection({debug: true});
```
This will print all incoming and outgoing packets on stdout. You can also restrict debugging to
packet types by passing an array of types to debug:
```js
var connection = mysql.createConnection({debug: ['ComQueryPacket', 'RowDataPacket']});
```
to restrict debugging to the query and data packets.
If that does not help, feel free to open a GitHub issue. A good GitHub issue
will have:
* The minimal amount of code required to reproduce the problem (if possible)
* As much debugging output and information about your environment (mysql
version, node version, os, etc.) as you can gather.
## Running tests
The test suite is split into two parts: unit tests and integration tests.
The unit tests run on any machine while the integration tests require a
MySQL server instance to be setup.
### Running unit tests
```sh
$ FILTER=unit npm test
```
### Running integration tests
Set the environment variables `MYSQL_DATABASE`, `MYSQL_HOST`, `MYSQL_PORT`,
`MYSQL_USER` and `MYSQL_PASSWORD`. Then run `npm test`.
For example, if you have an installation of mysql running on localhost:3306
and no password set for the `root` user, run:
```sh
$ mysql -u root -e "CREATE DATABASE IF NOT EXISTS node_mysql_test"
$ MYSQL_HOST=localhost MYSQL_PORT=3306 MYSQL_DATABASE=node_mysql_test MYSQL_USER=root MYSQL_PASSWORD= FILTER=integration npm test