Node JS mySQL tripple query and lost of information - mysql

In my application I have a two different tables related to each other by ID of the first one (one to many relation). It should first collect the data from the frontend-side by in JSON format which looks like this:
cancellation = {
name: someting
id: someting
rule =
[
{someting}, {something}, {something}
]
}
One table would be for cancellation and the second one for the rules. If I want to put those information in this order I need first insert one record for cancellation. Then make a query to find out what is an ID of this record in the database and after that insert all rules using this ID as a foreign key. But since Node JS is asynchronous before I fetch the information about the ID of the record program stars to execute rest of the code and consider this variable as undefined.
app.post('/databaseSend/cancellation', function(req,res){
var cancellationReceived = req.body;
var cancellationID;
var rules = [];
var cancellation = [];
cancellation[0] =
[
cancellationReceived.name,
cancellationReceived.id
]
// inserting data into cancellation table
connection.query("INSERT INTO cancellations (name, User_ID) VALUES ?", [cancellation],
function(err,results){
if(err){console.log(err)}
}
)
//fetching ID of the current record
connection.query("SELECT id FROM cancellations WHERE User_ID = ? AND name = ?", [cancellationReceived.id, cancellationReceived.name],
function(err, results){
var cancellationID = results[0].id;
});
//assigning ID to use it as a foreign key
for(var i = 0; i < cancellationReceived.rule.length; i++)
{
rules[i] =
[
cancellationReceived.rule[i].daysBefore,
cancellationReceived.rule[i].fee,
cancellationReceived.rule[i].type,
cancellationID
]
}
for(var i = 0; i < rules.length; i++)
{
console.log(rules[i]); // ID is undefined
}
});
How can I solve this problem? I tried to use setTimeout for pausing my code but it did not change anything.
And I use this node module for mysql - > https://github.com/mysqljs/mysql

The best way to solve this problem is RTFM.
connection.query('INSERT INTO cancellations (name, user_id) values ?', [cancellation], function(err, results) {
if (err)
return console.error(err);
// See https://github.com/mysqljs/mysql#getting-the-id-of-an-inserted-row
var cancellation_id = results.insertId;
// Generate sql for rules, join them by ; and execute as one query
// See https://github.com/mysqljs/mysql#multiple-statement-queries
connection.query(sqls, function(err) {
if (err)
return console.error(err);
// Send response here
});
})

Related

sqlite: how to get row id of the row that has the update button on it?

I have sqlite3 database with lastdate column then I query this column and put it into HTML table and dynamically add an update button to every HTML table row.
Also by clicking update button another page will open with input field type="date" and another update button on it and when I click this update button a function query the id of the row and update the corresponding column value in the database.
However, this function always update the last row whatever row I click. My function is as following:
ipcMain.on("update-hide",function(event, inptData){
var sqlDB = new sqlite3.Database('./database.sqlite')
var dateupdate = inptData.toString();
var id_1;
sqlDB.serialize(() => {
sqlDB.serialize(() => {
var n = 0;
sqlDB.each("SELECT * FROM info", function(err, row, i) {
let data = {id: row.ID,};
var id = data.id;
id_1 = id;
}, ()=> {
let listOfData = [dateupdate,id_1];
sqlDB.run(`UPDATE infoSET lastdate = (?)WHERE id=(?)`, listOfData, function(err) {
if(err){
console.log(err)
}
else{
console.log(`Row(s) updated: ${this.changes}`);
}
sqlDB.close();
});
});
});
});
})
So how to query the ID of the row that I click the update button on it?
Note:
I'm using electron framework.
I guess maybe you should pass the row id into the another page and use get method to get the id from the url something like
$ids = $result["ID"];
index.php?id='.$ids.' //This will get the corresponding row id of the column you have to store the row id into ids
index.php?id=1 //url
$id = $_GET["id"]; // get the id

firebase update by batches does not work with large dataset

I want to populate a feed to almost one million of users upon a content posted by a user with high number of followers using GCP cloud functions.
In order to do this, I am designing to split the firebase update of the feed into numbers of small batches. That's because I think if I dont split the update, I might face the following issues:
i) keeping one million of users feed in memory will exceed the allocated maximum 2GB memory.
ii) update one million of entries at one go will not work (How long it takes to update one million entries?)
However, the batch update only works for me when the batch only inserting around 100 entries per update invocation. When I tried with 1000 per batch, only the 1st batch was inserted. I wonder if this is due to:
i) time-out ? however I dont see this error in the log.
ii) The array variable , userFeeds{} , keeping the batch is destroyed when the function is out of scope ?
Below is my code:
var admin = require('firebase-admin');
var spark = require('./spark');
var user = require('./user');
var Promise = require('promise');
var sparkRecord;
exports.newSpark = function (sparkID) {
var getSparkPromise = spark.getSpark(sparkID);
Promise.all([getSparkPromise]).then(function(result) {
var userSpark = result[0];
sparkRecord = userSpark;
sparkRecord.sparkID = sparkID;
// the batch update only works if the entries per batch is aroud 100 instead of 1000
populateFeedsToFollowers(sparkRecord.uidFrom, 100, null, myCallback);
});
};
var populateFeedsToFollowers = function(uid, fetchSize, startKey, callBack){
var fetchCount = 0;
//retrieving only follower list by batch
user.setFetchLimit(fetchSize);
user.setStartKey(startKey);
//I use this array variable to keep the entries by batch
var userFeeds = {};
user.getFollowersByBatch(uid).then(function(users){
if(users == null){
callBack(null, null, null);
return;
}
//looping thru the followers by batch size
Object.keys(users).forEach(function(userKey) {
fetchCount += 1;
if(fetchCount > fetchSize){
// updating users feed by batch
admin.database().ref().update(userFeeds);
callBack(null, userKey);
fetchCount = 0;
return;
}else{
userFeeds['/userFeed/' + userKey + '/' + sparkRecord.sparkID] = {
phase:sparkRecord.phase,
postTimeIntervalSince1970:sparkRecord.postTimeIntervalSince1970
}
}
});//Object.keys(users).forEach
if(fetchCount > 0){
admin.database().ref().update(userFeeds);
}
});//user.getFollowersByBatch
};
var myCallback = function(err, nextKey) {
if (err) throw err; // Check for the error and throw if it exists.
if(nextKey != null){ //if having remaining followers, keep populating
populateFeedsToFollowers(sparkRecord.uidFrom, 100, nextKey, myCallback);
}
};

how to save two rows when two rows are sent and than delete one if just one sent?

I am new in mySql. but need to implement next fnx:
Step 1: I save
notificationChannels = ['channel1', 'channel2];
I save each channel in separate row.using loop
notificationSettings.notificationChannels.forEach(function (channel) {
var channelQuery = 'INSERT INTO notification_channels (user_id, channel) VALUES('+ connection.escape(req.session.user_id)+','+ connection.escape(channel)+') ON DUPLICATE KEY UPDATE channel='+connection.escape(channel) ;
connection.query( channelQuery, function(err, rows) {
if (!err){
isOk = true;
}
else{
console.log(err);
}
});
});
So I've saved 2 rows.
than I want to change settigns - save just 1 channel:
notificationChannels = ['channel2];
So now I need to delete row with 'channel1 and leave just 'channel2'. how to do it?

How to get value from unknown object property?

I have an issue with extracting value from object. I want to check if my SQL table have the asked row:
var checkRow = function(connection,chekedColumn,chekParam, checkVal){
connection.query('SELECT EXISTS(SELECT '+ chekedColumn +' FROM asterisk.users where ' +chekParam+'='+checkVal+')', function (err, rows) {
if(err) console.log('SQL suerry error')
else {
console.log(rows[0]); // output: { 'EXISTS(SELECT id FROM asterisk.users where name=1600)': 1 }
return (rows[0]);
};
});
};
but returned value from query is an object, and return(rows[0]) give just [object object] output. How can I extract value of this object?
You can use
Object.keys(obj)
to get the values of the object. See api reference for more info.
EDIT:
Just to elaborate abit more on this... how you'd go about getting it out is this.
// get the keys of the source
var keys = Object.keys( source );
// loop through the keys
for ( var i = 0; i < keys.length; i++ ) {
var key = keys[i];
var value = source[key];
//do something with value
}
The output is an object which you don't know. So try either:
console.log("Result: %j", rows[0]);
console.log(JSON.stringify(rows[0]));
console.log(require('util').inspect(rows[0], false, null));
to view the structure. After you know the keys, use it to access the data.
Thanks all for helps and for your ideas. Dmitry Matveev help me to understand how to identify object properties(Objekt.keys()). And thanks to user568109 for reminding of asynchronous function, so I use callback. Final code:
var checkRow = function(connection,chekedColumn,chekParam, checkVal,callback){
connection.query('SELECT EXISTS(SELECT '+ chekedColumn +' FROM asterisk.users where ' +chekParam+'='+checkVal+')', function (err, rows) {
if(err) console.log('SQL suerry error')
else {
var keys=Object.keys(rows[0]);
keys.forEach(function(key) {
callback(rows[0][key]);
});
};
});
};
And for using this functions we need to call it like:
checkRow(connection,'id','name',name,function(value){
console.log(value)
})

Fastest way to get JSON object into mysql using node

Using a prior example? How could I insert/update a mysql table using
a JSON object without manually naming the table column headers? And insure it async.
var mysql = require('node-mysql');
var conn = mysql.createConnection({
...
});
var values = [
{name:'demian', email: 'demian#gmail.com', ID: 1},
{name:'john' , email: 'john#gmail.com' , ID: 2},
{name:'mark' , email: 'mark#gmail.com' , ID: 3},
{name:'pete ' , email: 'pete#gmail.com' , ID: 4}
];
// var sql = "INSERT INTO Test (name, email, n) VALUES ?";
conn.query(sql, [values], function(err) {
if (err) throw err;
conn.end();
})
You could do something like this:
for(var i = 0; i < values.length; i++){
var post = values[i]
var query = connection.query('INSERT INTO posts SET ?', post, function(err, result) {
// Finish
});
}
EDIT
This is how you inserts multiple 'posts' at once.
INSERT INTO posts (type, details)
VALUES
('Helen', 24),
('Katrina', 21),
You would have to loop through the first value to get the names like this.
var names = [];
for(name in values[0]){
names.push(name);
// That would give you name, email, id
}
Then you would have to create your own string to insert.
var newvalues = [];
for(var i = 0; i < values.length; i++){
newvalues.push('(' + values[i].join(',') + ')');
}
Then to execute the query:
connection.query('INSERT INTO posts (' + names.join(',') + ') VALUES ' + newvalues.join(',') , function(err, rows, fields) {
// Result
});
You would have to test the code yourself, this is just how you would do it.
Look at the 'Custom Format' part here. If you notice, this example using named placeholders in the query, allowing you to pass an object, and the placeholders are replaced with the matching attributes from the object. I've also pasted the relevant section for clarity:
connection.config.queryFormat = function (query, values) {
if (!values) return query;
return query.replace(/\:(\w+)/g, function (txt, key) {
if (values.hasOwnProperty(key)) {
return this.escape(values[key]);
}
return txt;
}.bind(this));
};
connection.query("UPDATE posts SET title = :title", { title: "Hello MySQL" });
You could create a small function that maps an array with that format to an insert statement.
You can easily loop through the fields and use some string concatenation.
Better option is (using MySQL Connection):
app.get('/yourcontroller/:id', function (req, res) {
var id = req.params.id;
var dataUpdate = req.body;
connection.query(
'UPDATE yourtable SET ? Where ID = ?',
[dataUpdate, id],
function (err, result) {
if (err) throw err;
console.log('Updated data ! Changed ' + result.changedRows + ' rows');
}
);
});