[ https://issues.apache.org/jira/browse/TINKERPOP-2802?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17748673#comment-17748673 ]
ASF GitHub Bot commented on TINKERPOP-2802: ------------------------------------------- j-white commented on code in PR #2174: URL: https://github.com/apache/tinkerpop/pull/2174#discussion_r1277736470 ########## gremlin-go/driver/graphBinary.go: ########## @@ -1282,6 +1284,78 @@ func metricsReader(data *[]byte, i *int) (interface{}, error) { return metrics, nil } +type JanusgraphRelationIdentifier struct { Review Comment: This will be moved outside of the driver, but including here for an example of what an implementation could look like. ########## gremlin-go/driver/graphBinary.go: ########## @@ -1282,6 +1284,78 @@ func metricsReader(data *[]byte, i *int) (interface{}, error) { return metrics, nil } +type JanusgraphRelationIdentifier struct { + OutVertexIdLong int64 + OutVertexIdString string + TypeId int64 + RelationId int64 + InVertexIdLong int64 + InVertexIdString string +} + +func janusgraphRelationIdentifierReader(data *[]byte, i *int) (interface{}, error) { + const ( + relationIdentifierType uint32 = 0x1001 + longMarker byte = 0 + stringMarker byte = 1 + ) + + r := new(JanusgraphRelationIdentifier) + + // expect type code + customDataTyp := readUint32Safe(data, i) + if customDataTyp != relationIdentifierType { + return nil, newError(err0408GetSerializerToReadUnknownTypeError, customDataTyp) + } + + // value flag, expect this to be non-nullable + if readByteSafe(data, i) != valueFlagNone { + return nil, newError(err0405ReadValueInvalidNullInputError) + } + + // outvertexid + if readByteSafe(data, i) == longMarker { + r.OutVertexIdLong = readLongSafe(data, i) + } else { + vertexId, err := readString(data, i) + if err != nil { + return nil, err + } + r.OutVertexIdString = vertexId.(string) + } + + r.TypeId = readLongSafe(data, i) + r.RelationId = readLongSafe(data, i) + + // invertexid + if readByteSafe(data, i) == longMarker { + r.InVertexIdLong = readLongSafe(data, i) + } else { + vertexId, err := readString(data, i) + if err != nil { + return nil, err + } + r.InVertexIdString = vertexId.(string) + } + + return r, nil +} + +// {name}{type specific payload} +func customTypeReader(data *[]byte, i *int) (interface{}, error) { + // type name + *i = *i - 1 + customTypeName, err := readString(data, i) + if err != nil { + return nil, err + } + deserializer, ok := customDeserializers[customTypeName.(string)] Review Comment: For custom types, it looks like we write the name of the type, and then the remaining bytes are specific to the implementation. So it could make sense to key off the name, and let the custom reader handle the rest. Does this make sense? ########## gremlin-go/driver/graphBinary.go: ########## @@ -1282,6 +1284,78 @@ func metricsReader(data *[]byte, i *int) (interface{}, error) { return metrics, nil } +type JanusgraphRelationIdentifier struct { + OutVertexIdLong int64 + OutVertexIdString string + TypeId int64 + RelationId int64 + InVertexIdLong int64 + InVertexIdString string +} + +func janusgraphRelationIdentifierReader(data *[]byte, i *int) (interface{}, error) { + const ( + relationIdentifierType uint32 = 0x1001 + longMarker byte = 0 + stringMarker byte = 1 + ) + + r := new(JanusgraphRelationIdentifier) + + // expect type code + customDataTyp := readUint32Safe(data, i) + if customDataTyp != relationIdentifierType { + return nil, newError(err0408GetSerializerToReadUnknownTypeError, customDataTyp) + } + + // value flag, expect this to be non-nullable + if readByteSafe(data, i) != valueFlagNone { + return nil, newError(err0405ReadValueInvalidNullInputError) + } + + // outvertexid + if readByteSafe(data, i) == longMarker { + r.OutVertexIdLong = readLongSafe(data, i) + } else { + vertexId, err := readString(data, i) + if err != nil { + return nil, err + } + r.OutVertexIdString = vertexId.(string) + } + + r.TypeId = readLongSafe(data, i) + r.RelationId = readLongSafe(data, i) + + // invertexid + if readByteSafe(data, i) == longMarker { + r.InVertexIdLong = readLongSafe(data, i) + } else { + vertexId, err := readString(data, i) + if err != nil { + return nil, err + } + r.InVertexIdString = vertexId.(string) + } + + return r, nil +} + +// {name}{type specific payload} +func customTypeReader(data *[]byte, i *int) (interface{}, error) { + // type name + *i = *i - 1 Review Comment: Need to backup the index by 1 to be read the 32-bit int with the size of the string ########## gremlin-go/driver/graphBinary.go: ########## @@ -224,11 +225,12 @@ func instructionWriter(instructions []instruction, buffer *bytes.Buffer, typeSer // Format: {steps_length}{step_0}…{step_n}{sources_length}{source_0}…{source_n} // Where: -// {steps_length} is an Int value describing the amount of steps. -// {step_i} is composed of {name}{values_length}{value_0}…{value_n}, where: -// {name} is a String. This is also known as the operator. -// {values_length} is an Int describing the amount values. -// {value_i} is a fully qualified typed value composed of {type_code}{type_info}{value_flag}{value} describing the step argument. +// Review Comment: unchanged, just go fmt ########## gremlin-go/driver/graphBinary.go: ########## @@ -1282,6 +1284,78 @@ func metricsReader(data *[]byte, i *int) (interface{}, error) { return metrics, nil } +type JanusgraphRelationIdentifier struct { + OutVertexIdLong int64 + OutVertexIdString string + TypeId int64 + RelationId int64 + InVertexIdLong int64 + InVertexIdString string +} + +func janusgraphRelationIdentifierReader(data *[]byte, i *int) (interface{}, error) { + const ( + relationIdentifierType uint32 = 0x1001 + longMarker byte = 0 + stringMarker byte = 1 + ) + + r := new(JanusgraphRelationIdentifier) + + // expect type code + customDataTyp := readUint32Safe(data, i) + if customDataTyp != relationIdentifierType { + return nil, newError(err0408GetSerializerToReadUnknownTypeError, customDataTyp) + } + + // value flag, expect this to be non-nullable + if readByteSafe(data, i) != valueFlagNone { + return nil, newError(err0405ReadValueInvalidNullInputError) + } + + // outvertexid + if readByteSafe(data, i) == longMarker { + r.OutVertexIdLong = readLongSafe(data, i) + } else { + vertexId, err := readString(data, i) + if err != nil { + return nil, err + } + r.OutVertexIdString = vertexId.(string) + } + + r.TypeId = readLongSafe(data, i) + r.RelationId = readLongSafe(data, i) + + // invertexid + if readByteSafe(data, i) == longMarker { + r.InVertexIdLong = readLongSafe(data, i) + } else { + vertexId, err := readString(data, i) + if err != nil { + return nil, err + } + r.InVertexIdString = vertexId.(string) + } + + return r, nil +} + +// {name}{type specific payload} +func customTypeReader(data *[]byte, i *int) (interface{}, error) { + // type name + *i = *i - 1 + customTypeName, err := readString(data, i) + if err != nil { + return nil, err + } + deserializer, ok := customDeserializers[customTypeName.(string)] + if !ok { + return nil, newError(err0408GetSerializerToReadUnknownTypeError, 0x00) Review Comment: Introduce a new error code so we can pass the type name as a string? (this error code expects a number) ########## gremlin-go/driver/serializer.go: ########## @@ -320,5 +321,12 @@ func initDeserializers() { // Metrics metricsType: metricsReader, traversalMetricsType: traversalMetricsReader, + + // Customer + customType: customTypeReader, + } + + customDeserializers = map[string]reader{ Review Comment: We could an option to provide this map during initialization. Would it make sense to add a property to the `DriverRemoteConnectionSettings` struct? > Support Adding Custom Serializer for Gremlin Go > ----------------------------------------------- > > Key: TINKERPOP-2802 > URL: https://issues.apache.org/jira/browse/TINKERPOP-2802 > Project: TinkerPop > Issue Type: Improvement > Components: go > Affects Versions: 3.6.2 > Reporter: Yang Xia > Priority: Major > > To enable mechanisms to add custom serializers in the Go driver, for > compatibility with database specific types outside of TinkerPop, such as the > JanusGraph RelationIdentifier. -- This message was sent by Atlassian Jira (v8.20.10#820010)