Query is working on phpmyadmin but not in express - mysql

I have a problem with a MySQL query, I'm making a controller where I need a filter on the front (React). The controller is made with params inside the route, but is not working when I try to test it with Postman, but if I make the same exact query on phpmyadmin works perfectly.
Controller:
let { tabla, nameUno, fechaIni, fechaFin, nameDos, nameTres, nameCuatro } =
req.params;
conn.query(
// SELECT * FROM tyt_finan WHERE tf_fecha_r BETWEEN '2022-05-31' AND '2022-06-01' AND tf_city IN ('Bogota') AND tf_estado = 'Pendiente' AND tf_campana = 'IN'
"SELECT * FROM " +
tabla +
" WHERE " +
nameUno +
" BETWEEN " +
fechaIni +
" AND " +
fechaFin +
" AND " +
nameDos +
" IN ('') AND " +
nameTres +
" = ? AND " +
nameCuatro +
" = ?",
[req.params.value1, req.params.value2, req.params.value3],
Routes
routes.get(
"/searchAll/:tabla/:nameUno/:fechaIni/:fechaFin/:nameDos/:value1/:nameTres/:value2/:nameCuatro/:value3",
defaultController.searchAll
);
And this is the GET petition that I'm sending on Postman:
http://localhost:9000/searchAll/tyt_finan/tf_fecha_r/'2022-05-31'/'2022-06-01'/tf_city/'Bogota','Barranquilla'/tf_estado/'Pendiente'/tf_campana/'IN'

Use parameters for the variables. It's also easier to use a template literal than concatenation to construct the SQL string with variables for the table and column names.
You also had more values in your parameters array than ? in the SQL. I've replaced IN ('') with = ? to use value1 there.
let {tabla, nameUno, fechaIni, fechaFin, nameDos, value1, nameTres, value2, nameCuatro, value3} = req.params;
conn.query(
`SELECT *
FROM ${tabla}
WHERE ${nameUno} BETWEEN ? AND ?
AND ${nameDos} = ?
AND ${nameTres} = ?
AND ${nameCuatro} = ?`, [fetchaIni, fechaFin, value1, value2, value3], (err, res) => {
if (!err) {
console.log(res);
}
});

Related

How to query DynamoDB in AWS using a number partition key

I'm currently having trouble querying a DynamoDB table where the partition key, id, is of type number. This is for a wider project for my own Alexa Skill on AWS. My skill will take as input from the user, a unique id value, which is of slot type AMAZON.NUMBER.
I've looked at the documentation for query and nothing I've tried worked so I decided to start from scratch to a template.
Again, I am just trying to query a table for data based on a partition key called "id" that has a numeric value. The Code below is what I have managed to narrow down as the source of the error.
var params = {
TableName : "QueryTestTable",
KeyConditionExpression: "#pkey = :value",
ExpressionAttributeNames:{
"#pkey": "id"
},
ExpressionAttributeValues: {
":value": idNumber
}
};
return docClient.query(params, function(err,data) {
if (err) {
console.error("Unable to query. Error:", JSON.stringify(err, null, 2));
} else {
console.log("Query succeeded.");
console.log("data = " + JSON.stringify(data,null,2));
data.Items.forEach(function(item) {
console.log(" -", item.id + ": " + item.firstName);
results += item.id + " has name " +item.firstName + " " + item.lastName + ".\n";
});
}
if (results)
speakOutput = results;
else
speakOutput = "Sorry, no result for " + idNumber +" was found in the database.";
return handlerInput.responseBuilder
.speak(speakOutput)
.reprompt()
.withSimpleCard(SKILL_NAME, speakOutput) //added to generate video output.
.getResponse();
})
I'm just using a simplified version of my table for now. But the above code snippet. For some reason, It keeps skipping to the no entries found in the database statement.

How to stub mysql query using some mock data and mocha in node js

My requirement is to use stubbing in unit testing script to bypass some actual mysql query using a mock data. I'm using mocha testing framework and chai. I don't know how to use mock data to bypass the mysql query.
I tried with some testing variable and if the variable is true i'm just bypassing the mysql query with predefined mock data. But that's not a proper proceedure. So can you please explain me how to use sinon stub to overcome mysql using mock data.
let query_response = await sequelize.query("select * from `" + table_name + "` where email='" + data.user + "' and name = '" + name + "' " + pre_name + ";", {
type: sequelize.QueryTypes.SELECT
});
In unit testing i need to bypass this query and give response using some mock data. The response should be like this,
[ { id: '3',
xyz_id: 'Z1455264',
vir_id: '264_3',
name: 'XYZ',
pre_name: 'abc',
value: 1 },
{ id: '32',
xyz_id: 'Z1455dd264',
vir_id: '26s4_3',
name: 'XYZQ',
pre_name: 'abdc',
value: 1 }];
There are a bunch of ways (dependency injection, runtime module replacement, etc) to do it and a bunch of libraries to help you. It's up to the level of abstraction you have and how neat you want it. The quick and dirty way is to use something like proxyquire and a mocking library like testdouble.
With your sut.js (the module/system you will be testing), you would have:
const sequelize = require('sequelize')
// ...
exports.doSomething = async function () {
await sequelize.query("select * from `" + table_name + "` where email='" + data.user + "' and name = '" + name + "' " + pre_name + ";", {
type: sequelize.QueryTypes.SELECT
})
}
And in your test you could do the following (agnostic to the testing framework):
const proxyquire = require('proxyquire')
const td = require('testdouble')
const sequelize = require('sequelize')
const query = td.function()
const sut = proxyquire('/path/to/your/sut.js', { 'sequelize': { query } })
const expected = [{
id: '3',
xyz_id: 'Z1455264',
vir_id: '264_3',
name: 'XYZ',
pre_name: 'abc',
value: 1
}, {
id: '32',
xyz_id: 'Z1455dd264',
vir_id: '26s4_3',
name: 'XYZQ',
pre_name: 'abdc',
value: 1
}];
td.when(query("select * from `<the_table_name>` where email='<the_email>'...", { type: sequelize.QueryTypes.SELECT })).thenResolve(expected);
// assert whatever you need from sut.doSomething()

Determine which PropertyInfos of a generic TEntity are primary keys via reflection

I am writing a MySQL INSERT ... ON DUPLICATE KEY UPDATE implementation via a raw SQL command in EF Core 2.0. I am very close to a working solution, but the only problem that I have is determining which PropertyInfos read via reflection are primary keys. In the CreateUpdates() method below, how can I filter primary keys out from columnProperties so they are not a part of the update SQL statement?
I have tried using EntityFramework.PrimaryKey
, but I cannot seem to get it to work with generics (TEntity).
I have included all of my relevant code, but the piece I am focused on in this question is the TODO in the last method, CreateUpdates().
private static void InsertOnDuplicateKeyUpdate<TEntity>(DbContext dbContext) where TEntity : class
{
var columnProperties = GetColumnPropertiesLessBaseEntityTimestamps<TEntity>();
var tableName = GetTableName<TEntity>();
var columns = string.Join(", ", columnProperties.Select(x => x.Name));
var values = CreateValues<TEntity>(columnProperties);
var updates = CreateUpdates(columnProperties);
var rawSqlString = "INSERT INTO " + tableName + " (" + columns + ") VALUES " + values +
" ON DUPLICATE KEY UPDATE " + updates;
dbContext.Set<TEntity>().FromSql(rawSqlString);
dbContext.SaveChanges();
}
private static string GetTableName<TEntity>()
{
return typeof(TEntity).Name.Pluralize().ToLower();
}
private static List<PropertyInfo> GetColumnPropertiesLessBaseEntityTimestamps<TEntity>()
{
return typeof(TEntity).GetProperties().Where(x =>
x.PropertyType.Namespace != "System.Collections.Generic" &&
!new List<string> {"CreatedDateUtc", "ModifiedDateUtc"}.Contains(x.Name)).ToList();
}
private static string CreateValues<TEntity>(IReadOnlyCollection<PropertyInfo> columnProperties)
{
return GetSeedRows<TEntity>().Select(row => CreateRowValues(columnProperties, row)).Aggregate("",
(current, rowValues) => current == "" ? rowValues : current + ", " + rowValues);
}
private static string CreateRowValues<TEntity>(IEnumerable<PropertyInfo> columnProperties, TEntity row)
{
return (from property in columnProperties
let value = row.GetType().GetProperty(property.Name).GetValue(row)
select WrapStringPropertyValueInSingleQuotes(property, value)).Aggregate("",
(current, value) => current == "" ? "(" + value : current + ", " + value) + ")";
}
private static object WrapStringPropertyValueInSingleQuotes(PropertyInfo property, object value)
{
if (property.PropertyType == typeof(string))
value = "'" + value + "'";
return value;
}
private static string CreateUpdates(IEnumerable<PropertyInfo> columnProperties)
{
//TODO: filter out primary keys from columnProperties
return columnProperties.Select(property => property.Name).Aggregate("", (current, column) => current == ""
? column + " = VALUES(" + column + ")"
: current + ", " + column + " = VALUES(" + column + ")");
}
In ef-core it has become much easier to retrieve meta data from the mapping model. You can get the PropertyInfos of the primary key by this line:
var keyPropertyInfos = dbContext.Model.FindEntityType(typeof(TEntity))
.FindPrimaryKey()
.Properties
.Select(p => p.PropertyInfo);
By the way, you can get all (mapped) properties by replacing FindPrimaryKey().Properties by GetProperties();

Make query after query with nodejs and sequelize

I want to make a query after another query in node.js with sequqlize. Second query iterate ower the first elements query result.
The code:
exports.index = function(req, res) {
sqldb.sequelize.query("select * from food", {type: sqldb.sequelize.QueryTypes.SELECT})
.then(function (food) {
for (var i = food.length; i--;) {
sqldb.sequelize.query("select i.name_ingredient " +
"from food_incredients as fi, " +
"ingredients as i " +
"where fi.food_id = " + food[i].id + " and " +
"i.id = fi.ingredient_id;",
{type: sqldb.sequelize.QueryTypes.SELECT}).then(function (ingredients) {
food[i]["ingredients"] = ingredients;
});
}
res.status(200).json(food);
}
);
At the line when I try to add "infredients" field I reveive an error that the "food[i]" object is undefined. How can I fix this problem and return the "food" with ingredients for every elements?
Thanks

NodeJS - MySQL query error

My query works fine if the person exist in my table, but if he/she does not; the NodeJS will give me an error.
function ClientConnected(remoteClient)
{
debugLog(remoteClient.name + " connected to the server. (ID: " + remoteClient.networkId + ") Loading player data..");
sql.query('SELECT * FROM `players` WHERE `character_name` = ?', [remoteClient.name], function(err, rows)
{
if(err)
{
debugLog('[DB] Error when loading ' + remoteClient.name + "'s (" + remoteClient.networkId + ') data: ' + err.code);
} else {
players[remoteClient.networkId] = {
'a_socialid' : rows[0].account_socialid,
'i_money' : rows[0].inventory_money,
};
debugLog("Successfully loaded " + remoteClient.name + "'s (" + remoteClient.networkId + ") data..");
}
});
}
events.Add("ClientConnected", ClientConnected);
If someone joins with the name that already exists in the table, it will load the players data:
But if not, it gives me an error. (TypeError, undefined, blabla)
You need to check that a record was returned. Maybe something like this:
if(err)
{
debugLog('[DB] Error when loading ' + remoteClient.name + "'s (" + remoteClient.networkId + ') data: ' + err.code);
} else if (rows.length === 0) {
debugLog('Nothing returned from database');
} else {
// ...
}
Presumably the err result would only give you feedback on the actual query, not the data it returns.