Stored Procedure for node.js - mysql

User.createuser = (req, result) => {
sql.query("INSERT INTO Users SET ?", req, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
// if (await User.findOne({ where: { username: req.body.username } })) {
// throw 'Username "' + req.body.username + '" is already taken';
// }
console.log("created User: ", { id: res.insertId, ...req });
result(null, { id: res.insertId, ...req });
});
};
Example json object for api create route (post method)
{
"username": "seve",
"user_name": "sev123",
"user_surname": "avcı",
"email": "sevre#gmail.com",
"user_type": "user",
"password": "123456"
}
The "INSERT INTO Users SET ?" query that I use in my code, I want it as a stored procedure, I want it to handle the stored procedure id itself, what is the equivalent of this code's stored procedure?

INSERT INTO users (username, user_name, user_surname, email, user_type, password)
SELECT x->>'$.username', x->>'$.user_name', x->>'$.user_surname', x->>'$.email', x->>'$.user_type', x->>'$.password'
FROM ( SELECT ? AS x ) jsondata
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=f190bb4b9d4c3e4003bae631af901d72

Related

NodeJS/MySQL: Use Results of Previous SELECT Query?

Building a simple ToDo app in React/NodeJS/Express with MySQL. Users join a group ("family" in the code), then tasks are viewable filtered by familyId. To create a task, I first have a query that finds the user's familyId from the Users table, then I want to include that familyId value in the subsequent INSERT query for creating the task row in the Tasks table. My task.model.js is below:
const sql = require("./db.js");
// constructor
const Task = function(task) {
this.title = task.title;
this.familyId = task.familyId;
this.description = task.description;
this.completed = task.completed;
this.startDate = task.startDate;
this.userId = task.userId;
};
Task.create = (task, result) => {
sql.query("SELECT familyId FROM users WHERE userId = ?", task.userId, (err, res) => {
if (err) {
console.log("Error selecting from USERS: ", err);
return result(err, null);
}
sql.query("INSERT INTO tasks (familyId, title, description, completed, startDate) VALUES (?,?,?,?,?)", [result, task.title, task.description, task.completed, task.startDate], (err, res) => {
if (err) {
console.log("Error inserting in TASKS: ", err);
return result(err, null);
}
})
console.log("created task: ", { id: res.insertId, ...task });
return result(null, { id: res.insertId, ...task });
});
};
However, I cannot figure out how to properly use the familyId result of the SELECT query as a parameter in the suqsequent INSERT query. I know the overall syntax works because I can manually plug in an ID value as a parameter and the entire operation completes successfully - I just need to know how to use the resule of the first query in the next.
The way you are using it should work but the problem is you have defined the callback as res but are passing result in the 2nd sql query
sql.query("SELECT familyId FROM users WHERE userId = ?", task.userId, (err, res) => {
if (err) {
console.log("Error selecting from USERS: ", err);
return result(err, null);
}
//res should have the value for the familyId of the given user so in next line pass res not result
sql.query("INSERT INTO tasks (familyId, title, description, completed, startDate) VALUES (?,?,?,?,?)", [res[0].familyId, task.title, task.description, task.completed, task.startDate], (err, res) => {
if (err) {
console.log("Error inserting in TASKS: ", err);
return result(err, null);
}
})
console.log("created task: ", { id: res.insertId, ...task });
return result(null, { id: res.insertId, ...task });
});
SQL returns array in result , so use result[0] to get first Object ,
and then access the object key by result[0].keyName
Task.create = (task, result) => {
sql.query("SELECT familyId FROM users WHERE userId = ?", task.userId, (err, users) => {
if (err) {
console.log("Error selecting from USERS: ", err);
return result(err, null);
}
let familyId = users && users[0] ? users[0].familyId : null;
sql.query("INSERT INTO tasks (familyId, title, description, completed, startDate) VALUES (?,?,?,?,?)", [familyId, task.title, task.description, task.completed, task.startDate], (err, res) => {
if (err) {
console.log("Error inserting in TASKS: ", err);
return result(err, null);
}
})
console.log("created task: ", { id: res.insertId, ...task });
return result(null, { id: res.insertId, ...task });
});
};

NodeJS - Update MySQL Field after fetching new created id

I'm using NodeJS to insert a row into MySQL with a "title", "userid" and "opid" field ;
After insertion, I'd like to use the newly created id and the userid to create a new string called "audioname".
Then I'd like update a field called "audioname" with this new "audioname" string
Here's the code I'm using to create the audioname;
const audiopost = new Audiopost({
title: req.body.title,
userid: req.body.userid,
opid: req.body.opid
});
Audiopost.create(audiopost, (err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Some error occurred while creating the Audiopost."
});
else
var newaudioid = data.id.toString();
var newuserid = data.userid.toString();
var hyphen = "-";
var m4a = ".m4a"
var newaudioname = newuserid + hyphen + newaudioid + m4a;
res.send(newaudioname);
});
};
And here's the model;
const Audiopost = function(audiopost) {
this.userid = audiopost.userid;
this.title = audiopost.title;
this.opid = audiopost.opid;
};
Audiopost.create = (newAudiopost, result) => {
sql.query("INSERT INTO audioposts SET ?", newAudiopost, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
console.log("created audiopost: ", { id: res.insertId, ...newAudiopost });
result(null, { id: res.insertId, ...newAudiopost });
});
};
This will help you I believe,
sql.query("INSERT INTO audioposts SET ?", newAudiopost, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
const insertId = res.insertId;
const userId = newAudiopost.userid;
const m4a = ".m4a";
const audioname = ${insertId}-${userId}${m4a}; //You can change this string in any format
sql.query("UPDATE audioposts SET audioname = ? WHERE id = ?", [audioname, insertId], (err, res, fields) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
})
});

NodeJS Json Return id only?

Here's the NodeJS code I'm using to create a customer in my MySql database;
const customer = new Customer({
email: req.body.email,
name: req.body.name,
active: req.body.active
});
Customer.create(customer, (err, data) => {
if (err)
res.status(500).send({
message:
err.message || "Some error occurred while creating the Customer."
});
else res.send(data);
});
};
Heres' the model;
const Customer = function(customer) {
this.email = customer.email;
this.name = customer.name;
this.active = customer.active;
};
Customer.create = (newCustomer, result) => {
sql.query("INSERT INTO customers SET ?", newCustomer, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
console.log("created customer: ", { id: res.insertId, ...newCustomer });
result(null, { id: res.insertId, ...newCustomer });
});
};
And here's what I'm getting in return;
{"id":8,"email":"harry#gmail.com","name":"harry","active":1}
How can I get it to return just the id as a plain integer instead of the entire JSON string?
To get the specific property from the object. e.g. id, access it as data.id and id is an number which will be treated as status code in express so toString() is needed to convert it to string
The response should be:
res.send(data.id.toString())

Save google authenticated user into mysql database with node.js and passport.js

I build a simple web application where the user has notes. I want the user to be able to sign in with a google account as well, but the user didn't save into the database. The local login works but the social login doesn't. Wherever I searched I only found a solution in which mongodb was used. What is the correct way with mysql?
Here is my passport.js file:
passport.serializeUser((user, done) => {
done(null, user);
});
passport.deserializeUser((req, user, done) => {
conn.query("SELECT * FROM user WHERE id = ? OR facebook_id = ? OR google_id", [user.id,
user.facebook_id, user.google_id], (err, rows) => {
if (err) {
console.log(err);
return done(null, err);
}
done(null, user);
});
});
passport.use(new GoogleStrategy({
clientID: configAuth.googleAuth.clientID,
clientSecret: configAuth.googleAuth.clientSecret,
callbackURL: configAuth.googleAuth.callbackURL,
passReqToCallback: true,
profileFields: configAuth.googleAuth.profileFields
},
function (req, accessToken, refreshToken, profile, done) {
process.nextTick(function () {
conn.query("SELECT * FROM user WHERE google_id = ?", [profile.id], (err, user) => {
if (err) {
return done(err);
} else if (user) {
return done(null, user);
} else {
let newUser = {
google_id: profile.id,
google_token: accessToken,
google_email: profile.emails[0].value,
google_name: profle.name.givenName + ' ' + profile.name.familyName
};
conn.query("INSERT INTO user (google_id, google_token, google_email, google_name) VALUES (?, ?, ?, ?)",
[newUser.google_id, newUser.google_token, newUser.google_email, newUser.google_name], (err, rows) => {
if (err) {
console.log(err);
}
return done(null, newUser);
})
}
});
});
}
));
And here are the routes:
app.get('/auth/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
app.get('/auth/google/callback', passport.authenticate('google', {
successRedirect: '/main',
failureRedirect: '/'
}));
I can log in, I didn't receive an error message, but if I want to assign a new note to the user it doesn't add it because it doesn't save the user to the database.
I think you forget to put ? after the google_id.
Example:
google_id=?

Error retrieving Entry with AreaName in node.js

I am trying to perform a get with multiple parameters in node.js . I have the following files
entry.routes.js
module.exports = app => {
const entry = require("../controlers/entry.controller.js");
// Retrieve a single Entry with Id
app.get("/entry/:Id", entry.findOne);
app.get("/energy/api/ActualTotalLoad/:AreaName/:Resolution/:Year/:Month/:Day", entry.find1a);
};
ActualTotalLoad.model.js
const sql = require("./db.js");
// constructor
const Entry = function(entry) {
this.Id=entry.Id
};
Entry.findByPk = (Id, result) => {
sql.query(`SELECT * FROM ActualTotalLoad WHERE Id = ${Id}`, (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
if (res.length) {
console.log("found entry: ", res[0]);
result(null, res[0]);
return;
}
// not found Customer with the id
result({ kind: "not_found" }, null);
});
};
Entry.findBy1a = (AreaName,Resolution,Year,Month,Day,result) => {
sql.query(`SELECT AreaName,AreaTypeCodeId,MapCodeId,ResolutionCodeId,Year,Month,Day FROM ActualTotalLoad WHERE AreaName = ${AreaName} AND ResolutionCodeId = ${Resolution} AND Year = ${Year} AND Month = ${Month} AND Day = ${Day}` , (err, res) => {
if (err) {
console.log("error: ", err);
result(err, null);
return;
}
if (res.length) {
console.log("found entry: ", res[0]);
result(null, res[0]);
return;
}
// not found Customer with the id
result({ kind: "not_found" }, null);
});
};
module.exports=Entry;
and the file: entry.controller.js
const Entry = require("../models/ActualTotalLoad.model.js");
// Find a single Customer with a customerId
exports.findOne = (req, res) => {
Entry.findByPk(req.params.Id, (err, data) => {
if (err) {
if (err.kind === "not_found") {
res.status(404).send({
message: `Not found Entry with id ${req.params.Id}.`
});
} else {
res.status(500).send({
message: "Error retrieving Entry with id " + req.params.Id
});
}
} else res.send(data);
});
};
exports.find1a = (req, res) => {
Entry.findBy1a(req.params.AreaName,req.params.Resolution,req.params.Year,req.params.Month,req.params.Day, (err, data) => {
if (err) {
if (err.kind === "not_found") {
res.status(404).send({
message: `Not found Entry with AreaName ${req.params.AreaName}.`
});
} else {
res.status(500).send({
message: "Error retrieving Entry with AreaName " + req.params.AreaName
});
}
} else res.send(data);
});
};
I am trying to perform this get http://localhost:8765/energy/api/ActualTotalLoad/DE-AT-LU/7/2018/1/4
But I get the error "message": "Error retrieving Entry with AreaName DE-AT-LU"
What am I doing wrong?
You should change your WHERE statement like this
SELECT ... WHERE AreaName = "${AreaName}" AND ResolutionCodeId = ${Resolution} AND Year = ${Year} AND Month = ${Month} AND Day = ${Day}
Note: notice the quotes ( "${AreaName}" )
AreaName in your DB schema is problably typed as string (or text), so you need to quote you search criteria as string (surrounding it by " or ')
I assume that ResolutionCodeId, Year Month, and Day are number types, so it's ok to not quote them.