-
Notifications
You must be signed in to change notification settings - Fork 99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: reject filter objects in destroyAll method #132
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't the fix live in Juggler?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the test failures related to this PR?
@virkt25 The fix could live in juggler, but based on strongloop/loopback#3094 (comment), I opted to have it here and since juggler's EDIT: Also, the failures on db2/dashdb are not related to this PR. |
lib/sql.js
Outdated
} else { | ||
throw new Error('Filter object detected. Please use a where object instead.'); | ||
} | ||
} | ||
var p = props[key]; | ||
if (p == null) { | ||
// Unknown property, ignore it |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, the change proposed above is not really fixing the problem.
For example, consider a Product
model with a name
property, the developer making a typo in their query and calling Product.destroyAll({names: 'Pen'})
. Right now, the entire SQL table is deleted. IMO, the correct behavior is that no records should have been deleted.
I think the root cause of this whole issue lies here.
var p = props[key];
if (p == null) {
// Unknown property, ignore it
debug('Unknown property %s is skipped for model %s', key, model);
continue;
}
Instead of ignoring unknown properties, we need to construct a WHERE statement that is not going to match any record, or perhaps throw an error as you proposed above (but please use a different error message to better describe the new intent).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch! Thank you for illustrating what is IMO another big issue from the original ticket (among others). While I'm working on that, I want to keep what I have because it ensures rejection of filter
objects. Do you have suggestions on how I can improve that (test case is here)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about the following?
var p = props[key];
if (p == null) {
- // Unknown property, ignore it
- debug('Unknown property %s is skipped for model %s', key, model);
- continue;
+ throw new Error(
+ `Unknown property ${key} used in a "where" condition for model ${model}`
+ );
}
This is an important question. I think the new behavior should be enabled by default, because it makes more sense and is safer for LB users. However, there may be applications out there that rely on the current behavior and will break after update. To mitigate that, I think it makes sense to introduce a feature flag allowing applications to switch to the old behavior. Since the new feature flag is relevant only for SQL-based connector, I think it makes most sense to define it at datasource/connector-setting level (configured in |
That sounds great. Thank you for pointing out where it should be defined too! I'll take a crack at it. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Please review all places that may call
_buildWhere
and make sure they report catch the new error and report it via the callback. An easy example:save
. We need to look for places that are calling other helpers that eventually call_buildWhere
, e.g. code calling_constructUpdateQuery
. -
Please add tests to cover these changes.
-
What's your opinion on the feature flag discussed above - should it be implemented as part of this pull request?
debug('Unknown property %s is skipped for model %s', key, model); | ||
continue; | ||
throw new Error( | ||
`Unknown property ${key} used in a "where" condition for model ${model}` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would be nice if we could list all unknown properties in the error message.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
This issue has been closed due to continued inactivity. Thank you for your understanding. If you believe this to be in error, please contact one of the code owners, listed in the |
Description
Connect to loopbackio/loopback-datasource-juggler#1597 and strongloop/loopback#3094. The first commit ensures that we reject filter objects passed on to the
destroyAll
method. This should be applicable to all the SQL connectors.EDIT: The second commit ensures that we reject objects with keys that are not part of the model properties in
destroyAll
method. This should be applicable to all the SQL connectors.Related issues
Checklist
guide