Exemplo n.º 1
0
//
// Serialization format for EMBEDDEDLIST and EMBEDDEDSET
// +-------------+------------+-------------------+
// |size:varInt  | type:Otype | items:item_data[] |
// +-------------+------------+-------------------+
//
// The item_data data structure is:
// +------------------+--------------+
// | data_type:OType  | data:byte[]  |
// +------------------+--------------+
//
func (serde ORecordSerializerV0) serializeEmbeddedCollection(buf *obuf.WriteBuf, ls oschema.OEmbeddedList) error {
	err := varint.EncodeAndWriteVarInt32(buf, int32(ls.Len()))
	if err != nil {
		return oerror.NewTrace(err)
	}

	// following the lead of the Java driver, you don't specify the type of the list overall
	// (I tried to and it doesn't work, at least with OrientDB-2.0.1)
	err = rw.WriteByte(buf, byte(oschema.ANY))
	if err != nil {
		return oerror.NewTrace(err)
	}

	for _, val := range ls.Values() {
		buf.WriteByte(byte(ls.Type()))
		err = serde.writeDataValue(buf, val, ls.Type())
		if err != nil {
			return oerror.NewTrace(err)
		}
	}

	return nil
}
Exemplo n.º 2
0
//
// In Progress attempt to rewrite writeSerializedRecord and related fns
// using a seekable/skipping WriteBuf
//
func (serde ORecordSerializerV0) writeSerializedRecord(wbuf *obuf.WriteBuf, doc *oschema.ODocument) (err error) {
	nfields := len(doc.FieldNames())
	ptrPos := make([]int, 0, nfields) // position in buf where data ptr int needs to be written

	currDB := serde.dbc.GetCurrDB()
	oclass, ok := currDB.Classes[doc.Classname]

	docFields := doc.GetFields()
	for _, fld := range docFields {
		var oprop *oschema.OProperty
		if ok {
			oprop = oclass.Properties[fld.Name]
		}

		// FROM THE JAVA CLIENT:
		// if (properties[i] != null) {
		//   OVarIntSerializer.write(bytes, (properties[i].getId() + 1) * -1);
		//   if (properties[i].getType() != OType.ANY)
		//     pos[i] = bytes.alloc(OIntegerSerializer.INT_SIZE);
		//   else
		//     pos[i] = bytes.alloc(OIntegerSerializer.INT_SIZE + 1);   // TODO: why does ANY required an additional byte?
		// } else {
		//   writeString(bytes, entry.getKey());
		//   pos[i] = bytes.alloc(OIntegerSerializer.INT_SIZE + 1);

		if oprop != nil {
			// if property is known in the global properties, then
			// just write its encoded id
			varint.EncodeAndWriteVarInt32(wbuf, encodeFieldIDForHeader(oprop.ID))
			ptrPos = append(ptrPos, wbuf.Len())
			wbuf.Skip(4)
			// Note: no need to write property type when writing property ID

		} else {
			// property Name
			err = varint.WriteString(wbuf, fld.Name)
			if err != nil {
				return oerror.NewTrace(err)
			}
			ptrPos = append(ptrPos, wbuf.Len())
			wbuf.Skip(4)

			// property Type
			err = rw.WriteByte(wbuf, byte(fld.Type))
			if err != nil {
				return oerror.NewTrace(err)
			}
		}
	}
	wbuf.WriteByte(0) // End of Header sentinel

	// now write out the data values
	for i, fld := range docFields {
		currPos := wbuf.Len()
		wbuf.Seek(uint(ptrPos[i]))
		err = rw.WriteInt(wbuf, int32(currPos))
		if err != nil {
			return oerror.NewTrace(err)
		}
		wbuf.Seek(uint(currPos))
		err = serde.writeDataValue(wbuf, fld.Value, fld.Type)
		if err != nil {
			return oerror.NewTrace(err)
		}
	}

	return nil
}