Exemplo n.º 1
0
//
// writeEmbeddedMap serializes the EMBEDDEDMAP type. Currently, OrientDB only uses string
// types for the map keys, so that is an assumption of this method as well.
//
func (serde ORecordSerializerV0) writeEmbeddedMap(buf *obuf.WriteBuf, m oschema.OEmbeddedMap) error {
	// number of entries in the map
	err := varint.EncodeAndWriteVarInt32(buf, int32(m.Len()))
	if err != nil {
		return oerror.NewTrace(err)
	}

	ptrPos := make([]int, 0, m.Len()) // position in buf where data ptr int needs to be written

	// TODO: do the map entries have to be written in any particular order?  I will assume no for now
	keys, vals, types := m.All()

	/* ---[ write embedded map header ]--- */
	for i, k := range keys {
		// key type
		err = rw.WriteByte(buf, byte(oschema.STRING))
		if err != nil {
			return oerror.NewTrace(err)
		}

		// write the key value
		err = varint.WriteString(buf, k)
		if err != nil {
			return oerror.NewTrace(err)
		}

		ptrPos = append(ptrPos, buf.Len())
		buf.Skip(4) // placeholder integer for data ptr

		dataType := types[i]
		if dataType == oschema.UNKNOWN {
			dataType = getDataType(vals[i]) // TODO: not sure this is necessary
		}
		// write data type of the data
		err = rw.WriteByte(buf, byte(dataType))
		if err != nil {
			return oerror.NewTrace(err)
		}
	}

	/* ---[ write embedded map data values ]--- */
	for i := 0; i < len(vals); i++ {
		currPos := buf.Len()
		buf.Seek(uint(ptrPos[i]))
		err = rw.WriteInt(buf, int32(currPos))
		if err != nil {
			return oerror.NewTrace(err)
		}
		buf.Seek(uint(currPos))
		err = serde.writeDataValue(buf, vals[i], types[i])
		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
}