-
Notifications
You must be signed in to change notification settings - Fork 236
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
feat: adds mongodb: {dataType: 'ObjectID'} to model properties #517
Conversation
954f159
to
35af7d6
Compare
ba18b44
to
3bc1a45
Compare
c6a2db5
to
2e4c2af
Compare
693ccf4
to
9836d99
Compare
9836d99
to
9858fb0
Compare
62965ce
to
305e0e0
Compare
adc266a
to
3b73d23
Compare
3b73d23
to
e6d504b
Compare
if (isDecimal) { | ||
cond = Decimal128.fromString(cond); | ||
debug('buildWhere decimal value: %s, constructor name: %s', cond, cond.constructor.name); | ||
} | ||
} |
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.
I think you need to handle prop.mongodb.dataType.toLowerCase() === 'objectid'
too, so that string properties stored as ObjectIDs are handled in where
queries too. Please start with a unit test that fails now.
I am ok to leave this part out of scope of this pull request if you prefer, but I think it should be implemented before we can call the user story done.
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.
Given:
const ObjectIdTypeRegex = /objectid/i;
Shouldn't ObjectIdTypeRegex.test()
take care of things?
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.
That should do it. Can we add a test where we specify the type as dataType: 'objectid'
?
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
ObjectIdTypeRegex.test()
take care of things?
What will happen when the value is not an ObjectID string? IIUC, in your proposal the query will return no records, because the non-ObjectID string will not match any of the ObjectID values stored in the database.
Are we fine with that behavior?
I was thinking that we should reject such requests with 400 Bad Request
error instead.
Also, what happens when strictObjectIDCoercion
is enabled and the property is defined as {type: 'string', mongodb: {dataType: 'ObjectID'}}
. Will we correctly coerce the string value to ObjectID, so that it can match any existing values in the database?
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.
I got your point, I was thinking of something else.
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
ObjectIdTypeRegex.test()
take care of things?What will happen when the value is not an ObjectID string? IIUC, in your proposal the query will return no records, because the non-ObjectID string will not match any of the ObjectID values stored in the database.
Are we fine with that behavior?
I was thinking that we should reject such requests with
400 Bad Request
error instead.Also, what happens when
strictObjectIDCoercion
is enabled and the property is defined as{type: 'string', mongodb: {dataType: 'ObjectID'}}
. Will we correctly coerce the string value to ObjectID, so that it can match any existing values in the database?
I misunderstood this, sorry. Rejecting non-objectID string makes sense to me (I thought this was the behaviour). Also, for the case when strict coercion flag is enabled, we should coerce string values to ObjectID, and also reject/throw an error if we can't (invalid values).
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.
@bajtos @hacksparrow is this something we can create a follow-up story on?
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.
Let's create a follow up story.
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.
@b-admike @hacksparrow @bajtos
Created #545 as I believe it relates to this conversation. This commit and its related code appears to fix the issue related to string-properties-stored-as-ObjectId but does not account for a property that is an Array of ObjectID or Array of ObjectID-like-strings.
@bajtos Thank you for the detailed explanation 👍 I forgot the relation constraint. Fair enough. |
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.
Looking great. Thanks for adding some docs in the README. I've put my thoughts on the ongoing discussions.
if (isDecimal) { | ||
cond = Decimal128.fromString(cond); | ||
debug('buildWhere decimal value: %s, constructor name: %s', cond, cond.constructor.name); | ||
} | ||
} |
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.
That should do it. Can we add a test where we specify the type as dataType: 'objectid'
?
test/id.test.js
Outdated
|
||
it('should throw if id is not a ObjectID-like string', async function() { | ||
// Why is this not working? | ||
// await User.create({id: 'abc', name: 'John'}).should.be.rejectedWith(/not an ObjectID string/); |
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.
Here are two ways of doing it (one is for expect/chai, one for mocha):
expect:
https://github.com/strongloop/loopback-next/blob/75939a4a144b3068ff2890394c178faad58d7458/packages/cli/test/integration/generators/relation.integration.js#L39-L48
I suggest trying to have a promise based test:
it('should throw if id is not an ObjectID-like string', () => {
return user.create({id: 'abc', name: 'John'}).should.be.rejectedWith(/not an ObjectID string/);
});
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.
return user.create({id: 'abc', name: 'John'}).should.be.rejectedWith(/not an ObjectID string/);
Doesn't help.
Would it be ok to replace should
with expect
in this repo? Will do so in a separate PR after this one lands, if ok.
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.
Maybe my example is wrong. I didn't get to try it out. I'll try it out and let you know. In terms of replacing should
with expect
, it is ok, but not sure how much effort that is and how much beneficial it is.
6fb8e55
to
9114a18
Compare
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.
if (isDecimal) { | ||
cond = Decimal128.fromString(cond); | ||
debug('buildWhere decimal value: %s, constructor name: %s', cond, cond.constructor.name); | ||
} | ||
} |
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
ObjectIdTypeRegex.test()
take care of things?
What will happen when the value is not an ObjectID string? IIUC, in your proposal the query will return no records, because the non-ObjectID string will not match any of the ObjectID values stored in the database.
Are we fine with that behavior?
I was thinking that we should reject such requests with 400 Bad Request
error instead.
Also, what happens when strictObjectIDCoercion
is enabled and the property is defined as {type: 'string', mongodb: {dataType: 'ObjectID'}}
. Will we correctly coerce the string value to ObjectID, so that it can match any existing values in the database?
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.
Changes LGTM 👍. I think there are two discussions where we can create follow-up tasks/PRs on.
9114a18
to
ab4d3f7
Compare
@b-admike any idea why this is failing? https://travis-ci.org/strongloop/loopback-connector-mongodb/jobs/540672910 |
ab4d3f7
to
a909ff1
Compare
Ok, all green now. Let's land this today. |
a909ff1
to
3503be6
Compare
Adds mongodb.dataType to model property definition Feedback
3503be6
to
8d86bdc
Compare
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.
LGTM 🎉
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.
👏 LGTM great effort!
Adds
mongodb: {dataType: 'ObjectID'}
to model properties. EnforcesstrictObjectIDCoercion
settings on all model properties.Related issues
loopbackio/loopback-next#2085
Checklist
guide