let static_times_generate = async (static_file_path) => {
//Import MySQL database pool connection:
const db = require('../database_pool.js');
const Promise_pool = db.promise();
//Import Static Text file dependencies:
const { readFile } = require('fs/promises') , stop_times = static_file_path+'/stop_times.txt', trips = static_file_path+'/trips.txt';
let trip_data = (await readFile(trips,'utf8')).split('\n').slice(1,2);
let stop_times_data = (await readFile(stop_times,'utf8')).split('\n').slice(1,-1);
trip_data.forEach(trip_line => {
const t_array = trip_line.split(',');
stop_times_data.forEach(st_line =>{
const st_array = st_line.split(',');
if(st_array[0] == t_array[2]){
if(t_array[1] == 'SundaySum'){ t_array[1] = 'Sunday' }
else if(t_array[1] == 'SaturdaySum'){ t_array[1] = 'Saturday' }
//Here is the issue
await Promise_pool.execute(`INSERT INTO static_times (1, 2, 3, 4, 5, 6, 7) VALUES (?,?,?,?,?,?,?)`
,[elm1,elm2,elm3,elm4,elm5,elm6,elm7] )
}
});
});
console.log("COMPLETED!")
}
static_times_generate('./mysql_table_generators/STATIC_FILES'); //This is how i'm calling the function
I read files and push certain data into a MySQL database, I'm using node mysql2 for this.
let trip_data = (await readFile(trips,'utf8')).split('\n').slice(1,2);
let stop_times_data = (await readFile(stop_times,'utf8')).split('\n').slice(1,-1);
The readFile promises are being awaited just fine, but when it comes to the Promise_pool query, it's giving the error:
await Promise_pool.execute(`INSERT INTO static_times (routeId, serviceId, tripId, stopId, arrivalTime, orientation, tripHeadsign) VALUES (?,?,?,?,?,?,?)`
^^^^^
SyntaxError: await is only valid in async function
at wrapSafe (internal/modules/cjs/loader.js:979:16)
at Module._compile (internal/modules/cjs/loader.js:1027:27)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
at Module.load (internal/modules/cjs/loader.js:928:32)
at Function.Module._load (internal/modules/cjs/loader.js:769:14)
at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:72:12)
at internal/main/run_main_module.js:17:47
I've done this kind of await in other files of my code, and it worked, Why isn't it recognizing that the await is wrapped in an async function? (I've also tried the await db.execute method, without using the db.promise() prototype)
This is my database_pool.js file
const mysql = require('mysql2');
const db_pool = mysql.createPool({
host: 'localhost',
user: 'root',
password: '',
database: 'drt_sms_db',
multipleStatements: true
});
module.exports = db_pool;
*** Yes I know I don't need the await, however i'm inserting 1 million rows into my database, so I get a MySQL ETIMEOUT error. await is my only option at this point.
The scope of your await call is restricted to the forEach callback function. If you want to use await you can add async to the forEach callback like this:
stop_times_data.forEach(async (st_line) => {
await doSomething();
}
That being said, the callback function here does not actually wait for the promise to finish since forEach accepts only synchronous functions. Have a look here for more details. If you need to wait for one request to finish before sending another one you should use a for loop instead.
Related
Here I am working on node js typescript and mysql api, after excecuting my api showing undefined.
if i check using console in params variable i am getting result
like this in terminal
[
1,
'2023-02-09T12:27:09+05:30',
'2023-02-09T12:27:09+05:30',
'jaga78',
'988888888',
'jagadeeshwaran907#gmail.com',
'123',
'0'
]
if i check console using 2nd variable addedUser showing undefined
here i have attached my api
const loginemail = async (req: Request, data:any ) => {
const connection = await createConnection()
try {
let sqlQuery = `INSERT INTO account (status,created_date,updated_date,username,phone,email,password,verified) VALUES (?,?,?,?,?,?,?,?)`
const params = [data.accountStatus,moment().format(),moment().format(),data.userName, data.Phone, data.accountEmail, data.Password,"0"]
const addedUser:any = await connection.execute(sqlQuery, params);
return {success: "success"}
} catch (error) {
await connection.end()
throw error
}
}
I'm developing a simple GET endpoint using NodeJS, express and MySql, but whenever i use the mysql.query('select * from table'), through an service, the server is shutdown. The same query is successful when i declare it in the database.js file, but not when integrated with the rest of my system.
My database.js is as follows:
const mysql = require("mysql");
const con = mysql.createConnection({
host: "localhost",
user: "root",
password: "rootpwd",
port: 3306,
database: "blog",
});
con.query("select * from post", (er, row) => {
if (er) throw er;
console.log(row);
return row;
});
This con.query function is only declared for test purpose, and deleted when endpoint is called. When i run my server and this query is declared, it logs in my console all the content in this table.
When i run node database.js all my entries in posts table are shown in console.
But when i call, in another file,
database.query('select * from post', (er, rows) => { if (er) throw er return rows })
The localhost is shutdown with the following message:
-> starting at object with constructor 'Query'
| property '_timer' -> object with constructor 'Timer'
--- property '_object' closes the circle
at JSON.stringify (<anonymous>)
at stringify (/home/guilherme/Documentos/Projects/rest_api/node_modules/express/lib/response.js:1150:12)
at ServerResponse.json (/home/guilherme/Documentos/Projects/rest_api/node_modules/express/lib/response.js:271:14)
at /home/guilherme/Documentos/Projects/rest_api/server/route/postsRoute.js:7:19
at processTicksAndRejections (internal/process/task_queues.js:95:5)
I've installed body-parser in my project and i'm using express.json() as a middleware in my app:
const express = require("express");
const app = express();
app.use(express.json());
app.use("/", require("./route/postsRoute"));
app.listen(process.env.PORT || 3000, () =>
console.log(`Server running on port ${process.env.PORT || 3000}`)
);
My route file:
const express = require("express");
const router = express.Router();
const postService = require("../service/postService");
router.get("/posts", async (req, res) => {
const posts = await postService.getPosts();
res.status(200).json(posts);
res.end();
});
My Service file:
exports.getPosts = async () => {
const test = await postsData.getPosts();
console.log(test, "this is what is returned");
return test;
};
And finally, my data file:
exports.getPosts = () =>
database.query("select * from post;", (er, rows) => {
if (er) throw er;
return JSON.stringify(rows);
});
this JSON.strinfy was inserted for test purpose, and the error is returned the same way.
Node version: v14.18.0
dependecies:
"dependencies": {
"axios": "^1.2.1",
"body-parser": "^1.20.1",
"express": "^4.18.2",
"jest": "^29.3.1",
"mysql": "^2.18.1",
}
If anyone needs more information to help me debug this, please let me know.
I've tried parsing the content that is returned in my query, but it didn't returned anything useful. I've added async and awaits, but it didn't helped either.
I'm expecting to see all my tables content when i access the /posts route.
You're converting the result to JSON twice, in the data file and the services file. You should only do the JSON conversion in one place, not both.
I recommend doing it only in the service, so in the data code use
exports.getPosts = () =>
database.query("select * from post;", (er, rows) => {
if (er) throw er;
return rows;
});
So the main issue was that 'mysql' lib does not handle promises correctly.
I've added mysql2 and and changed my Data.js file to
database.promise().query("select * from post;");
And it works just fine now.
I am working on a discord.js bot, and I'm storing a bunch of information on various servers in a database. The problem is, that the code doesn't wait for the database to return the results. In the current situation, I'm trying to check if the server specific prefix checks out.
I tried using async and await at various places, but those didn't work. If I could, I'd rather not use .then(), because I don't really want to put all the commands inside a .then().
const { Client, Attachment, RichEmbed } = require('discord.js');
const client = new Client();
const mysql = require("mysql");
const config = require("./config.json")
var con = mysql.createConnection({
host: 'localhost',
user: 'root',
password: '',
database: 'botdb'
})
client.on("ready", () => {
console.log("I'm ready")
})
client.on("message", message => {
if (message.author.bot) return;
if (message.channel.type === 'dm') return;
let msg = message.content.split(" ");
let command = msg[0];
let prefix;
con.query(`SELECT * FROM serversettings WHERE ServerID = ${message.guild.id}`, (err, rows) => {
if (err) throw err;
prefix = rows[0].Prefix;
console.log(prefix)
})
console.log(`Prefix: ${prefix}, Command: ${command}`)
if (command === `${prefix}examplecommand`) {
//Do something
}
//Other code that uses prefix and command
}
It should log the prefix first, and then the Prefix: ${prefix}, Command: ${command} part, but it does it the other way around, so the examplecommand doesn't work.
Your result is caused by the fact that what's outside your query callback is executed immediately after the call. Keep in mind the mysql module is callback-based.
Possible Solutions
Place the code inside the callback so it's executed when the query is completed.
Wrap the query in a promise and await it.
function getGuild(guildID) {
return new Promise((resolve, reject) => {
con.query(`SELECT * FROM serversettings WHERE ServerID = '${guildID}', (err, rows) => {
if (err) return reject(err);
resolve(rows);
});
});
}
const [guild] = await getGuild(message.guild.id) // destructuring 'rows' array
.catch(console.error);
console.log(guild.prefix);
Use a Promise-based version of a MySQL wrapper, like promise-mysql. You could use it the same way as the code above, without worrying about coding your own Promises.
const [guild] = await con.query(`SELECT * FROM serversettings WHERE serverID = '${message.guild.id}'`)
.catch(console.error);
console.log(guild.prefix);
I am using Node's async/await syntax,
I am trying to promisify a MySql function using Node's util library.
When trying to promisify mysql's begin transaction method,
I am getting the following error -
TypeError [ERR_INVALID_ARG_TYPE]: The "original" argument must be of type Function. Received type undefined
Code snippet -
let connection = requestBody.mysqlConnection;
try {
let createTransaction = util.promisify(connection.beginTransaction).bind(connection);
await createTransaction();
let insertQuery = util.promisify(connection.query).bind(connection);
let queryResponse = await insertQuery(sqlQuery, sqlData);
await connection.commit();
await connection.end();
response.insertId = queryResponse.insertId;
response.hasError = false;
return response;
} catch (error) {
console.log("RDS MySql Error : ", error);
await connection.rollback();
await connection.end();
response.hasError = true;
response.error = error;
return response;
}
Error trace -
Bind your mysql function before to promisify it, take a look on this small example:
const util = require('util')
function mysqlFn(params, callbk) {
callbk(null, true)
}
// bind first to make sure the first param is the callback after promisify the function
const mysqlFnBind = mysqlFn.bind(null, {param: 1})
const mysqlFnAsync = util.promisify(mysqlFnBind)
mysqlFnAsync().then(console.log)
I have a form with one field that allows user to enter multiple developer id via comma delimited (ab1234,bc5678).
Once the form is submitted I perform the following tasks:
Get the the project
Loop through array of developer IDs to get their full name using mySQL
update the project using MongoDB
I'm new and sure this this is possible, The codes I have below is not working for me. Can someone please let me know if the codes below is even close.
const mongoose = require('mongoose'
const mysql = require('mysql');
// Create mySQL connection
const mySQLdb = mysql.createConnection({
host : 'localhost',
user : 'root',
password : 'root',
database : 'projects'
});
const Project = mongoose.model('project');
router.post('/developerSave', async (req, res) => {
let devList = req.body.dev_ids,
devIdArr = devList.split(','),
rData = {};
// get project
const project = await Project.findById(req.body.projectID);
mySQLdb.connect();
for(var i=0, len=devIdArr.length; i < len; i++) {
let sql = `SELECT CONCAT(first_name, ' ', last_name) as full_name FROM users WHERE id= '${devIdArr[i]}'`;
mySQLdb.query(sql, function (err, results) {
if (err) throw err;
let newDev = {
userId: devIdArr[i],
fullName: results[0].full_name
}
project.developers.unshift(newDev);
await project.save();
});
}
mySQLdb.end();
rData.success = true;
rData.msg = 'Developer was added successfully.';
res.status(200).json(rData);
});
The reason you are seeing this is because your await project.save(); is inside the callback function. Your main function will not wait for all the callbacks to complete and close the db connection. Lets look at the example below
const myCallback = (param, callback) => {
setTimeout(() => {
console.log('callback function', param);
callback();
}, 1000)
}
const myAsync = async () => {
console.log('inside async');
const result = await axios.get('http://google.com/');
for (let i = 0; i < 10; i++) {
myCallback(i, () => {
console.log('this is the actual callback function');
});
}
const result2 = await axios.get('http://bing.com/');
console.log('after second call');
}
myAsync();
The output of this is
inside async
after second call
callback function 0
this is the actual callback function
...
As you can see, the after second call is printed before the callback functions.
To solve this problem, you can wrap your callback function in a promise and resolve that once save is complete.