I am working in node.js with mySql database.
i'm fetching lat-long routes from googleMaps sanpToRoad Api and insert that data into my table but it's doesn't inserted in flow (sequence)
var pool = mysql.createPool({
connectionLimit : 10,
host : 'localhost',
user : 'root',
password : '',
database : 'myTestDb'
});
var googleAPILink = 'https://roads.googleapis.com/v1/snapToRoads?path='+lastLat+','+lastLong+'|'+currentLat+','+currentLong+'&interpolate=true&key=GOOGLE_MAP_KEY';
console.log(googleAPILink);
var roadResponse = request(googleAPILink, function (error, response, body) {
if (!error && response.statusCode == 200) {
responseData = JSON.parse(body);
for(i = 0; i < responseData.snappedPoints.length; i++) {
var locationArrayObject = responseData.snappedPoints[i];
var locationArrayObjectInsider = (locationArrayObject.location);
var roadLat = locationArrayObjectInsider.latitude;
var roadLong = locationArrayObjectInsider.longitude
var rideStatus = rows2[0].status;
var rideStartedAns = 'n';
if(rideStatus == 's')
{
rideStartedAns = 'y'
}
var post = {
tripid: rideId,
latitude: roadLat,
road_longitude: roadLong,
rideStarted: rideStartedAns,
routeRideCounter: routeCounter,
status: 'y'
};
pool.getConnection(function(err, connectDB4) {
var qry = connectDB4.query('INSERT INTO tbl_rout SET ?', post, function(err5, result5) {
console.log(qry.sql);
connectDB4.release();
});
});
}
}
});
So, here if google Maps API return me in lat-long routes sequence like
1)
lat : 12.3456789,
long : 12.3456789
2)
lat : 23.1456789,
long : 23.1456789
3)
lat : 34.1256789,
long : 34.1256789
then it will may be first insert record 3) then may be insert record 1) then may be insert record 2).
so it will conflict my code and i can't get proper flow of map road path.
please help me.
Issue is your for loop flush all the requests together. Using this technique you cant get control the query execution flow.
There are two ways to achieve this
Dont call insert query in a loop. prepare a query for example
INSERT INTO tableName(field1, field2, field3) VALUES(val1,val2,val3), (val1,val2,val3),....
create query like this and execute it once this will do it in one db call instead of many
Second way is to use async module
async.eachSeries will execute you query one by one instead of flushing and this will enter data in sequence. check example below.
do npm install async --save
var async = require('async');
async.eachSeries(responseData.snappedPoints , function(snappedPoint , cb){
var locationArrayObject = snappedPoint;
var locationArrayObjectInsider = (locationArrayObject.location);
var roadLat = locationArrayObjectInsider.latitude;
var roadLong = locationArrayObjectInsider.longitude
var rideStatus = rows2[0].status;
var rideStartedAns = 'n';
if(rideStatus == 's')
{
rideStartedAns = 'y'
}
var post = {
tripid: rideId,
latitude: roadLat,
road_longitude: roadLong,
rideStarted: rideStartedAns,
routeRideCounter: routeCounter,
status: 'y'
};
pool.getConnection(function(err, connectDB4) {
var qry = connectDB4.query('INSERT INTO tbl_rout SET ?', post, function(err5, result5) {
console.log(qry.sql);
connectDB4.release();
cb();
});
});
}, function(){
console.log('execuation completed);
});
Related
I am creating a payout API for my site, this one is set up around Monero and I am fetching the values needed to make payments and where to send them from my MongoDB database. I am using Mongoose to do this
I have everything mapped out, it grabs from an array the total net value for that day that needs to be paid out and it grabs from another array the latest wallet entry so it knows where to send the amount to.
The problem arises when I'm trying to structure a new array with this data, pushing this data into it.
Monero intrinsically only allows one transaction to be sent out at a time, locking your leftover balance and the amount sent out until that one transaction has been fully confirmed. The one transaction can be split into multiple transactions but it all has to be sent as "one" big chunk.
So when I send the request to Monero it has to include an array of every wallet and what amount each wallet is receiving.
When I'm pushing to the array I noticed it executes the Transfer Monero function for every time it pushes to the array. How do I make it so the array is pushed completely first with every possible value that meets my if statement (Date is today, paymentStatus is set to false, the amount due is not equal or below 0) before sending that variable over for the Transfer Monero function to use?
I've already tried using return functions, etc. Not sure how to implement async/await or Promises
var bodyParser = require('body-parser');
var mongoose = require('mongoose');
var moment = require('moment');
var User = require('../models/user');
var moneroWallet = require('monero-nodejs');
var Wallet = new moneroWallet('127.0.0.1', 18083);
var destinations = []
var xmrnet = []
// connect to MongoDB
mongoose.connect('mongodb://)
// Fetch IDs
function getID(){
var cursor = User.find({}, function (err, users) {
}).cursor();
return cursor;
}
var cursor = getID();
cursor.on('data', function(name){
var id = name.id
// Map all users using IDs
function getUsers(){
var cursor = User.findById(id, function (err, users) {
}).cursor();
return cursor;
}
var cursor = getUsers();
cursor.on('data', function(user){
net = user.netHistory.map(element => element)
order = user.orderHistory.map(element => element)
userWallets = user.userWallets.map(element => element)
var today = moment();
// date is today? validation
for (var i = 0; i < net.length; i++){
netDate = net[i].net_date_time
netStatus = net[i].paymentStatus
netUSD = net[i].current_usd_net
xmrnet = net[i].xmr_net
for (var j = 0; j < userWallets.length; j++){
xmrwalletsU = userWallets[j].xmr_wallet
if(xmrwalletsU !== ''){
xmrwallet = xmrwalletsU
}
}
var Dateistoday = moment(netDate).isSame(today, 'day');;
if (Dateistoday === true && xmrnet !== 0 && netStatus === false){
console.log('its true')
netid = net[i].id
var destinationsU = [{amount: xmrnet, address: xmrwallet}]
destinations.push(destinationsU)
console.log(destinations)
// problem is right here with destinations^ it pushes one by one
// problem over here as well as wallet.transfer executes one by one by the time it gets to the second, the balance is already locked, unable to send
Wallet.transfer(destinations).then(function(transfer) {
console.log(transfer);
var payouts = {
payout_date_time: Date(),
payout_usd_amount: netUSD,
xmr_wallet: xmrwallet,
xmr_txid: transfer.tx_hash,
}
// add payout to payoutHistory array
User.findByIdAndUpdate(id, {"$addToSet": { 'payoutHistory': [payouts]}},
function(err, user) {
if(err) { console.log(err) }
else {
console.log()
};
})
// update paymentStatus of specific net entry to true
User.updateMany({
"_id": id,
"netHistory._id": netid
}, {
"$set": {
"netHistory.$.paymentStatus": true
}
}, function(error, success) {
})
})
}
}
})
})
I have a server that is written in Java running Rhino for js,
and I decide to rewrite this server into nodejs...
And I need to get data from DB synchronous like :
function executeRowsetParam(sql, p){
return DB.raw(sql,p)// returns object
}
so I can use it like :
var userName = executeRowsetParam('SELECT user_name FROM users where user_id = ?', ["123"]);
if(userName.getRow(0).getValue("user_name ") == "admin"){
//do sth
}
is just an a simple example sometimes I need to select from database data that i have to use in like 1000 lines of code so code like :
executeRowsetParam('SELECT user_name FROM users where user_id = ?', ["123"]).then((r)=>{
if(r.getRow(0).getValue("user_name ") == "admin"){
//do sth
}
})
won't work so well ...
I have code like this too:
IfExists(SQL,p){
if(DB.raw("selecect top 1 1 from" + sql,p) == 1){
return true
}else{return false}
and rewriting it into :
DB.raw("selecect top 1 1 from" + sql,p).then((r)=>{
if(r == 1){//do sth}else{//do else}
})
won't work for me
so is there some npm package that I can use to make selects from db synchronuch that would make my day.
is code like this would be okey ?
var Start = async () => {
var Server = require("./core/server/Server");
console.log('hi!');
console.dir("there is nothing to look at at the momment");
var db = require("./core/db/DB");
global.DB = new db()
function foo() {
return DB.executeSQL("asdasd", [123, 123])
}
console.dir(await foo());
console.dir('asd');
global.DEBUG = true;
global.NEW_GUID = require('uuid/v4');
var server = new Server()
server.start();
}
Start();
is that enough to let me use await in every single instance inside the server or have I make every single function async if I would use await?
Found and tested deasync works great!
var deasync = require('deasync');
module.exports = function DB(){
var knex = require('knex')(require("./../../config").DB);
this.executeRowsetParam = (sql, param) => {
let done = false;
knex.raw(sql, param).then((r => {
done = r;
})).catch((e => {
throw "Error in query "+ e
}))
deasync.loopWhile(function () { return !done; });
return done
}
}
I have nodejs-mongo setup with db configured as follows (only one entry shown here)
{
"filename":"type1.json","secs":72.4060092977,"platform":"mac","version":"1.3.0", "inputfile":"temp.mov"
},
Here are the mongo commands I am trying to replicate
db.perfR.distinct("platform") * (output: ["mac", "win"] ) *
db.perfR.distinct("version",{"platform":"win"}) * (output: ["1.3.0", "1.3.2"] ) *
db.perfR.find({"version":1.3.2,"platform":"win"},{"filename":1,"secs":1,"_id":0}) * (output: ["filename":"type1.json","secs":72.4060092977] ) *
So what I am trying to do is
for every platform
for every version
get filename
get secs
Here is the code I have written thus far
function createPlatformDataSets(callback){
var dbHost = "mongodb://mongo:27017/perfSample";
var mongodb = require('mongodb')
var platformDataSets = []
var platformq = "platform"
//get Instance of Mongoclient
var MongoClient = mongodb.MongoClient;
//Connecting to the Mongodb instance.
//Make sure your mongodb daemon mongod is running on port 27017 on localhost
MongoClient.connect(dbHost, function(err, db){
if ( err ) throw err;
//use the distinct() to retrive distinct platforms
db.collection("perfR").distinct(platformq,function(err, platResultSet){
if ( err ) throw err;
var maxPlatCnt = platResultSet.length // 1
if (maxPlatCnt == 0){
console.log("Bad PlatfQ Query")
callback(true)
}
var versionedPlatDataSet = 0
for (p=0; p < platResultSet.length; p++){
(function(index){
var platform = platResultSet[index]
var options = createOptions(platform);
//Get Versions
var versionq = "\"version\",{\"platform\":" + platform + "}"
console.log("Versionq::"+versionq)
var dataSets = [];
//var versions = ["1.3.0", "1.3.2"]; // (select disctinct(version) from cpu where platform = plat)
// Use distinct() to find distinct Versions
db.collection("perfR").distinct(versionq,function(err, verResultSet){
if ( err ) throw err;
var maxVerCnt = verResultSet.length // 2
if (maxVerCnt == 0){
db.close()
console.log("Bad Versionq Query")
callback(true)
}
var dataSetResponseCnt = 0
for ( v=0; v < verResultSet.length; v++){
(function(idx){
var dataq = "{platform:" + platform + ",version:" + version + "},{filename:1,secs:1,_id:0}"
// Use find() to find filename and secs for given version and platform
db.collection("perfR").find(dataq,function(err, dataResultSet){
if ( err ) throw err;
if (dataResultSet.length == 0){
console.log("Bad dataq Query")
callback(true)
}
//do something with filename and secs
dataSetResponseCnt++
if (maxVerCnt == dataSetResponseCnt){
var platformData = {"options":options, "labels":labels, "datasets":dataSets, "platform":platform}
platformDataSets.push(platformData)
if (versionedPlatDataSet == maxPlatCnt){
db.close()
callback(null,platformDataSets)
}
}
})
})(v)
}
versionedPlatDataSet++
})(p)
}
}
}
At "1" I am able to retrive distinct platforms
But at "2" I get verResultSet.length to be zero.
Can someone point to me what is wrong?
(PS: This is my first serious async problem with javascript so bear with my code. All suggestions are welcome :) )
you can use Promises. so for example your code is going to be something like this:
return loadPlatforms().then(function (res){
res.map(function(platform){
loadVersion(platform).then(...)
}
})
Your use of .distinct() isn't correct. You are passing a JSON-like string when the API actually takes two separate arguments (not including the callback). So the real code should in fact just be more or less what you originally showed:
var query = { platform: 'win' };
db.collection('perfR').distinct('version', query, function(err, verResultSet) {
// ...
});
I am learning about Node and Feathers on a job. Need to make a simple app that would use feathers to load the [nedb] with sample data.
var fake = require('./fake.js');
var feathers = require('feathers-client');
var io = require('socket.io-client');
var socket = io("http://127.0.0.1:8000");
var app = feathers()
.configure(feathers.socketio(socket));
var accountsAPIService = app.service('/api/accounts');
var dummyData = fake();
// import dummy data
for ( var i = 0; i < dummyData.accounts.length; i++) {
// console.log(dummyData.accounts[i]);
var params = { query: {}};
accountsAPIService.create(dummyData.accounts[i], params).then(function(account) {
console.log("inserted: ", account);
});
}
// read back inserted records
accountsAPIService.find(params, function(accounts) {
console.log("accounts: ", accounts);
});
i just need to insert items from the array dummyData.accounts into the server.
When I run the script, it seems that nothing is being imported.
When I read the records back, it returns:
accounts: null
What is the proper way of inserting/creating records with Feathers?
Could not figure out how to use ".then" so used a regular form:
for ( var i = 0; i < dummyData.accounts.length; i++) {
var params = { query: {}};
accountsAPIService.create(dummyData.accounts[i], params, function(error, account) {
// console.log("inserted: ", account);
});
}
That works fine.
To read the data back, I corrected the method signature. Then, it works. :)
accountsAPIService.find(function(error, accounts) {
console.log("accounts: ", accounts);
});
I m creating mobile web application using html5 and javascript.I m having two javascript files. AttributesDatabase.js and AttributeView.js.From AttributeView.js i m calling one function from AttributeDatabase.js in that i m executing one select query.Now the query result should go to AtttributeView.js.But the Websql transaction is asynchronous call that is what it is not returning proper result.Is there any way to handle the websql result.
Please help if any way there?
Edited
AttributeView.js
var AttributeDAOObj = new AttributeDAO();
AttributeDAOObj.GetAttributeList();
alert(AttributeDAOObj.GetAttributeList()); //This alert is coming as undefined.
AttributeDAO.js
this.GetAttributeList = function () {
var baseDAOObj = new BaseDAO();
var query = "SELECT AttributeName FROM LOGS";
// this.Successcalbackfromsrc = this.myInstance.Successcalback;
var parm = { 'query': query, 'Successcalback': this.myInstance.Successcalback };
baseDAOObj.executeSql(parm);
}
//To Create database and execute sql queries.
function BaseDAO() {
this.myInstance = this;
//Creating database
this.GetMobileWebDB = function () {
if (dbName == null) {
var dbName = 'ABC';
}
var objMobileWebDB = window.openDatabase(dbName, "1.0", dbName, 5 * 1024 * 1024);
return objMobileWebDB;
}
//Executing queries and getting result
this.executeSql = function (query) {
var objMobileWebDB = this.myInstance.GetMobileWebDB();
objMobileWebDB.transaction(function (transaction) {
//In this transaction i m returning the result.The result value is coming.
transaction.executeSql(query, [], function (transaction, result) { return result; }, this.Errorclback);
});
}
}
The problem is in you succes call back (like in the comment to your question, stated by DCoder)
function (transaction, result) { return result; }
this is returning where to?
So this is how to do it (or at least one way)
you can do for example:
function (transaction,result){
console.log("yes, I have some result, but this doesn't say anything, empty result gives also a result");
// so check if there is a result:
if (result != null && result.rows != null) {
if (result.rows.length == 0) {
// do something if there is no result
}else{
for ( var i = 0; i < result.rows.length; i++) {
var row = result.rows.item(i);
var id = result.rows.item(i).id; //supposing there is an id in your result
console.log('Yeah! row id = '+id);
}
}
}else{
// do something if there is no result
}
};
note the code above can be compacter, but this is how to understand it better.
another way is to put this function is a seperate piece of code, so you keep the sql statement more compact and readable. Like you call you error callback this can be in your function (with this. in front of it) or a completely seperate function.