Adding a column and updating all records using knex and postgres - postgresql

I need to add a column to my table of riders, allowing us to store the name of the image that will display on that rider's card. I then need to update all of the records with the auto-generated image names.
I've done a bunch of searching, and all roads seem to lead back to this thread or this one. I've tried the code from both of these threads, swapping in my own table and column names, but I still can't get it to work.
This is the latest version of the code:
export async function up(knex, Promise) {
return knex.transaction(trx => {
const riders = [
{
name: 'Fabio Quartararo',
card: 'rider_card_FabioQuartararo'
},
...24 other riders here...
{
name: 'Garrett Gerloff',
card: 'rider_card_GarrettGerloff'
},
];
return knex.schema.table('riders', (table) => table.string('card')).transacting(trx)
.then(() =>{
const queries = [];
riders.forEach(rider => {
const query = knex('riders')
.update({
card: rider.card
})
.where('name', rider.name)
.transacting(trx); // This makes every update be in the same transaction
queries.push(query);
});
Promise.all(queries) // Once every query is written
.then(() => trx.commit) // We try to execute all of them
.catch(() => trx.rollback); // And rollback in case any of them goes wrong
});
});
}
When I run the migration, however, it fails with the following error:
migration file "20211202225332_update_rider_card_imgs.js" failed
migration failed with error: Cannot read properties of undefined (reading 'all')
Error running migrations: TypeError: Cannot read properties of undefined (reading 'all')
at D:\Users\seona\Documents\_Blowfish\repos\MotoGP\dist\database\migrations\20211202225332_update_rider_card_imgs.js:134:25
at processTicksAndRejections (node:internal/process/task_queues:96:5)
So it's clearly having some sort of problem with Promise.all(), but I can't for the life of me figure out what. Searching has not turned up any useful results.
Does anyone have any ideas about how I can get this working? Thanks in advance.

I think you might be following some older documentation and/or examples (at least that's what I was doing).
The Promise argument is no longer passed into the migration up and down functions.
So, the signature should be something like this:
function up(knex) {
// Use the built in Promise class
Promise.all(<ARRAY_OF_QUERY_PROMISES>);
...
}

Related

Prisma findFirstOrThrow does not throw

Using prisma I am trying to write some tests, however the findFirstOrThrow method (https://www.prisma.io/docs/reference/api-reference/prisma-client-reference#findfirstorthrow) does not seem to throw when nothing should be found. Instead it is returning the first database record it finds.
The following piece of code is what I am testing
console.log('sessionId', this.ctx.session?.user?.id);
const author = await this.db.author.findFirstOrThrow({
where: { userId: this.ctx.session?.user?.id },
select: { id: true },
});
console.log({ author });
And in my test output I get the following logs
RERUN src/api/service.ts x31
stdout | src/api/service.test.ts > BlockService > block creation > without an author
sessionId undefined
stdout | src/api/service.test.ts > BlockService > block creation > without an author
{ author: { id: 'cle79pisg007hb2b8rhpii1ws' } }
So even though the this.ctx.session?.user?.id is undefined, prisma still returns the first author in the table.
What I've tried so far:
When not populating the authors table in the test it will throw.
When populating the authors table with a single author it will return this author
When giving an explicit undefined as the userId it will still returns the first record
edit: I use prisma ^4.8.0
This is the expected behaviour.
If you will pass undefined then it is equivalent to not passing any userId.
So, the query is equivalent to the following:
const author = await this.db.author.findFirstOrThrow({
where: { },
select: { id: true },
});
And this query would return the first record from database.
For reference, here is the section that defines this behaviour.

How to Validate /check the input fields value exist in back end DB or not during live change in sapui5

I have requirement where in need to create the record from SAPui5 application,
For that we have Form and enterthe all details and submit to the data base.
Now i need to validate the first field value, if that value exist in the system/DB need to populate the error, like this record already exist during livechange.
For E.g., Input fields are as follows.
Empld : 121
EmpName : tom
On Change of Empid value need to check 121 record exist in the database or not.
Following are the blogs refereed for the solution but didn't get the solution for the same.
https://blogs.sap.com/2015/10/19/how-to-sapui5-user-input-validations/
https://blogs.sap.com/2015/11/01/generic-sapui5-form-validator/
As i"m new to SAPUI5.Please help me with the coding.
Thanks in advance.
I don't know how much you are aware of Requests to the Backend but maybe you could make a Read Operation and check if there is any data returned:
First solution could be like this (with Entity key):
this.getOwnerComponent().getModel().read("/EntityPath", {
success: function(oData, response) {
if(oData.results.length === 0) {
console.log("Nothing found for this key");
}
},
error: function(oError) {
//Error Handling here
}
});
Or you could build a Filter, pass it to the read operation and check if there is any data returned:
var aFilter = new sap.m.Filter(new Filter("EmpId", sap.m.FilterOperator.EQ, "value"));
this.getOwnerComponent().getModel().read("/EntitySet", {
filters: aFilter,
success: function(oData, response) {
if(oData.results.length === 0) {
console.log("User is not available");
}
},
error: function(oError) {
//Error Handling here
}
});
However, this isn't the best way to check if there is already an entry in your database. You should do this in your Business Logic with Error Messages which get passed to the Frontend.
Hope this helps :-)

Sequelize js transaction on destory and bulkCreate not rolling back

I am trying to delete all report_details before bulkCreate/insert the new ones. The problem is when there is an error in bulkCreate it does not rollback. It should bring the destroyed report_details back but it is not working.
The way i am testing this transaction code is I insert the report_details and then manually change one column name so that when inserting again it gives column error. and transaction should rollback but in actual report_details are destroyed and on bulkCreate error it does not bring back destroyed report_details
can some one please take a look on my code. I have search on google my syntax is correct.
and how do i test transactions on my machine ? instead of changing the column name is there any other way to produce error?
function saveReportsDetails(results) {
db.report_detail.bulkCreate(results.report.objAllReportsDetail);
return db.snpreq.transaction(t => {
// transaction block
return db.report_detail.destroy({
where: {
profile_id: results.profile.data[0].id
}
}, {
transaction: t
}).then(deleted => {
console.log('*******TRANSACTION DELETED*********');
return db.twenreport_detail.bulkCreate(results.report.objAllReportsDetail, {
transaction: t
}).then(reports_created => {
console.log('*******TRANSACTION bulk created*********');
});
});
}).then(transaction => {
console.log('********All Transaction********');
}).catch(err => {
console.log('*******ROLL BACK*********');
});
}
There was error in m code syntax. In delete transaction it takes transaction: t in single argument
like this
return db.twentythree_and_me_report_detail.destroy({
where: {
profile_id: results.profile.data[0].id
},
transaction: t
})
I was not receiving any kind of syntax error or any other error. so, i just kept search and found answer

Meteor (Iron Router subscriptions): handling server errors with waitOn

I'm attempting to redirect my users to a 404 page (or even to home) if they stumble onto a page for which there is no database match.
My waitOn code (inside the Iron Router Route)
waitOn: function(){
return Meteor.subscribe('cars', this.params.slug);
},
My publish method:
Meteor.publish("cars", function (slug) {
var selectedCar = Cars.findOne({slug: slug})._id;
return [
Cars.find({ _id: selectedCar}),
Parts.find({carid: selectedCar}),
]
});
Everything is fine, except waitOn hangs whenever someone visits a page for which there is no matching Car (i.e the :slug doesn't match anything in the database)
Example Server error:
Exception from sub cars id CTusRZSAPqJaK9ws3 TypeError: Cannot read
property '_id' of undefined
I've tried all sorts of things as recommended on various blogs/posts, and still not sure how to deal with such server errors when waitOn is involved.
Has anyone been able to deal with such errors in their subscriptions?
In your current code you are not handling the case where findOne method might return undefined as a result.
Please modify your publication:
Meteor.publish("cars", function (slug) {
var selectedCar = Cars.findOne({slug: slug});
if (selectedCar) {
return [
Cars.find({ _id: selectedCar._id}),
Parts.find({carid: selectedCar._id}),
]
}
this.ready()
});
in above code if findOne returns an undefined result, we are calling the this.ready() method which will set the subscription ready.
on the client side if you don't receive any data in your subscription you can display the 404 message (item not found).
Also you should validate the slug, before querying. Just to avoid any nosql injection. for that you could use the check package.

Meteor-Mongo: Error handling for findone

I am trying to handle errors using findOne in meteor-mongo.
From this stackoverflow question, it appears that I should be able to handle errors by doing collection.findOne({query}, function(err, result){ <handleError> }, but doing so results in an errormessage:
"Match error: Failed Match.OneOf, Match.Maybe or Match.Optional validation"
The following code works:
export default createContainer((props) => {
let theID = props.params.theID;
Meteor.subscribe('thePubSub');
return {
x: theData.findOne({_id: theID}),
};
}, App);
The following code does not:
export default createContainer((props) => {
let theID = props.params.theID;
Meteor.subscribe('thePubSub');
return {
x: theData.findOne({_id: theID}, function(err,result){
if(!result){
return {}
};
}),
};
}, App);
What am I doing wrong and how should I be resolving this error? Is this a meteor specific error?
Any help is greatly appreciated!
What kind of error are you exactly trying to handle with your callback?
Meteor's findOne is different from node's mongodb driver's findOne that the post you link to uses.
The expected signature is:
collection.findOne([selector], [options])
There is no callback involved, since the method runs synchronously (but is reactive).
If you want to return a default value when the document is not found, you can simply use a JS logical OR:
// Provide an alternative value on the right that will be used
// if the left one is falsy.
theData.findOne({_id: theID}) || {};
A more rigorous approach would be to compare its type with
typeof queryResult === 'undefined'
Note that if theData collection is fed by the above subscription Meteor.subscribe('thePubSub'), I doubt Meteor will have time to populate the collection on the client by the time you query it…