I am working on a node js app which makes use of the express and mysql libraries.
I have a MySQL user table with the following columns:
auto incrementing primary id
username varchar unique
There is no password, etc.
Other tables include:
room
id
room_name
user_room
id
user_id (FK to user table)
room_id (FK to room table)
details
id
user_room_id (FK to user_room table)
col1
col2
col3
Upon trying to connect to a room, I want the database to try pulling their data for that room.
If the data does not exist, I want to see if the username exists in the user table.
If the username does exist, I want to get their id.
If the username does not exist, I want to add their name to the user table and capture the last inserted id
Once having their id, I want to add a record to the user_room table for that user and then several records to the details table based on the newly inserted id in the user_room table.
I seem to be getting into a tangled web going into so many layers.
This is what my code currently looks like:
socket.on('enter room', function(data, callback){
var sql = "select col1, col2, col3 from room JOIN user_room on room.id = user_room.room_id JOIN user on user_room.user_id = user.id JOIN details on user_room.id = details.user_room_id where username = ?";
db_connection.query(sql, [socket.nickname], function (err, result) {
if (err){
console.log("ENTER ROOM DB ERROR: " + err);
return;
}
if (!result.length){
var sql = "select id from user where name = ?";
db_connection.query(sql, [socket.nickname], function (err, result){
if (err){
console.log("ENTER ROOM, SELECT ID DB ERROR: " + err);
return;
}
if (!result.length){
var sql = "insert into user (name) values (?)";
db_connection.query(sql, [socket.nickname], function(err, result){
if (err){
console.log("ENTER ROOM, INSERT ID DB ERROR: " + err);
return;
}
id = result.insertId;
});
}
else {
id = result[0].id;
}
});
//We need to pull things back into one branch again here
//Using the user id and room id I will insert a record into the user_room table
//Then using the newly inserted id in the user_room table, I need to add records to a details table
}
});
//Send col1, col2, and col3 data back to user
//This section here also needs to be pulled back into one branch again
io.sockets.emit('details', result);
});
It mostly works, but because I branch off in two different ways to get the user id (one if it already exists, and one if I need to insert it), I do not know how to pull it back together again into one branch.
What can I do to pull my code back into one branch again so that I can use the id again? Or, is there a better way of approaching this altogether?
A side question: Can I safely remove the "callback" in my opening function, or should I be using this somewhere in my code? I feel that the emit is like a callback to the client so that I do not need "callback" here.
I took a different approach to get userId on upsert. I used promise to send the room data immediately, if available.
socket.on('enter room', function (data, callback) {
let nickName = '';
let roomId = '';
return bookingDetails(nickName).then((details) => {
if (details.length !== 0) {
return Promise.resolve(details);
} else {
return createRoom(nickName, roomId);
}
}).then((details) => {
io.sockets.emit('details', details);
});
});
function createRoom(nickName, roomId) {
return getUserDetails(nickName).then((userId) => {
return insertUserRoom(userId, roomId); //your function
}).then((userRoomDetails) => {
return insertDetails(userRoomDetails); //your function
});
}
function bookingDetails(nickName) {
let sql = "select col1, col2, col3 from room " +
"JOIN user_room on room.id = user_room.room_id " +
"JOIN user on user_room.user_id = user.id " +
"JOIN details on user_room.id = details.user_room_id where username = ?";
return new Promise((resolve, reject) => {
db_connection.query(sql, [nickName], function (err, details) {
if (err) {
return reject("ENTER ROOM DB ERROR: ");
}
return resolve(details);
});
});
}
function getUserDetails(nickName) {
return new Promise((resolve, reject) => {
let sql = "select id from user where name = ?";
db_connection.query(sql, [nickName], function (err, userDetail) {
if (err) {
return reject(err);
}
if (userDetail === null) { //insert
return createUser(nickName);
}
return userDetail;
}).then((userDetail) => {
return resolve(userDetail.id);
});
});
}
function createUser(nickName) {
return new Promise((resolve, reject) => {
let sql = "insert into user (name) values (?)";
db_connection.query(sql, [nickName], function (err, userDetail) {
if (err) {
return reject(err);
}
return resolve(userDetail);
});
});
}
Related
I want to write a query in MySQL for filtering. For example, if there is a column id in table table1 where the filter values for id come in a POST request body, saved in variable A. I want to extract the matching rows if A is not empty and return all rows otherwise. I am not sure about using IN with WHERE.
SELECT * FROM table1 WHERE id IN (A)
One option is that I return all rows from the database and use JavaScript filters, but I don't want to return all rows and expose the entire table to user.
NOTE: A can be a single value, a tuple or an array.
If you use javascript, use A.join(), and sanitize your POST.
var your_post = [1, 2, 3];
var A = your_post.join();
if (A == '') {
var sql = 'SELECT * FROM table1';
con.query(sql, function (err, result) {
if (err) throw err;
console.log(result);
});
} else {
var sql = 'SELECT * FROM table1 WHERE id IN (?)';
con.query(sql, [A], function (err, result) {
if (err) throw err;
console.log(result);
});
}
thanks for reading.
I have a table with 3 fields, one is the ID, which autoincrements and I can´t access it from my Node.js server since it's added by MySql. Another field contains a string, and the last field should be the sum of the 3 first letters of the string field, added to the id.
The thing is, when I do my query I can't just add them up because the id doesn´t exist until the query is sent to the DB.
What should I do? It'd be such an inconvenience to handle the ID autoincrement from the API.
Thanks for your time!
After you insert the row, you can get its ID and update the third column.
connection.query('INSERT INTO yourTable (name) VALUES (?)', [name], function(err, result) {
if (err) {
throw err;
}
let code = name.substr(0, 3) + result.insertId;
connection.query('UPDATE yourTable SET code = ? WHERE id = ?', [code, result.insertId], function(err) {
if (err) {
throw err;
}
});
});
However, this won't work if you're inserting multiple rows in bulk, since result.insertId is just the last row that was inserted.
You could update all the rows where the code
connection.query('INSERT INTO yourTable (name) VALUES ?', names.map(n => [n]), function(err, result) {
if (err) {
throw err;
}
connection.query('UPDATE yourTable SET code = CONCAT(SUBSTR(name, 1, 3), id) WHERE code IS NULL', function(err) {
if (err) {
throw err;
}
});
});
I am building an app where my users can have friends and I store them in a table like this
uid | ownerUid | friendUid
and then I have a users database like this
uid | username | password
and I am trying to make a system to where the user enters the uid of a user into a text box and it adds him as a friend if he is a user and if he is not already his friend using this code
connection.query("SELECT * FROM users WHERE uid = ?", [friendToAddUid], function(err, rows) {
if(rows){
rows.forEach(function(row) {
//is an actual person
connection.query("SELECT * FROM friends WHERE ownerUid = ?", [uid], function(err, rows) {
if(rows){
console.log("user exist")
rows.forEach(function(row){
if (row.friendUid = friendToAddUid){
}else{
var timestamp = new Date().toLocaleDateString("en-US") + ", " + new Date().toLocaleTimeString("en-US");
var row = [ uniqid(), uid, friendToAddUid, timestamp];
connection.query('INSERT INTO friends SET uid=?, ownerUid=?, friendUid=?, since=?', row, function(err) {
console.log(err)
});
}
})
if(rows.length <= 0){
var timestamp = new Date().toLocaleDateString("en-US") + ", " + new Date().toLocaleTimeString("en-US");
var row = [ uniqid(), uid, friendToAddUid, timestamp];
connection.query('INSERT INTO friends SET uid=?, ownerUid=?, friendUid=?, since=?', row, function(err) {
console.log(err)
});
}
}else{
var timestamp = new Date().toLocaleDateString("en-US") + ", " + new Date().toLocaleTimeString("en-US");
var row = [ uniqid(), uid, friendToAddUid, timestamp];
connection.query('INSERT INTO friends SET uid=?, ownerUid=?, friendUid=?, since=?', row, function(err) {
console.log(err)
});
}
})
})
}
})
it adds the user fine and won't add him if he is already your friend but I cant add any more friends after I add one friend and I don't know why
wanted to know if there is an issue with my MySQL query
I'm trying to update a TEXT field in a MYSQL table. I can't get the UPDATE query to work, even though the original INSERT attempt works fine when the user doesn't exist.
The purpose of the function is to INSERT new row if the user doesn't exist yet, and to UPDATE the textColumn (that always contains a JSON) if the user already exists in the table.
My code:
let first = 'jake';
let last = 'mcdonald';
let first_json = JSON.stringify({a:7, b:7});
let second_json = JSON.stringify({a:'updated'});
const row = {
name: first,
last_name: last,
textColumn: first_json,
}
db.query(`SELECT * FROM tableName
WHERE name="${first}"
AND last_name="${last}"`, (err, result) => {
if (err) console.log(err);
if (result.length < 1) {
db.query(`INSERT INTO tableName SET ?`, row, (err, result) => {
console.log('NEW ROW CREATED: ', result);
})
} else if (result.length > 0) {
console.log('ROW EXISTS');
db.query(`UPDATE tableName
SET textColumn=${second_json}
WHERE name="${first}"
AND last_name="${last}"`, (err, result) => {
console.log('UPDATED: ', result);
}
)
}
}
)
the else if section is what is giving me issues: I reach the inside console.log('ROW EXISTS') but the Update query logs "undefined".
The same UPDATE query works if I try to UPDATE tableName SET name="someNewName" WHERE last_name="original_last_name", but nothing happens when I try to UPDATE the textColumn.
Basically I have two table
User -> id, name , email , fname, lname etc...
Device -> id, name, user_id, etc......
here first I will insert data into User table and I get result,
from that result how to get the Id of the User table entry so that I can use is as user_id for the entry in device
basically user_id is foreign key referring User table
My insert code goes like this
exports.user = function(req,res){
var user_email = req.param('email', null);
var user_fname = req.param('fname', null);
var user_lname = req.param('lname', null);
var user_phone = req.param('phone', null);
var user_description = req.param('description',null);
var user_data = {
table:TABLE_USER,
data:{
'email':user_email,
'fname':user_fname,
'lname':user_lname,
'phone':user_phone,
'description':user_description
}
}
db.insert(user_data,function (result) {
//How to get the ID of the last inserted row from result,
// get Id and insert in device table
res.writeHeader(200, {"Content-Type": "text/plain"});
res.write(result[0] + " ");
res.end();
}
);
}
Just have a look at the documentation : Getting the id of an inserted row
Their code example :
connection.query('INSERT INTO posts SET ?', {title: 'test'}, function(err, result) {
if (err) throw err;
console.log(result.insertId);
});