-
Notifications
You must be signed in to change notification settings - Fork 0
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(NODE-6503): Add Int32 as a SchemaType #1
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.
besides removing the code from lib/types
, only minor comments. Lint is failing too, btw
(also can't request changes)
lib/schema/int32.js
Outdated
const INT32_MIN = -0x80000000; | ||
|
||
if (v != null) { | ||
if (typeof v !== 'number') { |
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.
do you think we should also confirm that it is an integer 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.
I'm not sure - I wonder if that would make it too similar to the other cast function
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.
We can leave a comment open for when we open this for Val
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.
Yes, this function should check for integer.
The idea behind _defaultCaster()
is that _defaultCaster()
is the function Mongoose will use if casting is disabled using cast: false
, so it should skip any type coercions (like converting strings or objects to int32).
lib/types/index.js
Outdated
@@ -14,6 +14,7 @@ exports.Embedded = require('./arraySubdocument'); | |||
exports.DocumentArray = require('./documentArray'); | |||
exports.Decimal128 = require('./decimal128'); | |||
exports.ObjectId = require('./objectid'); | |||
exports.Int32 = require('./int32'); |
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.
No - but mongoose has specific wrappers for them in lib/types. see Automattic#1671
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.
just one minor comment
lib/mongoose.js
Outdated
* | ||
* @property Int32 | ||
* @api public | ||
*/ |
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.
Do we need to store a reference to our schema on the Mongoose object? My thought is no becase the majority of schema types do not. Can we remove this? (and the TS changes you made as well)?
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.
Removed them - will add back in depending on discussion with Val
index.js
Outdated
@@ -46,6 +46,7 @@ module.exports.Decimal128 = mongoose.Decimal128; | |||
module.exports.Mixed = mongoose.Mixed; | |||
module.exports.Date = mongoose.Date; | |||
module.exports.Number = mongoose.Number; | |||
module.exports.Int32 = mongoose.Int32; |
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.
Along with my comment in mongoose.js, i think this should be removed
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.
Why do you think this should be removed?
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.
Not all schema types are exported as top-level exports, so I assumed that the exported schema types are exported for a reason. Is that incorrect?
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've removed the schema type top level export for Int32
but i can add it back in case this is incorrect behavior
lib/cast/int32.js
Outdated
} | ||
|
||
let coercedVal; | ||
if (val instanceof BSON.Int32 || val instanceof BSON.Double) { |
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.
we check for _bsontype
because that lines up with how the serializer interprets our BSON types. instanceof
is a different contract than our code expects so I think it shouldn't be introduced here so we don't create two versions of what is a true "type check"
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 agree with using _bsontype
rather than instanceof
. Mongoose has an isBsonType()
helper for this purpose.
The reason why we use _bsontype
over instanceof
is that it is common for Node.js apps to have multiple versions of bson floating around, and relying on instanceof
can lead to hard-to-debug behavior when we get an Int32 instance from a different version of bson module
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.
made the change!
test/int32.test.js
Outdated
}); | ||
|
||
describe('supports the required property', function() { | ||
it('when vaglue is null', async function() { |
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.
Minor typo value -> vaglue
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.
Made the change, another good catch!
test/int32.test.js
Outdated
const Test = mongoose.model('Test', schema); | ||
|
||
const doc = new Test({ | ||
myInt: -42 |
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 I'm reading this test correctly, myInt should be a string 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.
Good catch!
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 had a couple of minor comments, but overall this looks good, no major issues
885d0ee
to
18d18a7
Compare
lib/cast/int32.js
Outdated
return null; | ||
} | ||
|
||
const coercedVal = val instanceof BSON.Long ? val.toNumber() : Number(val); |
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 be using instanceof here per convo ^
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.
My bad! Fixed now!
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.
Per Val's comment, I think it is recommended to use the isBsonType()
helper in mongoose
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.
Oh I see! I'll change it again.
lib/cast/int32.js
Outdated
return null; | ||
} | ||
|
||
const coercedVal = val instanceof BSON.Long ? val.toNumber() : Number(val); |
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.
Per Val's comment, I think it is recommended to use the isBsonType()
helper in mongoose
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 can't approve because I opened the PR but LGTM
Note: @aditi-khare-mongoDB is the implementer, just a clarification in case it seems confusing why @baileympearson is leaving review comments.
Summary
Motivation
Support a 32-bit integer type in mongoose for compatibility with CSFLE/QE. The current
Number
schema type can result in either Int32, Int64, or Doubles that are inserted into the database using type inference but CSFLE and QE require exact BSON types in schemas.Summary of Changes
SchemaType
Int32
, which has the following behavior:cast
method throws when provided aNaN
$type: int
or$type: number
, but NOT$type: double
Example