neo4j-javascript-driver
neo4j-javascript-driver copied to clipboard
Expand Record Object Mapping to allow Parameter Mapping
closes DRIVERS-107
This PR provides support for typechecking and automatic conversion of parameters, as well 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.
class Obj {
constructor (obj) {
this.string = obj?.string ?? 'hi'
this.number = obj?.number ?? 1
this.bigint = obj?.bigint ?? BigInt(1)
this.date = obj?.date ?? "2024-01-01"
this.localDate = obj?.localDate ?? "2024-01-01"
this.dateTime = obj?.dateTime ?? new neo4j.DateTime(1, 1, 1, 1, 1, 1, 1, 0)._toUTC()
this.localDateTime = obj?.localDateTime ?? new neo4j.LocalDateTime(1, 1, 1, 1, 1, 1, 1).toString()
this.duration = obj?.duration ?? "P1DT5.00007S"
this.time = obj?.time ?? "10:11:12.13Z"
this.localTime = obj?.localTime ?? "10:11:12.0001"
this.list = obj?.list ?? ["hi"]
this.function = () => "function string" // bolt cannot send functions
this.node = new neo4j.Node("123", [], {}) // nor can it send nodes
}
}
const session = driver.session()
const rules = {
number: neo4j.rule.asNumber(),
string: neo4j.rule.asString(),
bigint: neo4j.rule.asBigInt({acceptNumber: true}),
date: neo4j.rule.asDate({stringify: true}), // this will ensure date is stored as a Date in the DB and retrieved as a string
localDate: neo4j.rule.asDate({stringify: true}),
dateTime: neo4j.rule.asDateTime({stringify: true}),
localDateTime: neo4j.rule.asLocalDateTime({stringify: true}),
duration: neo4j.rule.asDuration({stringify: true}),
time: neo4j.rule.asTime({from: "dob", stringify: true}),
localTime: neo4j.rule.asLocalTime({stringify: true}),
list: neo4j.rule.asList({ apply: neo4j.rule.asString() }),
} // not including function and node here will make the driver skip sending them. They could alternatively be converted to a bolt-compatible type.
neo4j.RecordObjectMapping.register(Obj, rules)
//This allows us to use camelCase for our object properties and snake_case for the properties on our node in the DB
neo4j.RecordObjectMapping.translateIdentifiers(neo4j.RecordObjectMapping.getCaseTranslator("snake_case", "camelCase"))
session.run(
'MERGE (n {string: $string, number: $number, bigint: $bigint, date: $date, local_date: $local_date, date_time: $date_time, local_date_time: $local_date_time, duration: $duration, dob: $dob, local_time: $local_time, list: $list}) RETURN n',
new Obj(),
{}
).as({n: {convert: (n) => new Obj(n.as(rules))}})
.then((res) => {
console.log(res.records[0])
session.close()
driver.close()
})