func writeLinkBagCollectionPointer(buf *bytes.Buffer, linkBag *oschema.OLinkBag) error { // (treePointer:collectionPointer)(changes) // where collectionPtr = (fileId:long)(pageIndex:long)(pageOffset:int) err := rw.WriteLong(buf, linkBag.GetFileID()) if err != nil { return oerror.NewTrace(err) } err = rw.WriteLong(buf, linkBag.GetPageIndex()) if err != nil { return oerror.NewTrace(err) } return rw.WriteInt(buf, linkBag.GetPageOffset()) }
// // FetchEntriesOfRemoteLinkBag fills in the links of an OLinkBag that is remote // (tree-based) rather than embedded. This function will fill in the links // of the passed in OLinkBag, rather than returning the new links. The Links // will have RIDs only, not full Records (ODocuments). If you then want the // Records filled in, call the ResolveLinks function. // func FetchEntriesOfRemoteLinkBag(dbc *DBClient, linkBag *oschema.OLinkBag, inclusive bool) error { var ( firstLink *oschema.OLink linkSerde binserde.OBinaryTypeSerializer err error ) firstLink, err = FetchFirstKeyOfRemoteLinkBag(dbc, linkBag) if err != nil { return oerror.NewTrace(err) } dbc.buf.Reset() err = writeCommandAndSessionId(dbc, REQUEST_SBTREE_BONSAI_GET_ENTRIES_MAJOR) if err != nil { return oerror.NewTrace(err) } err = writeLinkBagCollectionPointer(dbc.buf, linkBag) if err != nil { return oerror.NewTrace(err) } typeByte := byte(9) linkSerde = binserde.TypeSerializers[typeByte] // the OLinkSerializer linkBytes, err := linkSerde.Serialize(firstLink) if err != nil { return oerror.NewTrace(err) } err = rw.WriteBytes(dbc.buf, linkBytes) if err != nil { return oerror.NewTrace(err) } err = rw.WriteBool(dbc.buf, inclusive) if err != nil { return oerror.NewTrace(err) } // copied from Java client OSBTreeBonsaiRemote#fetchEntriesMajor if dbc.binaryProtocolVersion >= 21 { err = rw.WriteInt(dbc.buf, 128) } // send to the OrientDB server _, err = dbc.conx.Write(dbc.buf.Bytes()) if err != nil { return oerror.NewTrace(err) } /* ---[ Read Response ]--- */ err = readStatusCodeAndSessionId(dbc) if err != nil { return oerror.NewTrace(err) } linkEntryBytes, err := rw.ReadBytes(dbc.conx) if err != nil { return oerror.NewTrace(err) } // all the rest of the response from the server in in this byte slice so // we can reset the dbc.buf and reuse it to deserialize the serialized links dbc.buf.Reset() // ignoring error since doc says this method panics rather than return // non-nil error n, _ := dbc.buf.Write(linkEntryBytes) if n != len(linkEntryBytes) { return fmt.Errorf("Unexpected error when writing bytes to bytes.Buffer") } nrecs, err := rw.ReadInt(dbc.buf) if err != nil { return oerror.NewTrace(err) } var result interface{} nr := int(nrecs) // loop over all the serialized links for i := 0; i < nr; i++ { result, err = linkSerde.Deserialize(dbc.buf) if err != nil { return oerror.NewTrace(err) } linkBag.AddLink(result.(*oschema.OLink)) // FIXME: for some reason the server returns a serialized link // followed by an integer (so far always a 1 in my expts). // Not sure what to do with this int, so ignore for now intval, err := rw.ReadInt(dbc.buf) if err != nil { return oerror.NewTrace(err) } if intval != int32(1) { ogl.Warnf("DEBUG: Found a use case where the val pair of a link was not 1: %d\n", intval) } } return nil }