Sequelize how to update json columns without select query - javascript

I want to update postgres column of json data type
columnData = [{"123":{a:1,b:2}}, {"456":{a:1,b:2}}]
expected = [{"123":{a:5,b:2}}, {"456":{a:1,b:2}}]
something "123".a =5 along with other values as it is.
I want to achieve this in single query
Model.update({columnData : columnData.123.a = 5});

Related

Sequelize how to return result as a 2D array instead of array of objects?

I am using Sequelize query() method as follows:
const sequelize = new Sequelize(...);
...
// IMPORTANT: No changed allowed on this query
const queryFromUser = "SELECT table1.colname, table2.colname FROM table1 JOIN table2 ON/*...*/";
const result = await sequelize.query(queryFromUser);
Because I am selecting two columns with identical names (colname), in the result, I am getting something like:
[{ "colname": "val1" }, { "colname": "val2" }...], and this array contains values only from the column table2.colname, as it is overwriting the table1.colname values.
I know that there is an option to use aliases in the SQL query with AS, but I don't have control over this query.
I think it would solve the issue, if there was a way to return the result as a 2D array, instead of the array of objects? Are there any ways to configure the Sequelize query that way?
Im afraid this will not be possible without changes in the library directly connecting to the database and parsing its response.
The reason is:
database returns BOTH values
then in javascript, there is mapping of received rows values to objects
This mapping would looks something like that
// RETURNED VALUE FROM DB: row1 -> fieldName:value&fieldName:value2
// and then javascript code for parsing values from database would look similar to that:
const row = {};
row.fieldName = value;
row.fieldName = value2;
return row;
As you see - unless you change the inner mechanism in the libraries, its impossible to change this (javascript object) behaviour.
UNLESS You are using mysql... If you are using mysql, you might use this https://github.com/mysqljs/mysql#joins-with-overlapping-column-names but there is one catch... Sequelize is not supporting this option, and because of that, you would be forced to maintain usage of both libraries at ones (and both connected)
Behind this line, is older answer (before ,,no change in query'' was added)
Because you use direct sql query (not build by sequelize, but written by hand) you need to alias the columns properly.
So as you saw, one the the colname would be overwritten by the other.
SELECT table1.colname, table2.colname FROM table1 JOIN table2 ON/*...*/
But if you alias then, then that collision will not occur
SELECT table1.colname as colName1, table2.colname as colName2 FROM table1 JOIN table2 ON/*...*/
and you will end up with rows like: {colName1: ..., colName2: ...}
If you use sequelize build in query builder with models - sequelize would alias everything and then return everything with names you wanted.
PS: Here is a link for some basics about aliasing in sql, as you may aliast more than just a column names https://www.w3schools.com/sql/sql_alias.asp
In my case I was using:
const newVal = await sequelize.query(query, {
replacements: [null],
type: QueryTypes.SELECT,
})
I removed type: QueryTypes.SELECT, and it worked fine for me.

getting distinct values from result set in taffyDB

I have a TAFFYDB database that consists of 4 fields:
clientID
cTech
arDate
active
What I want is a unique list of "cTech" for a certain clientID inside of a range of dates.
I can match clientID and dates like this:
var ret=clientTechsDB([{
"clientID":cFrom.toLowerCase(),
"arDate":{gte:sDfrom},
"arDate":{lte:sDto},
}]).get();
That returns the array "ret", but ret has many duplicated cTech values.
I tried
var ret=clientTechsDB([{
"clientID":cFrom.toLowerCase(),
"arDate":{gte:sDfrom},
"arDate":{lte:sDto},
}]).get().distinct("cTech");
but that generates and error "get(...).distinct is not a function"
I can iterate through and filter out duplicates but I was hoping to do it in a taffyDB query.
How?
You don't need "get" when using distinct. The correct syntax is:
var ret=clientTechsDB([{
"clientID":cFrom.toLowerCase(),
"arDate":{gte:sDfrom},
"arDate":{lte:sDto},
}]).distinct("cTech");

HTML5 SQL Insert Multiple Rows

I'm trying to insert multiple rows into an SQLite database.
Single row insert like this works fine:
tx.executeSql("INSERT or REPLACE INTO `table` (`type` , `pid` , `title` , `body`) VALUES (?,?,?,?) ", ['qa',v.id,v.title,v.content_html ] ,console_success, console_fail);
How can I pass an array of variables into that execute to run all at once?
(the paramiterizaion method seems to be properly sanitizing my data and inserting. when I do a raw query it does not and my sql fails. I need to inset a full html body in the DB )
so I can't just do a query like this
insert into table (a,b,c) values (a,b,c) ,(a,b,c),(a,b,c)
and escape() function messes up my html in the body.
P.S. NOT the same as this question HTML 5 SQLite: Multiple Inserts in One Transaction
As you found out, you should really stick to parametrized query and avoid "raw" queries. Parametrized queries will automatically escape the input for you thus preventing SQL injection.
The key here is to build a parametrized query that will fit your needs. Here is an example.
// Guessing 2d array of raw data
var dataArr = [ ['qa','123','title1','<html></html>' ],
['bc','456','title2','<html></html>' ],
['xy','789','title3','<html></html>' ] ];
// Creating a parametrized entry for every row of dataArr
var param = "(?,?,?,?),".repeat(dataArr.length).slice(0,-1);
// The insert query
var query = "INSERT or REPLACE INTO `MyTable` (`type` , `pid` , `title` , `body`) VALUES ";
// Convert the 2d dataArr into 1d data
var data = [];
for(var i = 0; i < dataArr.length; i++)
data = data.concat(dataArr[i]);
tx.executeSql(query + param, data); // Final query is : INSERT or REPLACE INTO `MyTable` (`type` , `pid` , `title` , `body`) VALUES (?,?,?,?),(?,?,?,?),(?,?,?,?)

tabulator update column data

I've a table set up with Tabulator with unknown data ( pulled from a file) so i can't make a column definitions setup for it except for general setup that works with any kind of data.
now I'm in situation that i need to add certain code for each row under column code which is included with the existing table.
i looked for away to add code something like SX0001 on the first row and just add 1 each row so the second row would be look like SX0002
I've checked this link http://tabulator.info/docs/4.1/update#alter-replace i saw some functions that works on rows but not columns .
solution i'm trying to achieve:-
the link includes under updateData function that i need to have index with default value (Id)
giving that I'm not sure what type of date it might have or be included with the table i've added a new column using this code
table.addColumn({title:"id", field: "id" , formatter:"rownum",width:40, align:"center"} , true)
now I don't know how to get the Length of the Column to loop through each one of the column and run function like this
var no = 1000;
var str = "SX";
var x = str + no ;
table.updateData([{id:1, code:x}]);
var no = no +1;
is there's anyway to do this ?
You can retrieve the data stored in the table using the getData function.
var data = table.getData();
This will return an array containing the data objects for each row in the table.
Then to get your lenght just do data.length
If you want to count the table data the getDataCount exactly for this, which returns a count of rows in the table:
var count = table.getDataCount();
But actually your current approach will result in the table being redrawn a load of times as you update the row data.
Mutators
Instead you should look at using a Mutator, these allow you to alter data as it enters the table, so in this case you could do something like this:
//global variable to keep track of row id
var rowCount = 0;
//custom mutator
var idMutator = function(value, data, type, params, component){
//increment rowCount and assign as column value
return rowCount++;
}
//in your column definition set this mutator
{title:"ID", field:"id", mutatorData:idMutator}
By using this approach the value is set as the data is loaded into the table, nothing needs to be redrawn and the whole proceess is much more efficient

how to fetch all values in single variable using java script

i am retrieving the all values in a for loop but i want to insert those values in database using single variable.It possible to store all values to the single record.
var emailId;
//log.info("testing 1234 = "+tw.local.EntityProMasterList.listAllSelected);
for (var i = 0; i < tw.local.EntityProMasterList.listAllSelected.listLength; i++){
emailId = tw.local.EntityProMasterList.listAllSelected[i];
log.info("testing 1 = "+emailId.value);
}
log.info("testing 1 = "+emailId.value);
You can user JSON.stringify() and save it as string:
var holder = {};
holder.var1 = "var1";
holder.var2 = "var2";
log.info("holder:"+JSON.stringify(holder));
The output will be:
holder:{"var1":"var1","var2":"var2"}
I believe your question is - given a list of values, how can I insert those values into the database as separate entries. If this is correct there is a right way and a wrong way to do this.
The wrong way is to simply put all the SQL into a string and use one of the DB services in the system data toolkit to execute. Something like -
insert into table blah values(1, 2, 3, 4);
This would be wrong because you are open to SQL injection attacks. There is a different service for parameterized queries. This takes 1 or more SQL statements and a list of parameters to use in them. The details are documented in the service so I won't repeat them here. Basically you would modify your query to have the ? Character where you need the data from your array. You then create arrays of parameters that fill out the values on execution.

Categories

Resources