How to use express.js with mysql and express-myconnection? - mysql

I am using Express 4.9.0 and express-generator. Executed this command:
express --hbs projectname
Installed following modules with NPM:
mysql
express-myconnection
I want to make todo application. I have created separate file under routes/todo.js and created get/post routes for creating todos in that file using router.get and router.post.
i have following code in app.js:
// mysql connection
var connection = require('express-myconnection');
var mysql = require('mysql');
app.use(
connection(mysql, {
host : config.db.host,
user : config.db.user,
password : config.db.password,
database : config.db.database,
debug : false //set true if you wanna see debug logger
}, 'request')
);
// end of mysql connection
Where should i place mysql config and connection code? Inside todo.js? I still don't get concept of organisation file structure and where to place database queries.

I don't know if you eventually found the answer, but I thought it might help out others who accidentally stumbled on your question:
After you've setup like mentioned above, you can call the connection from the request object using the getConnection method like this:
exports.index = function(req, res) {
req.getConnection(function (err, connection) {
connection.query('select * from table_name', function(err, rows, fields){
if (err) {
return res.status(400).send({
message: errorHandler.getErrorMessage(err)
});
} else {
res.jsonp(rows);
}
});
});
};
This should print out a json with the content of your table all nice an pretty.
Hope this comes in handy.

Related

REACT NATIVE Retrieving data from localhost MySQL database

I'm writing an app in React Native and I have created a MySQL database to store my information, but I was wondering if it was possible to use axios or fetch to interact with my database since it's local and doesn't have an HTTP address yet?
I feel like I used to be able to do it, but I forgot the syntax to use... If anyone knows anything, I would greatly appreciate it.
Thank you
There is no direct connection between React Native and Mysql. So you need to use Node js.
Step 1:
npm install express
npm install body-parser
npm install mysql
Step 2:
const connection = mysql.createPool({
host : 'localhost', // Your connection adress (localhost).
user : 'root', // Your database's username.
password : '', // Your database's password.
database : 'my_db' // Your database's name.
});
// Starting our app.
const app = express();
// Creating a GET route that returns data from the 'users' table.
app.get('/users', function (req, res) {
// Connecting to the database.
connection.getConnection(function (err, connection) {
// Executing the MySQL query (select all data from the 'users' table).
connection.query('SELECT * FROM users', function (error, results, fields) {
// If some error occurs, we throw an error.
if (error) throw error;
// Getting the 'response' from the database and sending it to our route. This is were the data is.
res.send(results)
});
});
});
// Starting our server.
app.listen(3000, () => {
console.log('Go to http://localhost:3000/users so you can see the data.');
});
To get the data in your React Native App. You need to use your PC's IP Address. If you use localhost you access the smartphone/emulator localhost. Here is an example to follow:
getData(){
fetch('http://yourpcip:3000/users')
.then(response => response.json())
.then(users => console.log(users))

How to debug an Azure Function using Node.js and mysql2 connecting to database

running into some issues trying to figure out an Azure Function (node.js-based) can connect to our mysql database (also hosted on Azure). We're using mysql2 and following tutorials pretty much exactly (https://learn.microsoft.com/en-us/azure/mysql/connect-nodejs, and similar) Here's the meat of the call:
const mysql = require('mysql2');
const fs = require('fs');
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
if (req.query.fname || (req.body && req.body.fname)) {
context.log('start');
var config = {
host:process.env['mysql_host'],
user: process.env['mysql_user'],
password: process.env['mysql_password'],
port:3306,
database:'database_name',
ssl:{
ca : fs.readFileSync(__dirname + '\\certs\\cacert.pem')
},
connectTimeout:5000
};
const conn = mysql.createConnection(config);
/*context.log(conn);*/
conn.connect(function (err) {
context.log('here');
if (err) {
context.error('error connecting: ' + err.stack);
context.log("shit is broke");
throw err;
}
console.log("Connection established.");
});
context.log('mid');
conn.query('SELECT 1+1',function(error,results,fields) {
context.log('here');
context.log(error);
context.log(results);
context.log(fields);
});
Basically, running into an issue where the conn.connect(function(err)... doesn't return anything - no error message, no logs, etc. conn.query works similarly.
Everything seems set up properly, but I don't even know where to look next to resolve the issue. Has anyone come across this before or have advice on how to handle?
Thanks!!
Ben
I believe the link that Baskar shared covers debugging your function locally
As for your function, you can make some changes to improve performance.
Create the connection to the DB outside the function code otherwise it will create a new instance and connect every time. Also, you can enable pooling to reuse connections and not cross the 300 limit that the sandbox in which Azure Functions run has.
Use the Promises along with async/await
You basically can update your code to something like this
const mysql = require('mysql2/promise');
const fs = require('fs');
var config = {
host: process.env['mysql_host'],
user: process.env['mysql_user'],
password: process.env['mysql_password'],
port: 3306,
database: 'database_name',
ssl: {
ca: fs.readFileSync(__dirname + '\\certs\\cacert.pem')
},
connectTimeout: 5000,
connectionLimit: 250,
queueLimit: 0
};
const pool = mysql.createPool(config);
module.exports = async function(context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
if (req.query.fname || (req.body && req.body.fname)) {
context.log('start');
const conn = await pool.getConnection();
context.log('mid');
await conn.query('SELECT 1+1', function(error, results, fields) {
context.log('here');
context.log(error);
context.log(results);
context.log(fields);
});
conn.release();
}
};
PS: I haven't test this code as such but I believe something like this should work
Debugging on serverless is challenging for obvious reasons. You can try one of the hacky solutions to debug locally (like Serverless Framework), but that won't necessarily help you if your issue is to do with a connection to a DB. You might see different behaviour locally.
Another option is to see if you can step debug using Rookout, which should let you catch the full stack at different points in the code execution and give you a good sense of what's failing and why.

Testing an AWS Lambda function

I need to create a lambda function to act as the middleman between a mobile Java app and an AWS RDS MySQL database. The idea is to submit queries from the mobile app and then send them off to the lambda function, which will then return the query. I have a basic MySQL query set up in my AWS lambda:
var mysql = require('mysql');
var config = require('./config.json');
var pool = mysql.createPool({
host : config.dbhost,
user : config.dbuser,
password : config.dbpassword,
database : config.dbname
});
exports.handler = (event, context, callback) -> {
context.callbackWaitsForEmptyEventLoop = false;
pool.getConnection(function(err, connection) {
if (err) throw err; // not connected!
// Use the connection
connection.query('select Album from record', function (error, results, fields) {
// When done with the connection, release it.
connection.release();
// Handle error after the release.
if (error) callback(error);
else callback(null, results[0].Album);
// Don't use the connection here, it has been returned to the pool.
});
});
};
And all that I am currently trying to do is get this code to run and output what the query will return. I've seen tutorials where people seem to just click test and have the code run, but it keeps asking me to create a test, and I'm not sure what exactly I would need to do to test this function.
EDIT: I realized I was missing a small change in my lambda uploaded code, but I am now getting an error on line 10 saying there is an unexpected token >.
I'm not sure what's wrong here, as the tutorial I watched seems to have the same exact thing.
Since you're not passing in any parameters through the context, you can just create a test with the defaults or an empty object {}, and click Test in the console. It will invoke your Lambda function as if it had been called from your mobile app, and you can debug from there.

Getting data from MySql through express

I've set up a database on Heroku and I've created a table called users with 2 records, and now I'm trying to get the data into my Node application through express.
I've set up an connection like so in my app.js file:
// connect to the heroku database
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'us-cdbr-iron-***-**.cleardb.net',
user : 'bfe4***0ede74',
password : '6742****',
database : 'heroku_****ee0f0e9102'
});
I then have a routes folder with an index.js file:
var express = require('express');
var router = express.Router();
/* GET home page. */
router.get('/', function(req, res, next) {
// res.render('layout', { title: 'Movieseat' });
connection.connect();
connection.query('SELECT * FROM `users` WHERE `first_name` = "Kees"', function (error, results, fields) {
// error will be an Error if one occurred during the query
// results will contain the results of the query
// fields will contain information about the returned results fields (if any)
console.log(results);
});
connection.end();
});
module.exports = router;
In this index route I'm trying to serve the record of first_name Kees. But when I visit my host I get the following error:
connection is not defined
ReferenceError: connection is not defined
So it looks like connection has no reference in my route file, but in my WebStorm IDE when I ctrl + click on the connection I get my app.js file where I define my connection. So how do I reference connection in my route file?
Also when I uncomment the following line in my index.js route file:
res.render('layout', { title: 'Movieseat' });
I get the error:
Error: Can't set headers after they are sent. What would be the propper way to request data and render a jade template?
The second error is likely because somewhere you're calling res.send() or res.end() or res.render() already, you just don't realize it. Check your middleware and so on to make sure you're not doing so.
The first issue is because you're neither exporting the connection object from your connection file, nor requiring it in your router file. You always have to explicitly require a module in order to have reference to it.
// connect to the heroku database
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'us-cdbr-iron-***-**.cleardb.net',
user : 'bfe4***0ede74',
password : '6742****',
database : 'heroku_****ee0f0e9102'
});
module.exports = connection;
NOte that in that case, you will always have the same connection, which isn't great for scalability. Have a look at connection pooling and consider exporting a method that gets the connection rather than passing around a global object.
Then in your router:
var express = require('express');
var router = express.Router();
var connection = require('./path/to/your/connection.js');
/* GET home page. */
router.get('/', function(req, res, next) {
// res.render('layout', { title: 'Movieseat' });
connection.connect();
connection.query('SELECT * FROM `users` WHERE `first_name` = "Kees"', function (error, results, fields) {
// error will be an Error if one occurred during the query
// results will contain the results of the query
// fields will contain information about the returned results fields (if any)
console.log(results);
});
connection.end();
});
module.exports = router;

Serverless Framework with Node MySQL

How to use mysql connection with serverless framework.connection should be available in my component functions without creating mysql connection each time in component function
Tried like this
var mysql = require('mysql');
module.exports.respond = function(event, cb) {
var pool = mysql.createPool({
connectionLimit : 100,
host : 'hostname',
user : 'username',
password : 'password',
database : 'databasename',
debug : false
});
var message='';
pool.getConnection(function(err,connection){
if(err) {
message='Could not connect to database';
} else {
message="Database is connected";
}
var response = {
message: message
};
return cb(null, response);
});
};
but above code will be only available for current function,want to make common thing for mysql connection in serverless framework,can not find proper document about how to use mysql in serverless framework
I am writing answer of my own question
make database.js file in component/lib folder
code of database.js
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'hostname',
user : 'username',
password : 'password',
database : 'databasename'
});
connection.connect();
module.exports = connection;
created object like this in component/lib/index.js file
var connection = require("../lib/database.js");
Can use connection variable to write mysql query like this in component/lib/index.js
module.exports.respond = function(event, cb) {
var query="SELECT * from table_name";
connection.query(query,function(err,rows) {
})
};
I believe you have a Component created in your Serverless Framework based project that contains multiple lambda functions. And now you want to write the MySQL connection code such that this code block is available for re-use in all your lambda functions of that component.
If this is the ask, then Serverless does provide a "lib" folder inside your Component directory, which you can utilize to write common code logic to be re-used. Since you have a NodeJS-based runtime for your component, there should be an "index.js" file inside your Component folder -
your_serverless_project_directory/component_name/lib/index.js
The first thing you want to do is to add the MySQL connection code logic to a function/method in index.js.
Serverless should have already included for you this entire lib/ folder in all your lambda function's handler.js code like this -
var lib = require('../../lib');
Therefore, the next/final thing you want to do is re-use your connection function/method (in all the lambda functions belonging inside your Component) like this -
module.exports.handler = function(event, context) {
lib.mySQLConnection();
};
Hope this helps, let me know how it goes.
To build off of Normal Goswami's answer:
You've specified the database here in the connection. My lambdas each need different databases, so in the connection code just leave off the database:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'hostname',
user : 'username',
password : 'password'
// no database here
});
connection.connect();
module.exports = connection;
And then use an oddly named function to change the database in each lambda function:
connection.changeUser({database: database}, function(err) {
if (err) { throw err; }
});
connection.query(sql, function(err, rows, fields) {
// etc
}
You could also look into using a database connection pool.
you have to make connection out of function, as we are doing it with mongodb
we are making mongodb connection out side of Lambda Function.
my code snippet from https://github.com/malikasinger1/serverles-practice/tree/master/mongodb-connection:
var mongoose = require("mongoose");
var dbURI = 'mongodb://localhost/mydatabase';
mongoose.connect(dbURI);
mongoose.connection.on('connected', function () {//connected
console.log("Mongoose is connected");
// process.exit(1);
});
module.exports.signup = (event, context, cb) => {
//doing signup here
}
in your cace it will be something like this most probably:
var mysql = require('mysql');
//make connection here
var pool = mysql.createPool({
...
});
pool.getConnection(function(err,connection){
...
});
module.exports.respond = function(event, cb) {
//use connection here
};
I am assuming you are using serverless framework on AWS.
Although you can create a connection and assign it to a frozen variable, it's not guaranteed that your lambda won't create a new connection. Here is why:
The best way so far (in my personal opinion) is to create a separate lambda function for db related operations and invoke this function through other lambdas. Here is the flow:
client -> registerUserLambda -> dbLambda -> DATABASE
However, the thing about lambdas is that when there are too many requests, there will be new containers created to handle other requests. That is, new connections will be created. Therefore the concept of connection pools does not work well for now on serverless lambdas.