// // readLink reads a two int64's - the cluster and record. // We translate it here to a string RID (cluster:record) and return it. // func (serde ORecordSerializerV0) readLink(buf io.Reader) (*oschema.OLink, error) { clusterID, err := varint.ReadVarIntAndDecode64(buf) if err != nil { return nil, oerror.NewTrace(err) } clusterPos, err := varint.ReadVarIntAndDecode64(buf) if err != nil { return nil, oerror.NewTrace(err) } orid := oschema.ORID{ClusterID: int16(clusterID), ClusterPos: clusterPos} return &oschema.OLink{RID: orid}, nil }
// // readDateTime reads an OrientDB DATETIME from the stream and converts it to // a golang time.Time struct. DATETIME is precise to the second. // The time zone of the time.Time returned should be the Local timezone. // // OrientDB server converts a DATETIME type to millisecond unix epoch and // stores it as the type LONG. It is written as a varint long. // func (serde ORecordSerializerV0) readDateTime(r io.Reader) (time.Time, error) { dtAsLong, err := varint.ReadVarIntAndDecode64(r) if err != nil { return time.Unix(0, 0), oerror.NewTrace(err) } dtSecs := dtAsLong / 1000 dtNanos := (dtAsLong % 1000) * 1000000 return time.Unix(dtSecs, dtNanos), nil }
// // readDate reads an OrientDB DATE from the stream and converts it to // a golang time.Time struct. DATE is precise to the day - hour, minute // and second are zeroed out. The time zone of the time.Time returned // should be the Local timezone. // // OrientDB server returns DATEs as (varint) longs. // From the OrientDB schemaless serialization spec on DATE: // The date is converted to second unix epoch,moved at midnight UTC+0, // divided by 86400(seconds in a day) and stored as the type LONG // func (serde ORecordSerializerV0) readDate(r io.Reader) (time.Time, error) { seconds, err := varint.ReadVarIntAndDecode64(r) if err != nil { return time.Unix(0, 0), oerror.NewTrace(err) } dateAsLong := seconds * int64(86400) // multiply the 86,400 seconds back utctm := time.Unix(dateAsLong, 0).UTC() // OrientDB returns it as a UTC date, so start with that loctm := utctm.Local() // convert to local time _, offsetInSecs := loctm.Zone() // the compute the time zone difference offsetInNanos := offsetInSecs * 1000 * 1000 * 1000 durOffset := time.Duration(offsetInNanos) adjustedLocTm := loctm.Add(-durOffset) // and finally adjust the time back to local time return adjustedLocTm, nil }
// // readDataValue reads the next data section from `buf` according // to the type of the property (property.Typ) and updates the OField object // to have the value. // func (serde ORecordSerializerV0) readDataValue(buf *obuf.ReadBuf, datatype oschema.ODataType) (interface{}, error) { var ( val interface{} err error ) switch datatype { case oschema.BOOLEAN: val, err = rw.ReadBool(buf) ogl.Debugf("DEBUG BOOL: +readDataVal val: %v\n", val) // DEBUG case oschema.INTEGER: var i64 int64 i64, err = varint.ReadVarIntAndDecode64(buf) if err == nil { val = int32(i64) } ogl.Debugf("DEBUG INT: +readDataVal val: %v\n", val) // DEBUG case oschema.SHORT: var i32 int32 i32, err = varint.ReadVarIntAndDecode32(buf) if err == nil { val = int16(i32) } ogl.Debugf("DEBUG SHORT: +readDataVal val: %v\n", val) // DEBUG case oschema.LONG: val, err = varint.ReadVarIntAndDecode64(buf) ogl.Debugf("DEBUG LONG: +readDataVal val: %v\n", val) // DEBUG case oschema.FLOAT: val, err = rw.ReadFloat(buf) ogl.Debugf("DEBUG FLOAT: +readDataVal val: %v\n", val) // DEBUG case oschema.DOUBLE: val, err = rw.ReadDouble(buf) ogl.Debugf("DEBUG DOUBLE: +readDataVal val: %v\n", val) // DEBUG case oschema.DATETIME: // OrientDB DATETIME is precise to the second val, err = serde.readDateTime(buf) ogl.Debugf("DEBUG DATEIME: +readDataVal val: %v\n", val) // DEBUG case oschema.DATE: // OrientDB DATE is precise to the day val, err = serde.readDate(buf) ogl.Debugf("DEBUG DATE: +readDataVal val: %v\n", val) // DEBUG case oschema.STRING: val, err = varint.ReadString(buf) ogl.Debugf("DEBUG STR: +readDataVal val: %v\n", val) // DEBUG case oschema.BINARY: val, err = varint.ReadBytes(buf) ogl.Debugf("DEBUG BINARY: +readDataVal val: %v\n", val) // DEBUG case oschema.EMBEDDED: doc := oschema.NewDocument("") err = serde.Deserialize(nil, doc, buf) val = interface{}(doc) // ogl.Debugf("DEBUG EMBEDDEDREC: +readDataVal val: %v\n", val) // DEBUG case oschema.EMBEDDEDLIST: val, err = serde.readEmbeddedCollection(buf) // ogl.Debugf("DEBUG EMBD-LIST: +readDataVal val: %v\n", val) // DEBUG case oschema.EMBEDDEDSET: val, err = serde.readEmbeddedCollection(buf) // TODO: may need to create a set type as well // ogl.Debugf("DEBUG EMBD-SET: +readDataVal val: %v\n", val) // DEBUG case oschema.EMBEDDEDMAP: val, err = serde.readEmbeddedMap(buf) // ogl.Debugf("DEBUG EMBD-MAP: +readDataVal val: %v\n", val) // DEBUG case oschema.LINK: // a link is two int64's (cluster:record) - we translate it here to a string RID val, err = serde.readLink(buf) ogl.Debugf("DEBUG LINK: +readDataVal val: %v\n", val) // DEBUG case oschema.LINKLIST, oschema.LINKSET: val, err = serde.readLinkList(buf) ogl.Debugf("DEBUG LINK LIST/SET: +readDataVal val: %v\n", val) // DEBUG case oschema.LINKMAP: val, err = serde.readLinkMap(buf) ogl.Debugf("DEBUG LINKMap: +readDataVal val: %v\n", val) // DEBUG case oschema.BYTE: val, err = rw.ReadByte(buf) ogl.Debugf("DEBUG BYTE: +readDataVal val: %v\n", val) // DEBUG case oschema.LINKBAG: val, err = serde.readLinkBag(buf) ogl.Debugf("DEBUG LINKBAG: +readDataVal val: %v\n", val) // DEBUG case oschema.CUSTOM: // TODO: impl me -> how? when is this used? panic("ORecordSerializerV0#readDataValue CUSTOM NOT YET IMPLEMENTED") case oschema.DECIMAL: // TODO: impl me -> Java client uses BigDecimal for this panic("ORecordSerializerV0#readDataValue DECIMAL NOT YET IMPLEMENTED") default: // ANY and TRANSIENT are do nothing ops } return val, err }