I would like to setup my prepared statements with the mssql module. I created a query file for all user related requests.
const db = require('../databaseManager.js');
module.exports = {
getUserByName: async username => db(async pool => await pool.request()
.input('username', dataTypes.VarChar, username)
.query(`SELECT
*
FROM
person
WHERE
username = #username;`))
};
This approach allows me to require this query file and access the database by executing the query that is needed
const userQueries = require('../database/queries/users.js');
const userQueryResult = await userQueries.getUserByName(username); // call this somewhere in an async function
My database manager handles the database connection and executes the query
const sql = require('mssql');
const config = require('../config/database.js');
const pool = new sql.ConnectionPool(config).connect();
module.exports = async request => {
try {
const result = await request(pool);
return {
result: result.recordSet,
err: null
};
} catch (err) {
return {
result: null,
err
}
}
};
When I run the code I get the following error
UnhandledPromiseRejectionWarning: TypeError: pool.request is not a
function
Does someone know what is wrong with the code?
I think this happens because the pool is not initialized yet... but I used async/await to handle this...
Here is how I made your code work (I did some drastic simplifications):
const sql = require("mssql");
const { TYPES } = require("mssql");
const CONN = "";
(async () => {
const pool = new sql.ConnectionPool(CONN);
const poolConnect = pool.connect();
const getUserByName = async username => {
await poolConnect;
try {
const result = await pool.request()
.input("username", TYPES.VarChar, username)
.query(`SELECT
*
FROM
person
WHERE
username = #username;`);
return {
result: result.recordset,
err: null
};
} catch (err) {
return {
result: null,
err
};
}
};
console.log(await getUserByName("Timur"));
})();
In short, first read this.
You probably smiled when saw that the PR was created just 2 months before your questions and still not reflected in here.
Basically, instead of:
const pool = new sql.ConnectionPool(config).connect();
you do this:
const pool = new sql.ConnectionPool(config);
const poolConnection = pool.connect();
//later, when you need the connection you make the Promise resolve
await poolConnection;
Related
ideally id like to move the line out of the function entirely but the only way i know to do this is in the function itself. the 'poolConnection' seems to be of the type 'mysql.PoolConnection', so id assume the query function is something like 'mysql.PoolConnection.query', but i cant find any way to modify the 'query' without writing it like 'poolConnection.query', which ties it to that specific connection. it seems like there should be a easy way to do this.
const discord = require('discord.js');
const config = require('./config.json');
var mysql = require('mysql');
const util = require('util');
const client = new discord.Client();
connection.connect(function(err) {
if (err) throw err;
client.login(config.token);
});
client.on('message', message => test());
let pool = mysql.createPool(poolConfig);
const getPoolConnection = util.promisify(pool.getConnection).bind(pool);
const endPool = util.promisify(pool.end).bind(pool);
async function test()
{
try
{
let poolConnection = await getPoolConnection();
//can the follow line be made so its not specific to one connection in the pool?
poolConnection.query = util.promisify(poolConnection.query);
let sql = `INSERT INTO user(UserID) VALUES(${01});`;
let sql2 = `INSERT INTO user(UserID) VALUES(${02});`;
await poolConnection.beginTransaction();
let results = await poolConnection.query(sql);
let results2 = await poolConnection.query(sql2);
await poolConnection.commit();
await poolConnection.release();
await endPool();
console.log(results);
console.log(results2);
}
catch(error)
{
console.log(error);
}
}
I have an app built with angular and node.js (with pg npm package, version = 8.7.1)
The app divided to microservice . Each server-app have "pg" package installed and have a connection to postgres db.
The problem is that if I run some "update" query and after this I running getList query, then I Got the old value instead the updated object. If I add setTimeout for 5 sec then it works fine
On my localhost all works fine. The issue occur only on heroku (with postgres on cloud) on the srever. sometimes I got the updated data and sometimes not
Here is my code:
Client code (angular) - calling to update func and then getList func with async & await
async filter({ value }) {
const list: any = await this.getList()
const [myData]: any = await this.updateData(this.value)
const list: any = await this.getList() // Here is the issue !!
}
The function calls to API to the server like this:
getList(): Promise<any> {
return this.http.get<any>(`${ENV.BASE_API}/doGetApiCalls`).toPromise();
}
updateData(value: any): Promise<any> {
return this.http.put<any>(`${ENV.BASE_API}/doUpdateApiCalls`, value).toPromise();
}
The server code is:
Bl code
async function updateData(description, id) {
let query = updateDataQuery(description, id);
let results = await postgressQuery(query);
return getDataResults;
}
DEL code
function updateDataQuery(description: string, id:number) {
const query = `UPDATE public.books
SET description='${description}',
WHERE book =${id}
RETURNING *`
return query;
}
And here is the connection to postgres db (BL calling to lib by import this)
const DATABASE_URL = process.env.DATABASE_URL;
const pool = new Pool({
connectionString:DATABASE_URL,
ssl:{rejectUnauthorized: false}
})
let openConnect = async () => {
await pool.connect();
}
let postgressQuery = async (q) => {
try {
const result = await pool.query(q);
return await result.rows;
}
catch (e) {
console.log(e);
}
}
========================================================
If I added await to client then it works fine. It takes a while for update?
async filter({ value }) {
const list: any = await this.getList() //
const [myData]: any = await this.updateData(this.value) //get the RETURN from server with correct data
await new Promise(resolve => setTimeout(resolve, 5000)) //added for wait for 5 sec
const list: any = await this.getList() // then data is correct (aafer 5 sec)
}
What wrong in this code above ?
Thanks in advance
I found a solution:
It was cache issue. Just need to install this package and all fine !
https://www.npmjs.com/package/nocache
I am trying to create an RTMP-server with the npm package: http://github.com/illuspas/Node-Media-Server. So the server works fine but I need to implement authentication in it. I am trying to check the authentication on "prePublish" event. I am querying the database and retrieving the user if the user was found then I want to let the user stream otherwise rejected. But the problem is, it doesn't leave it instead disconnects and then the stream automatically reconnected to it then it disconnects again and the loop goes on. How do I fix this problem?
Here is the code for the event:
const NodeMediaServer = require('node-media-server');
const config = require('./config').rtmp_server;
const db = require('./db');
const nms = new NodeMediaServer(config);
const getStreamKeyFromStreamPath = (path) => {
const parts = path.split('/');
return parts[parts.length - 1];
};
nms.on('prePublish', async (id, StreamPath, args) => {
const session = nms.getSession(id);
try {
const streamKey = getStreamKeyFromStreamPath(StreamPath);
const validStream = (
await db.query('SELECT * FROM public."People" WHERE stream_key = $1', [streamKey])
).rows[0];
console.log(validStream);
if (validStream) {
// do stuff
} else {
session.reject((reason) => {
console.log(reason);
});
}
console.log(
'[NodeEvent on prePublish]',
`id=${id} StreamPath=${StreamPath} args=${JSON.stringify(args)}`
);
} catch (err) {
session.reject();
}
});
module.exports = nms;
Here is the code of the entry point of the server:
require("dotenv").config();
const db = require("./db");
const nms = require("./nms");
// database connection
db.connect()
.then(() => {
console.log("Connected to database");
// start the rtmp server
nms.run();
})
.catch((err) => console.log(err.message));
Here is the db file:
const { Pool } = require('pg');
const connectionString = process.env.PG_CONNECTION_STRING;
const poolOptions = {
host: process.env.PG_HOST,
user: process.env.PG_USER,
port: process.env.PG_PORT,
password: process.env.PG_PASSWORD,
database: process.env.PG_DATABASE,
};
const pool = new Pool(process.env.NODE_ENV === 'production' ? connectionString : poolOptions);
module.exports = pool;
My procedures to solve that problem:
Instead of the async function, I tried to handle the database query using a callback but it didn't work.
Before I was calling session.reject() now I am passing a callback there but the behavior is still the same
If you have any solution for that, please let me know.
Thanks in advance
I use node js and postgres as well as chai and mocha for tdd, and now I have encountered a problem when I try to update an item in my database with a wrong foreign key. When this happens I want to basically get the old item from the database with the valid values.
this is the update method in the Item class
async update() {
if (this.description.length === 0) {
throw new Error("Description can not be deleted");
}
try {
const updateItem = await this.tryUpdate();
this.copyToThis(updateItem);
} catch (e) {
const oldItem = await Item.getById(this.id);
this.copyToThis(oldItem);
console.log(this);
throw new Error("Updating did not work");
}
}
This is the test that fails
it('should throw an error if you update with wrong category or project id and get the old values from the server', async function () {
const newProject = "3b4e092e-1dd9-40a5-8357-69696b3e35ba";
const newCategory = "3cf87368-9499-4af1-9af0-10ccf1e84088";
const item = await Item.getById(updateId);
expect(item).to.exist;
const oldProjectId = item.projectId;
const oldCategoryId = item.categoryId;
item.projectId = newProject;
expect(item.update()).to.be.rejectedWith(Error);
item.categoryId = newCategory;
expect(item.update()).to.be.rejectedWith(Error);
expect(item.categoryId).to.equal(oldCategoryId);
expect(item.projectId).to.equal(oldProjectId);
});
this is the AssertionError
-3cf87368-9499-4af1-9af0-10ccf1e84088
+3cf87368-9499-4af1-9af0-10ccf1e84087
As you can see the item still has the wrong categoryId and not the one from the server. Eventhough the log has the correct item.
I solved it myself
I needed to add an await in the test
it('should throw an error if you update with wrong category or project id and get the old values from the server', async function () {
const newProject = "3b4e092e-1dd9-40a5-8357-69696b3e35ba";
const newCategory = "3cf87368-9499-4af1-9af0-10ccf1e84088";
const item = await Item.getById(updateId);
expect(item).to.exist;
const oldProjectId = item.projectId;
const oldCategoryId = item.categoryId;
item.projectId = newProject;
await expect(item.update()).to.be.rejectedWith(Error);
item.categoryId = newCategory;
await expect(item.update()).to.be.rejectedWith(Error);
expect(item.categoryId).to.equal(oldCategoryId);
expect(item.projectId).to.equal(oldProjectId);
});
i want to pick my mysql response.
this is my code.
let [isTrue] = await conn.query("select user_key, isvalid from auth where user_key = ?", [user_key]);
console.log(isTrue);
This response was [ TextRow { user_key: '123445', isvalid: 1 } ]
That's good. But i want to get a value of user_key.
So I typed this code.
console.log(isTrue.user_key)
But this result was only undefined
How can i get a value of user_key??
instead of "await conn.query" use like this "await query".
Example
const mysql = require('mysql'); // or use import if you use TS
const util = require('util');
const conn = mysql.createConnection({host:"localhost", user:"root", password:"root", database:"test"});
// node native promisify
const query = util.promisify(conn.query).bind(conn);
(async () => {
try {
//const rows = await query('select count(*) as count from users ');
//console.log(rows);
var user_key = 1;
const [isTrue] = await query("select id,name from users where id = ?", [user_key]);
console.log(isTrue.name);
}
catch(err) {
throw new Error(err)
}
finally {
conn.end();
}
})();