not able to replace sqllite connection with mysql - node.js

I have a small nodejs app that I need to run on MySQL, but as a nodeJS newbie I am having a hard time getting my head around some of the concepts.
Today there is a method (database.js):
async function getLatestHeight() {
return (
await util.promisify(db.get.bind(db))(`SELECT MAX(height) FROM utxos`)
)["MAX(height)"];
}
Which is called like this in app.js:
let height = await db.getLatestHeight();
In database.js I have replaced the connection to sqllite with mysql:
const config = {
host: process.env.MYSQL_HOST,
user: process.env.MYSQL_USER,
port: 3306,
password: process.env.MYSQL_PASSWORD,
database: process.env.MYSQL_DB,
};
dbConnection = mysql.createConnection(config);
dbConnection.connect((err) => {
if (err) throw err;
console.log('Connected!');
});
But how do I rewrite the getLatestHeight to send the same query to MySQL? The API seems to work so differently that I am not able to have MySQL return data the same way.
I tried:
return (
await util.promisify(dbConnection.query("SELECT MAX(height) FROM utxos"))
)["MAX(height)"];
But that returns a different type so I get an error TypeError [ERR_INVALID_ARG_TYPE]: The "original" argument must be of type function. Received an instance of Query
This is probably a Node newbie issue, so happy for any hjelp. Hard to get my head out of OO and procedural coding styles...

Related

Node error connecting to SQL Server 2019 won't go away

i'm having some trouble connecting node to the database, it keeps throwing me an error of ssl and i tried a lot of different videos and stuff to see if it works but nothing does, here is what i'm currently doing
import sql from 'mssql'
const dbSettings = {
user: 'admin',
password: 'system',
server: 'localhost',
database: 'master',
options: {
trustedConnection: true,
encrypt: true,
trustServerCertificate: true,
},
}
async function getConnection() {
const pool = sql.connect(dbSettings)
const result = await sql.query("SELECT 1")
console.log(result)
}
getConnection()
i also tried this as well but didn't work either
async function getConnection() {
const pool = await sql.connect(dbSettings)
const result = await pool.request().query("SELECT 1")
console.log(result)
i also checked if the SQL Server authentication is enabled with windows and SQL Server and it is, i can log in into SQL Server with that info, but somehow is having trouble creating the connection, by the way, this is the error message it is showing me:
node_modules\mssql\lib\tedious\connection-pool.js:70
err = new ConnectionError(err)
^
ConnectionError: Failed to connect to localhost:1433 - 186B0000:error:0A000102:SSL routines:ssl_choose_client_version:unsupported protocol:c:\ws\deps\openssl\openssl\ssl\statem\statem_lib.c:1986
any tips or solution you can give me to solve this problem would be really helpful to me, thank you very much in advance.
EDIT
I noticed that the connection error only appears when i call the function getConnection if i remove it it doesn't appear, however i need to make sure that the connection was properly established and see the response from the database to move on
change encrypt: true to encrypt: false

Can Sequelize be used to connect to a new database?

In designing a simple node.js project, I tried using Sequelize to connect to a mysql server using the following configuration parameters:
{ dbname: users
username: jimmy
password: users
params:
host: localhost
port: 3306
dialect: mysql }
though the 'users' database didn't exist yet.
I got a server error:
InternalServerError: {"name":"SequelizeConnectionError","parent":{"code":"ER_BAD_DB_ERROR","errno":1049,"sqlState":"42000","sqlMessage":"Unknown database 'users'"},"original":{"code":"ER_BAD_DB_ERROR","errno":1049,"sqlState":"42000","sqlMessage":"Unknown database 'users'"}}
But the Sequelize docs: Manual | Sequelize indicate that Sequelize can connect to a new database. Please, how can Sequelize be used to connect to a
new(non-existing) database?
You should read the documentation again carefully (because the wording is indeed confusing!).
New databases versus existing databases
If you are starting a project from scratch, and your database does not exist yet, Sequelize
can be used since the beginning in order to automate the creation of
every table in your database.
Also, if you want to use Sequelize to connect to a database that is
already filled with tables and data, that works as well! Sequelize has
got you covered in both cases.
It will connect only to an existing DB, it can help you by creating the tables if they do not exist yet but the DB has to be there in order for sequelize to connect with it.
Following this question, I wrote this PR to update the documentation to be less confusing. Hope it help!
Found a similar problem on SO, and an answer by osifo:
//create the sequelize instance omitting the database-name arg
const sequelize = new Sequelize("", "<db_user>", "<db_password>", {
dialect: "<dialect>"
});
return sequelize.query("CREATE DATABASE `<database_name>`;").then(data
=> {
// code to run after successful creation.
});
So, I was able to implement it in my own code:
var SQUser;
var sequlz;
async function connectDB() {
sequlz =
new Sequelize("", "jimmy", "users", {host: "localhost", port: 3306, dialect: "mysql"});
await sequlz.query("CREATE DATABASE users;");
await sequlz.query("Use users;");
SQUser = sequlz.define('Table',
{
// define table schema
});
return SQUser.sync();
};
//use sequelize to populate the table
async function create() {
const SQUser = await connectDB();
return SQUser.create(
//values
);
}

How can I handle the error, Only one type of resume option is allowed, but multiple were found?

I am using a replicated MongoDB database, and listen to change streams from my app. I use the following code to set this up and listen to a test table:
const url = 'mongodb://localhost:27017/?replicaSet=rs'
let client = new MongoClient(url, {
keepAlive: true,
connectTimeoutMS: 60000,
socketTimeoutMS: 60000,
})
try {
let dbclient = await client.connect()
console.log(dbclient)
const db = dbclient.db('test')
const collection = db.collection('accounts')
const changeStream = collection.watch(pipeline)
changeStream.on('change', function(change) {
console.log('changed', change)
})
} catch (err) {
console.log('mongo err:', err)
}
However occasionally, I receive the following error:
Uncaught MongoError: Only one type of resume option is allowed, but multiple were found.
This has occurred twice in the past 3 days, after the app has been idle for some time. I am not aware of any way to replicate it.
I am not finding any information on this error aside from this JIRA issue, which I am not sure has the same root cause or not to my issue. I am using the latest version of mongodb available on npm.
How can I catch this error and properly handle it?

CloudSQL connection issues with deployed Bookshelf tutorial app (App Engine/NodeJS)

I deployed my code on app engine with node js (flex environment).
config.json
{
"GCLOUD_PROJECT": "XXXXXX",
"DATA_BACKEND": "cloudsql",
"MYSQL_USER": "XXXX",
"MYSQL_PASSWORD": "XXXXX",
"INSTANCE_CONNECTION_NAME": "XXXXXX:us-central1:XXXXX"
}
model-cloudsql.js
const options = {
user: config.get('MYSQL_USER'),
password: config.get('MYSQL_PASSWORD'),
database: 'XXXXX'
};
if (config.get('INSTANCE_CONNECTION_NAME') && config.get('NODE_ENV') === 'production') {
options.socketPath = `/cloudsql/${config.get('INSTANCE_CONNECTION_NAME')}`;
}
const connection = mysql.createConnection(options);
I am getting below error:
"Cannot enqueue Query after fatal error."
please provides any feedback on it.
It looks like the error "Cannot enqueue Query after fatal error." happens when you try to query a connection that encounter a fatal error during create. If we check out the mysqljs documentation, it recommends connecting with the following:
var mysql = require('mysql');
var connection = mysql.createConnection({
host : 'example.org',
user : 'bob',
password : 'secret'
});
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return;
}
console.log('connected as id ' + connection.threadId);
});
As you can see, you need to pass along a callback function to handle any errors that may arise while you are attempting to connect. This callback function will print the error encountered to give you more info on why it failed to connect.
Additionally, you may be interested in this section on handling errors.

Automated Testing with Databases

I'm fairly new to automated testing and was wondering how I should go about writing tests for the database. The project I'm working on right now is running PostgreSQL with Sequelize as the ORM on a Node.JS environment. If it matters, I'm also using Jest as the testing library right now.
In my app I use a config module to control configuration settings for different environments. When running tests the process.env.APP_ENV is set to test, and it will set the dialect to sqlite. Note that you will not have any data or data persistence, so you will need to populate it with all the data needed for your tests.
Include sqlite3
yarn add -D sqlite3
or
npm i -D sqlite3
Config
module.exports = {
database: {
name: 'dbname',
user: 'user',
password: 'password',
host: 'host',
// Use "sqlite" for "test", the connection settings above are ignored
dialect: process.env.APP_ENV === 'test' ? 'sqlite' : 'mysql',
},
};
Database/Sequelize
// get our config
const config = require('../config');
// ... code
const instance = new Sequelize(
config.database.name,
config.database.user,
config.database.password,
{
host: config.database.host,
// set the dialect, will be "sqlite" for "test"
dialect: config.database.dialect,
}
);
Test Class (Mocha)
const TestUtils = require('./lib/test-utils');
describe('Some Tests', () => {
let app = null;
// run before the tests start
before((done) => {
// Mock up our services
TestUtils.mock();
// these are instantiated after the mocking
app = require('../server');
// Populate redis data
TestUtils.populateRedis(() => {
// Populate db data
TestUtils.syncAndPopulateDatabase('test-data', () => {
done();
});
});
});
// run code after tests have completed
after(() => {
TestUtils.unMock();
});
describe('/my/route', () => {
it('should do something', (done) => {
return done();
});
});
});
Run Tests
APP_ENV=test ./node_modules/.bin/mocha
You could use ENV variables in other ways to set the dialect and connection parameters as well - the above is just an example based on what we have done with a lot of supporting code.
If you're not doing anything particularly complicated on the DB side, take a look at pg-mem:
https://swizec.com/blog/pg-mem-and-jest-for-smooth-integration-testing/
https://github.com/oguimbal/pg-mem
It's really cool in that it tests actual PG syntax and can pick up a bunch of errors that using a different DB or mock DB won't pick up. However, it's not a perfect implementation and missing a bunch of features (e.g. triggers, decent "not exists" handling, lots of functions) some of which are easy to work around with the hooks provided and some aren't.
For me, having the test DB initialized with the same schema initialization scripts as the real DB is a big win.

Resources