Reputation: 97
I know you might mark it as duplicate or downvote it. but I am unable to figure out a solution despite searching over forums and google. I am basically trying to create a migration system for MySQL nodejs. Code:
const table = require('../orm/Migration');
module.exports = {
async up(connection) {
table.newTable()
table.name('user_sessions')
console.log("SENT TABLE NAME")
table.id()
table.string('username').nullable()
table.string('ip').nullable()
table.boolean('success').default(true)
table.timestamps()
console.log("Finalizing")
var d=await table.finalize()
console.log("after sending finalization")
return d
}
}
Migration.js
if (connected) {
try{
var c= await connection.query(sql_query)
console.log("Created table. "+this.table_name + JSON.stringify(c))
}
catch(ex)
{
console.log(ex)
}
}
else
{
throw("Not connected to database.")
}
Main trigger function
var mysql= require('mysql2/promise');
require('dotenv').config()
const fs = require('fs');
const { connect } = require('tls');
var path = require('path');
(async () => {
try{
var connected=true
console.log("Connecting to database")
try{
var connection =await mysql.createConnection({
host : process.env.DB_HOST,
user : process.env.DB_USERNAME,
password : process.env.DB_PASSWORD,
database : process.env.DB_NAME
});
// connection.connect();
console.log("Connected")
}
catch(exce)
{
console.log(exce)
connected=false
}
if(connected)
{
var dirname = "migrations"
console.log("\nMigrating");
var rootpath=path.resolve(__dirname + "/migrations")
fs.readdirSync(rootpath).forEach(function (dirContent) {
var fclass=dirContent
var fc=dirContent.replace(".js","")
const fname = rootpath+"/" + fc;
const migration = require(fname);
(async () => {
try{
console.log("Before Up call of:" + fc)
const upcall =await migration.up(connection);
console.log("Upcall returned from " + fc + upcall)
console.log("After upcall of :"+ fc)
}
catch(exc)
{
console.log(exc)
}
console.log("Migrating done")
})()
})
// process.exit(0)
}
else
{
console.log("Not connected to database")
// process.exit(0)
}
}
catch(exc)
{
console.log(exc)
}
})()
Console output
Connecting to database
Connected
Migrating
Before Up call of:sessions
Setting Table_name to:user_sessions
SENT TABLE NAME
Finalizing
Before Up call of:users
Setting Table_name to:users
Before Up call of:users2
Setting Table_name to:sessions
Created table. sessions[{"fieldCount":0,"affectedRows":0,"insertId":0,"info":"","serverStatus":2,"warningStatus":1},null]
after sending finalization
Upcall returned from sessionstrue
After upcall of :sessions
Migrating done
Created table. sessions[{"fieldCount":0,"affectedRows":0,"insertId":0,"info":"","serverStatus":2,"warningStatus":1},null]
after await . true
Upcall returned from users2true
After upcall of :users2
Migrating done
Created table. sessions[{"fieldCount":0,"affectedRows":0,"insertId":0,"info":"","serverStatus":2,"warningStatus":1},null]
Upcall returned from userstrue
After upcall of :users
Migrating done
I don`t know why async await is behaving this way. I am expecting something like
Before Up call of:users
Setting Table_name to:users
Created table. users[{"fieldCount":0,"affectedRows":0,"insertId":0,"info":"","serverStatus":2,"warningStatus":1},null]
after sending finalization
Upcall returned from users
because that's the correct order of execution. As all functions are async and every call is put in await. whats wrong with nodejs
Nodejs Version v14.15.3
Upvotes: 0
Views: 107
Reputation: 895
The problem is that you are using forEach to iterate over migrations in main trigger function. Of course the forEach cannot be awaited from the outer async function. Here it is my suggestion(not tested)
async function migrate() {
var rootpath = ath.resolve(__dirname + "/migrations")
const migrationFilePaths = fs.readdirSync(rootpath);
for (const migrationPath of migrationFilePaths) {
let fc = migrationPath.replace(".js","")
const fname = rootpath +"/" + fc;
const migration = require(fname);
try {
await migration.up(connection);
}
catch(err) {
}
}
}
The await in for will be awaited by the migrate function.
Upvotes: 2