Expand Record Object Mapping to allow Parameter Mapping#1362
Expand Record Object Mapping to allow Parameter Mapping#1362
Conversation
robsdedude
left a comment
There was a problem hiding this comment.
Review part 1. I'll continue next week with the review. I just want to submit my comments to make sure they don't get lost.
|
Consider making the |
robsdedude
left a comment
There was a problem hiding this comment.
Here goes a first round of comments. Submitting them now so they don't get lost until tomorrow when I shall continue.
| * @param {mixed} query - Cypher query to execute | ||
| * @param {Object} parameters - Map with parameters to use in query | ||
| * @param {TransactionConfig} [transactionConfig] - Configuration for the new auto-commit transaction. | ||
| * @param {Rules} parameterRules - Rules to typecheck and/or map the parameter object . | ||
| * @param {Rules} parameterRules - Rules to typecheck and/or map the parameter object. Must not be provided as a separate argument if an Object is passed as first argument |
There was a problem hiding this comment.
More of the same question as above. To | undefined or not to | undefined as JShakespeare wrote.
Transaction and managed transaction are other places like this that were touched by this PR. As written about, this is likely a separate piece of work. But at least the newly added parameters should probably
- follow which ever way is right if the whole function is newly added
- or follow whatever other parameters are doing if the function existed or other functions with optional parameters exist in the near vicinity.
There was a problem hiding this comment.
indeed. Aligning this with the transactionConfig parameter.
| * @param {string} str The string to convert | ||
| * @returns {DateTime} | ||
| */ | ||
| static fromString (str: string): DateTime { |
There was a problem hiding this comment.
Here are 2 tests for invalid input which don't get rejected
['2026-01-05T15:36:42+[America/Anchorage]', 'DateTime could not be parsed from string'],
['2026-01-05T15:36:42-[America/Anchorage]', 'DateTime could not be parsed from string'],Here are tests for valid input which doesn't pass:
['2026-01-05T15:36:42+0001[America/Anchorage]', new DateTime(int(2026), int(1), int(5), int(15), int(36), int(42), int(0), int(60), 'America/Anchorage')],
// I *think* these should work according to RFC 9557
['2026-01-05T15:36:42Z[America/Anchorage]', new DateTime(int(2026), int(1), int(5), int(15), int(36), int(42), int(0), int(0), 'America/Anchorage')],
['2026-01-05T15:36:42-00:00[America/Anchorage]', new DateTime(int(2026), int(1), int(5), int(15), int(36), int(42), int(0), int(0), 'America/Anchorage')],These issues exist before, but I didn't see them, sorry. For me it's always like that with temporal types: the longer I look, the more broken things become (including my mind).
| if (processedValue != null || rule?.optional === true) { | ||
| // @ts-expect-error | ||
| obj[key] = processedValue | ||
| } |
There was a problem hiding this comment.
There's a small corner case left where input and output are asymmetric:
- if
rule.convertreturnsnull/undefinedit depends onrule.optionalwhether that value is assigned or not. - if
rule.parameterConversionreturnsnull/undefineda null check happens.
If I interpret things correctly, if a user wants to roll a custom Rule that for example maps a custom JS type to NULL | INTEGER in the DBMS they have to set optional. Fair enough, I'd say. But if they don't what currently happens to a value mapped to NULL is:
- DBMS -> app: if value is
NULLin DBMS,validateandconvertare correctly called, but the app object's property will not be set (undefined) - app -> DBMS: if
parameterConversioncalled and returnsnull,validateAndCleanParametersrejects that.
I think the 2nd is fine as is. The former, I think is very surprising behavior. I'm not sure what the right behavior is. Maybe the driver should also throw if rule.convert returns a null-ish value but rule.optional === false. Or the driver should just always assign whatever rule.convert returns... Looking at asList, probably this.
There was a problem hiding this comment.
Agreed on changing to always assign what rule.convert returns, it's both simpler and better. Also aligns with the pattern of App <> Convert <> Validate <> DB
| new RegExp( | ||
| /^([+|-]\d{5,}|\d{4})-(\d{2})-(\d{2})[T|t](\d{2})(?::?(\d{2}))?(?::?(\d{2}))?(\.\d+)?/.source + // DateTime | ||
| /([Z|z]$|\+|-)?(?:(\d{2})?(?::?(\d{2}))?(?::?(\d{2}))?$)?(?:\[([^\]]*)\])?$/.source // Timezone | ||
| /([Z|z]|\+|-)?(?:(\d{2})?(?::?(\d{2}))?(?::?(\d{2}))?)?(?:\[([^\]]*)\])?$/.source // Timezone |
There was a problem hiding this comment.
👀
['2026-01-05T15:36:42Z00:00[America/Anchorage]', 'DateTime could not be parsed from string']There was a problem hiding this comment.
2026-01-05T15:36:42Z:01[America/Anchorage]
closes DRIVERS-107
This PR provides support for typechecking and automatic conversion of parameters, as well as using the object mapping registry to register mapping strategies for classes. This lets users directly pass objects even with problematic properties that can not be sent over bolt (like functions), by automatically converting them or by omitting them from the mapping strategy.
This is the 2nd half of the Record Object Mapping feature, which is also marked stabilized and taken out of preview in this PR.
Examples