mysql.connect never returns - mysql

const mysql = require('mysql');
const dbCon = mysql.createConnection({
host: "localhost",
user: "mainUser",
password: "pa55",
database: "testDB"
});
dbCon.connect(function (err) {
if (err) throw err;
console.log("Connected to DB");
});
When I run it, I see the "Connected to DB" log but the program never finishes or exits, like it's waiting for something.

Let's try to get the code below and save this to 'dbConnect.js' file and then run node-command:
> node dbConnect.js
you will see the result.
const mysql = require('mysql');
const dbCon = mysql.createConnection({
host: "localhost",
user: "mainUser",
password: "pa55",
database: "testDB"
});
dbCon.connect(function(err) {
if (err) {
return console.log(err.message);
}
console.log('Connected to the MySQL server.');
});
let dbCreateQuery = `
create table if not exists users(
id int primary key auto_increment,
first_name varchar(255)not null,
last_name varchar(255)not null);
`;
let dbInsertQuery = `
insert into users (first_name, last_name)
values ('john', 'smith');
insert into users (first_name, last_name)
values ('jane', 'smith');
`;
let dbSelectQuery = `
select *
from users
`;
//test of create query execute
dbCon.query(
dbCreateQuery,
function(err, results, fields) {
if (err) {
console.log(err.message); //execution error
}
else {
console.log('Table "users" has been created';
}
});
//test of insert query execute
dbCon.query(
dbInsertQuery,
function(err, results, fields) {
if (err) {
console.log(err.message); //execution error
}
else {
console.log('Table "users" has been filled';
}
});
//test of select query execute
dbCon.query(
dbSelectQuery,
function(err, results, fields) {
if (err) {
console.log(err.message);
}
else {
console.log('Data rows from table "users" has been extracted';
console.log(results); // data rows
console.log(fields); // meta of fields
}
});
/*
Also, recommended use 'end()' method for closing connection to database after running operations.
*/
dbCon.end(function(err) {
if (err) {
return console.log(err.message);
}
console.log('Close the MySQL server connection.');
});
/*
Then use 'destroy()' method for close connection immediately, it's
guarantees that no more callbacks or events will be triggered for the connection,
i.e. method does not take any callback argument like the end() method.
*/
dbCon.destroy();

Related

How to pass multiple parameters for promise function in Nodejs connected with MYSQL server?

let mysql = require('mysql');
let connection = mysql.createConnection({
host: 'localhost',
user: 'priyanka',
password: '1234',
database: 'todoapp'
});
connection.connect(function(err) {
if (err) {
return console.error('error: ' + err.message);
}
console.log('Connected to the MySQL server.');
});
// promise function
query = `select device from user_table limit 34`;
sql = function(device){
return new Promise(function(resolve,reject)
{
connection.query(query, (error, results) => {
if (error) {
reject( console.error(error.message));
}
resolve(console.log(results));
});
})
}
sql('device').then(function(rows) {
}).catch((err) => setImmediate(() => { throw err; }));
connection.end();
sql('device') -> inside sql call , can i only place comma separated field values to get rows from user_table or is there any other way to pass multiple columns ?

How to immediately retrieve data after being bulk inserted into MySQL with NodeJS?

I have the following code in NodeJS that does a bulk insert of data into a table and I'd like to retrieve the last record inserted right after the bulk insert:
var mysql = require('mysql');
var pool = mysql.createPool({
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DATABASE,
});
(async () => {
await insert();
// this does not return the inserted values unless I wait for ~500 ms
console.log(await getLastRecord());
})();
function insert() {
var sql = "INSERT IGNORE INTO my_table (id, field1, field2) VALUES ?";
var data = [ /* ... array of 1000 records */ ];
return new Promise((resolve, reject) => {
pool.getConnection(function(err, connection) {
if (!err) {
connection.query(sql, params, function (err, result) {
connection.release();
if (err != null) reject();
resolve();
});
} else {
reject();
}
});
});
}
function getLastRecord() {
var sql = "SELECT * FROM my_table ORDER BY id DESC";
return new Promise((resolve, reject) => {
pool.getConnection(function(err, connection) {
if (!err) {
connection.query(sql, [], function (err, result) {
connection.release();
if (err != null) reject();
resolve(result);
});
} else {
reject();
}
});
});
}
However the SELECT statement does not retrieve the most recently inserted batch. The table is a MyISAM table.

requests not going through in nodejs and mysql

I have this code where I am trying to receive data from the user and it should be inserted into the db directly without any module just a controller, can someone tell me how can I do that, I know we can get the user data in the req.body, but I don't know how to send it back to the controller here is the
P.S user will be sending around 10 or more fields that will be inserted
here is the code
controller
sql.query(`INSERT INTO Admin (LoginID,Password,Preference,Name,Last Name) values ? ` , (err, result)=> {
if (err) {
console.error('Something bad happened: ' + err);
return res.status(500);
}
console.log('Response from controller', result);
res.json(result);
});
}
module.exports = {test}
and this is the router page
Router
router.post('/CreateOrganizer',(req,res)=>{
organizer.test
})
This is how you should proceed:
const con = mysql.createConnection({
host: "localhost",
user: "yourusername",
password: "yourpassword",
database: "mydb"
});
con.connect(function(err) {
if (err) throw err;
console.log("Connected!");
});
app.post('',(req, res, next) => {
const user = req.body;
// use the same key in the query that you are getting from body.
const sql = "INSERT INTO Admin (LoginID,Password,Preference,Name,Last Name)
VALUES ('user.LoginID', 'user.Password', 'user.Preference', 'user.Name''user.LastName')";
con.query(sql, function (err, result) {
if (err) {
console.error('Something bad happened: ' + err);
return res.status(500);
}
console.log("1 record inserted");
});
})
There are several tutorials available online that can help you to achieve the same.

MySQL isolation levels in nodejs. Is each query in connection isolated or each pool isolated?

My current isolation level for MySQL is tx_transaction = REPEATABLE-READ for each session.
So when I run the below code in different terminals the transactions are serially executed, meaning before the commit of the first transaction, the second would not start.
START TRANSACTION;
SELECT *
FROM test
WHERE id = 4 FOR UPDATE;
UPDATE test
SET parent = 98
WHERE id = 4;
So if I implement this in nodeJS, which of the following would give same result as running two terminals?
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'localhost',
user : 'me',
password : 'secret',
database : 'my_db'
});
connection.connect();
let query =
START TRANSACTION;
SELECT *
FROM test
WHERE id = 4 FOR UPDATE;
UPDATE test
SET parent = 98
WHERE id = 4;
connection.query(query, function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
connection.query(query, function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
});
connection.end();
or using pools
var mysql = require('mysql');
var pool = mysql.createPool({
connectionLimit : 10,
host : 'example.org',
user : 'bob',
password : 'secret',
database : 'my_db'
});
let query =
START TRANSACTION;
SELECT *
FROM test
WHERE id = 4 FOR UPDATE;
UPDATE test
SET parent = 98
WHERE id = 4;
pool.query(query, function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
connection.release();
});
pool.query(query, function (error, results, fields) {
if (error) throw error;
console.log('The solution is: ', results[0].solution);
connection.release();
});
My first guess was that the pools would create separate connections and sending queries in same connection would be same as typing in queries in the same terminal. However the documentation says https://github.com/mysqljs/mysql#pooling-connections under introduction section that
Every method you invoke on a connection is queued and executed in
sequence.
and I am not exactly sure what that means.
Also, if I use connection pooling, can I be 100% sure that the concurrently running queries are handled by different sessions? So for example if the pool is not released in the first query, would the second query ALWAYS be executed by another session?
I have done a few tests and realized that Connection Pooling results to the expected outcome.
when I do the following with just connection
let pool = mysql.createConnection({
connectionLimit:10,
host: 'localhost',
user: 'root',
password: 'thflqkek12!',
database: 'donationether'
});
connection.beginTransaction(function (err) {
console.log('first transaction has started');
if (err) {
console.log(err);
return;
}
connection.query(`INSERT INTO users VALUES (null, 0, 'username', 'token')`, function (err, results, fields) {
if (err) {
console.log(err);
return;
}
setTimeout(function () {
connection.commit(function (err) {
if (err) {
console.log(err);
return;
}
console.log('first query done');
connection.release();
})
}, 2000)
});
});
connection.beginTransaction(function (err) {
console.log('second transaction has started');
if(err) {
console.log(err);
return;
}
connection.query(`UPDATE users SET username = 'c_username' WHERE username = 'username'`,function (err, results, fields) {
if(err) {
console.log(err);
return;
}
connection.commit(function (err) {
if(err) {
console.log(err);
return;
}
console.log('second query done');
connection.release();
})
});
});
It leads to following output
first transaction has started
second transaction has started
second query done
first query done
Meaning that the transaction opened by the first connection is ignored and the second transaction finishes before. However, when I use connection pooling for following code,
let pool = mysql.createPool({
connectionLimit:10,
host: 'localhost',
user: 'root',
password: 'thflqkek12!',
database: 'donationether'
});
pool.getConnection(function (err, connection) {
connection.beginTransaction(function (err) {
console.log('first transaction has started');
if (err) {
console.log(err);
return;
}
connection.query(`INSERT INTO users VALUES (null, 0, 'username', 'token')`, function (err, results, fields) {
console.log('first query has started');
if (err) {
console.log(err);
return;
}
setTimeout(function () {
connection.commit(function (err) {
if (err) {
console.log(err);
return;
}
console.log('first query done');
connection.release();
});
}, 2000)
});
});
});
pool.getConnection(function (err, connection) {
connection.beginTransaction(function (err) {
console.log('second transaction has started');
if(err) {
console.log(err);
return;
}
connection.query(`UPDATE users SET username = 'c_username' WHERE username = 'username'`,function (err, results, fields) {
console.log('second query has started');
if(err) {
console.log(err);
return;
}
connection.commit(function (err) {
if(err) {
console.log(err);
return;
}
console.log('second query done');
connection.release();
})
});
});
});
The output is as following
first transaction has started
second transaction has started
first query has started
//2seconds delay
second query has started
first query done
second query done
meaning that the first transaction is blocking the second transaction from executing.
So when the documentation said
Every method you invoke on a connection is queued and executed in sequence
It meant that they are delivered to the database in sequence but it will still be asynchronous and parallel even under transaction. However, connection pooling leads to instantiation of multiple connections and transaction within different pool connection behaves as expected for each transaction.

nodejs mysql query doesn

I want to check if some date exist in a table, if not I want to insert it. I have done this in other project and there it works but now i don't know why it doesn't work.
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '',
user : '',
password : '',
database : ''
});
[..]
connection.query('SELECT id FROM users [...]', function(err, results) {
if (err) {
throw err;
} else if (results.length==1) {
callback(null, results[0].id);
} else {
console.log('before insert');
connection.query('INSERT INTO users SET ?', user, function(err, result) {
console.log('insert');
if (err) throw err;
});
}
});
The query with INSERT doesn't work, but if i get that query out of the SELECT query then it works.
Doesn't matter if it is INSERT or other query.
In console I only see: 'before insert' and no error.
This query it's in a loop.
You have syntax error in insert statement, it has to be:
connection.query('INSERT INTO users (`id`) VALUES (?)', user, function(err, result) {
console.log('insert');
if (err) throw err;
});
You could also optimise the code to run a single query only, using INSERT IGNORE syntax. If record already exists, MySQL will just ignore the insert, without giving any errors. But your field id has to be set as primary key.
Optimised, the code will look like:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '',
user : '',
password : '',
database : ''
});
[..]
connection.query('INSERT IGNORE INTO users (`id`) VALUES (?)', user, function(err, results) {
if (err) {
throw err;
} else {
callback(null, user);
}
});