makes a database connection in the constructor using Knex - node.js

I am trying to implement knex connection below into an equivalent DB class. I searched but did not find any example implementation.
var knex = require('knex')({
client: 'pg',
connection: {
host: '127.0.0.1',
user: 'your_database_user',
password: 'your_database_password',
database: 'myapp_test'
},
pool: { min: 0, max: 7 }
})

let knex = require("knex");
class Database {
constructor(connection) {
this.connection = connection;
}
connect(option = {}) {
this.instance = knex(Object.assign(this.connection, option));
}
}
let db = new Database({
connection: {
host: '127.0.0.1',
user: 'your_database_user',
password: 'your_database_password',
database: 'myapp_test'
}
});
db.connect({
pool: { min: 0, max: 7 },
client: 'pg'
});

Related

Nodejs MSSQL how to pool multiple databases simultaneously

I am building a massive intranet using NodeJS, converting from ASP.Net C#. I keep running into database errors about cannot use the connection while it is closing or connection must be opened etc. I am attempting to convert over to connection pooling but am running into issues with it since I am connecting with (currently) 6 different databases, and being new to Node MSSQL I am kind of at a loss for how to proceed.
Originally I was making a call to "runqueries()" passing in the config data, and from there opening a connection to the desired database. The connection details were stored in a JSON object in the database.js file. I am now trying to create the pool in the database.js file and return that as an object to connect.
//database.js
const sql = require('mssql');
// const Config = {
// MCAIntranet: {
// user: 'username',
// password: 'password',
// server: 'mcasql',
// database: 'MCAIntranet',
// options: { enableArithAbort: true }
// },
// DEV_Intranet: {
// server: 'mcasql',
// user: 'username',
// password: 'password',
// database: 'DEV_Intranet_Test',
// options: { enableArithAbort: true }
// },
// CMR: {
// user: 'username',
// password: 'password',
// server: 'mcasql',
// database: 'Corporate_Morning_Reports',
// options: { enableArithAbort: true }
// },
// Lansa: {
// user: 'username',
// password: 'password',
// server: 'mcasql',
// database: 'LANSA',
// options: { enableArithAbort: true }
// },
// Roles: {
// user: 'username',
// password: 'password',
// server: 'mcasql',
// database: 'dotNetRolesDB_New',
// options: { enableArithAbort: true }
// },
// PreAuth:{
// user: 'username',
// password: 'password',
// server: 'mcasql',
// database: 'PreAuth',
// options: { enableArithAbort: true }
// }
// }
const CORPIntranet = () => {
new sql.ConnectionPool({
user: 'username',
password: 'password',
server: 'dbserver',
database: 'CORPIntranet',
options: { enableArithAbort: true }
})
.connect().then(pool => pool)
};
const DEV_Intranet = () => {
new sql.ConnectionPool({
user: 'username',
password: 'password',
server: 'dbserver',
database: 'CORPIntranet_Test',
options: { enableArithAbort: true }
})
.connect().then(pool => pool)
};
const CMR = () => {
new sql.ConnectionPool({
user: 'username',
password: 'password',
server: 'dbserver',
database: 'Corporate_Morning_Reports',
options: { enableArithAbort: true }
})
.connect().then(pool => pool)
};
const Lansa = () => {
new sql.ConnectionPool({
user: 'username',
password: 'password',
server: 'dbserver',
database: 'LANSA',
options: { enableArithAbort: true }
})
.connect().then(pool => pool)
};
const Roles = () => {
new sql.ConnectionPool({
user: 'username',
password: 'password',
server: 'dbserver',
database: 'dotNetRolesDB_New',
options: { enableArithAbort: true }
})
.connect().then(pool => pool)
};
const PreAuth = () => {
new sql.ConnectionPool({
user: 'username',
password: 'password',
server: 'dbserver',
database: 'PreAuth',
options: { enableArithAbort: true }
})
.connect().then(pool => pool)
};
const Config = {
CORPIntranet: CORPIntranet(),
DEV_Intranet: DEV_Intranet(),
CMR: CMR(),
Lansa: Lansa(),
Roles: Roles(),
PreAuth: PreAuth()
}
module.exports = Config;
I am calling this using the code await dataQuery.runQuery(query, config.PreAuth);
and the runquery() code is
//dataQueries.js
let sql = require('mssql');
const runQuery = async (query, database) => {
try {
// await sql.connect(database);
// let request = new sql.Request();
let recordset = await database.query(query);
return recordset;
} catch (ex) {
console.log(ex);
{ error: "dataQueries.js 17" + ex.Message };
return "False";
}
finally{
sql.close();
}
}
I know that I don't need the "sql.close()" at the end but I am in the process of conversion. I am now getting a typeError: database.query is not a function.
If you could point out where my fault lies in this, and better yet link a good tutorial that assumes neophyte status of the reader, that would be excellent.
Thanks in advance.
EDIT
In my runQuery() function I changed the code to
let pool=await database();
let recordset = await pool.query(query);
which now allows the query to run. But is this the correct method and will it prevent errors on multiple database connections?
I solved this problem in the simplest fashion possible. I switched from using the mssql module to sequelize.js which gives a level of abstraction from the database access and connectivity, and simplifies access to multiple databases along with database types (MSSQL, Postgres, MongoDB etc)

Problem with connect by Sequelize when I connect to SQL Server

I use the mssql package and connect to database like this:
const sql = require('mssql')
const config = {
user: 'sa',
password: 'xxxxxx',
server: 'xxx.xxx.xxx.xxx',
database: 'zorgo',
options : {
enableArithAbort: false,
cryptoCredentialsDetails: {
minVersion: 'TLSv1'
}
}
};
Now I want to try 'sequelize' library and try to connect
const sequelize = new Sequelize('zorgo', 'sa', 'xxxxxx', {
dialect: 'mssql',
host: 'xxx.xxx.xxx.xxx',
options: {
enableArithAbort: false,
cryptoCredentialsDetails: {
minVersion: 'TLSv1'
}
}
});
But I get an error
Failed to connect to xxx.xxx.xxx.xxx:1433 - 584:error:1425F102:SSL routines:ssl_choose_client_version:unsupported protocol
Please help me resolve this problem
I found the answer to my question
const sequelize = new Sequelize('zorgo', 'sa', 'xxxxxx', {
dialect: 'mssql',
host: 'xxx.xxx.xxx.xxx',
dialectOptions: {
options: {
enableArithAbort: false,
cryptoCredentialsDetails: {
minVersion: 'TLSv1'
}
}
}
});
And works well...

Node.JS: Cannot connect to Microsoft Azure Database when using Sequelize

I am trying to connect Azure database using the express + Sequelize. I cannot get connection to work.
I have modified the database.json connection file like this:
"development": {
"username": "XXX",
"password": "XXX",
"database": "XXX",
"host": "XXX",
"dialect": "mssql",
"port": 1433,
"dialectOptions": {
"encrypt": true
}
}
I try to connect with sequelizer like this
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
I get error message:
https://i.imgur.com/FQdZCeZ.png
If I directly change Sequelize connection without using the JSON file and connect it like this:
sequelize = new Sequelize('XXX', 'XXX', 'XXX', { host: 'XXX', dialect: 'mssql', dialectOptions: { options: { encrypt: true } } });
I get error about Username being empty:
https://i.imgur.com/JbkOgIU.png
I have tried connection with MySql and everything works in there. Problems are only when connecting to Azure database. Any help would be great guys! Thank you.
I connected as below. It works.
const sequelize = new Sequelize(database, username, password, {
host: config.databaseHost,
Port: config.databasePort, // 49175 // 1433
dialect: 'mssql',
pool: {
max: 5,
min: 0,
idle: 10000
},
dialectOptions: {
instanceName: 'SQLEXPRESS',
requestTimeout: 60000
}
});
sequelize
.authenticate()
.then(() => {
console.log('Connection has been established successfully.');
})
.catch(err => {
console.error('Unable to connect to the database:', err);
});
Got it working! I didnt have Tedious Installed. Aftet that all is working.

sequelize.query() is not a FUNCTION

I am new to sequelize. I am trying to use row query, but I'm getting an error.
Code:
const sequelize = require('sequelize');
sequelize.query("SELECT * from users").then(results => {
console.log(results);
})
Error while calling this API:
(node:2380) UnhandledPromiseRejectionWarning: TypeError: sequelize.query is not a function
at Promise (C:\NodejsProject\mars\app\schedule\models\schedule.js:247:17)
at new Promise (<anonymous>)
How can I fix this?
You can't use sequelize directly from require('sequelize'); ,
first we need to create instance of that , and instance will be
created from DB details , so sequelize can know on which platform ,
which DB it has to run the query
Here is the basic snippet , just for a idea :
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'|'sqlite'|'postgres'|'mssql',
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
// SQLite only
storage: 'path/to/database.sqlite',
// http://docs.sequelizejs.com/manual/tutorial/querying.html#operators
operatorsAliases: false
});
sequelize.query("SELECT * from users").then(results => {
console.log(results);
});
For more detail : DO READ
If you are running your db config in external file AND want and extra layer to protect from SQL injection
./database/dbs.js
const Sequelize = require('sequelize')
const db = {}
const sequelize = new Sequelize('dbname',
'username',
'password', {
host: 'localhost',
dialect: 'mysql',
logging: console.log,
freezeTableName: true,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
})
db.sequelize = sequelize
db.Sequelize = Sequelize
module.exports = db
then in the file you want to use:
const db = require('../database/db')
...
const newDbName = 'myNewDb'
db.sequelize.query(`CREATE DATABASE IF NOT EXISTS ${newDbName} `, {
type: db.sequelize.QueryTypes.CREATE
}).then( () => {
res.send('ok done creating ' + req.body.newDbName).end()
}).catch( err => {
res.status(500).send('Err executing command ' + err).end()
})
dbConnect.js:
const Sequelize = require('sequelize');<br/>
const con = new Sequelize.Sequelize(<br/>
'db',
"user",
"password",
{
host: "localhost",
dialect: "mysql",
operatorsAliases: false,
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
},
},
);
con.query("SELECT 1", (err, rows) => {
console.log(rows)
if (err) throw err;
console.log(err)
}).then(function (result){
console.log("inventory")
console.log(result)
});
module.exports = con;
// import
let con = require("../common/dbConnect")
// use in function
const [results, metadata] = await con.query(
"SELECT * FROM officer JOIN user ON officer.UserID = user.UserID"
);
console.log(JSON.stringify(results, null, 2));

waterline and mysql without sails

I am building a node app and want to use waterline and mysql without sails. I cannot get the adapter to work. The exact error I get with the code from below is:
C:\node\mlb\node_modules\waterline\lib\waterline\core\index.js:70
var schemaAttributes = this.waterline.schema[this.identity].attributes;
TypeError: Cannot read property 'undefined' of undefined
Here is my code:
var Waterline = require('waterline');
var mysql = require('sails-mysql');
mysql.config = {
host: 'localhost',
database: 'mlb',
port: '3306',
username: 'admin',
password: 'xxxxxxxx'
}
var Batter = Waterline.Collection.extend({
adapter: 'mysql',
attributes: {
name: {
type: 'string',
required: true
}
}
});
new Batter({ tableName: 'batters', adapters: { mysql: mysql }}, function (err, Model) {
Model.findAll().exec(function(err, batters) {
// Now we have an array of users
});
});

Resources