func testSerializeEmbCol(t *testing.T, off int, col interface{}, origBase64 string) {
	buf := bytes.NewBuffer(nil)
	for i := 0; i < off; i++ {
		buf.WriteByte(0)
	}
	if err := (binaryRecordFormatV0{}).writeEmbeddedCollection(rw.NewWriter(buf), off, col, orient.UNKNOWN); err != nil {
		t.Fatal(err)
	}
	testBase64Compare(t, buf.Bytes(), origBase64)
}
Exemple #2
0
// SerializeAnyStreamable serializes a given object
func SerializeAnyStreamable(o CustomSerializable) ([]byte, error) {
	buf := bytes.NewBuffer(nil)
	bw := rw.NewWriter(buf)
	bw.WriteString(o.GetClassName())
	if err := o.ToStream(bw); err != nil {
		return nil, err
	}
	if err := bw.Err(); err != nil {
		return nil, err
	}
	return buf.Bytes(), nil
}
Exemple #3
0
func (bag *RidBag) ToStream(w io.Writer) error {
	var first byte
	hasUUID := false // TODO: do we need to send it?
	if !bag.IsRemote() {
		first |= 0x1
	}
	if hasUUID {
		first |= 0x2
	}
	bw := rw.NewWriter(w)
	bw.WriteByte(first)
	if hasUUID {
		bw.WriteRawBytes(bag.id[:])
	}
	return bag.delegate.serializeDelegate(bw)
}
func testSerializeEmbMap(t *testing.T, off int, mp interface{}, origBase64 string) {
	buf := bytes.NewBuffer(nil)
	for i := 0; i < off; i++ {
		buf.WriteByte(0)
	}
	if err := (binaryRecordFormatV0{}).writeEmbeddedMap(rw.NewWriter(buf), off, mp); err != nil {
		t.Fatal(err)
	}
	testBase64Compare(t, buf.Bytes(), origBase64)
	r := rw.NewReadSeeker(bytes.NewReader(buf.Bytes()))
	out, err := (binaryRecordFormatV0{}).readEmbeddedMap(r, nil)
	if err != nil {
		t.Fatal(err)
	}
	if reflect.TypeOf(out) != reflect.TypeOf(mp) {
		t.Logf("types are not the same: %T -> %T", mp, out)
	}
}
func TestSerializeDatetimeV0(t *testing.T) {
	buf := bytes.NewBuffer(nil)
	val := time.Now()
	val = time.Unix(val.Unix(), int64(val.Nanosecond()/1e6)*1e6) // precise to milliseconds
	if err := (binaryRecordFormatV0{}).writeSingleValue(rw.NewWriter(buf), 0, val, orient.DATETIME, orient.UNKNOWN); err != nil {
		t.Fatal(err)
	}

	r := rw.NewReadSeeker(bytes.NewReader(buf.Bytes()))
	out, err := (binaryRecordFormatV0{}).readSingleValue(r, orient.DATETIME, nil)
	if err != nil {
		t.Fatal(err)
	}
	if val2, ok := out.(time.Time); !ok {
		t.Fatalf("expected Time, got: %T", out)
	} else if !val.Equal(val2) {
		t.Fatalf("values differs: %v != %v", val, val2)
	}
}
func TestSerializeDecimalV0(t *testing.T) {
	buf := bytes.NewBuffer(nil)
	val := big.NewInt(123456789)
	if err := (binaryRecordFormatV0{}).writeSingleValue(rw.NewWriter(buf), 0, val, orient.DECIMAL, orient.UNKNOWN); err != nil {
		t.Fatal(err)
	}
	testBase64Compare(t, buf.Bytes(), "AAAAAAAAAAQHW80V")

	r := rw.NewReadSeeker(bytes.NewReader(buf.Bytes()))
	out, err := (binaryRecordFormatV0{}).readSingleValue(r, orient.DECIMAL, nil)
	if err != nil {
		t.Fatal(err)
	}
	if val2, ok := out.(orient.Decimal); !ok {
		t.Fatalf("expected Decimal, got: %T", out)
	} else if val.Cmp(val2.Value) != 0 {
		t.Fatalf("values differs: %v != %v", val, val2)
	}
}
Exemple #7
0
func TestReadErrorResponseWithSingleException(t *testing.T) {
	buf := new(bytes.Buffer)
	bw := rw.NewWriter(buf)
	bw.WriteByte(byte(1)) // indicates continue of exception class/msg array
	bw.WriteStrings("org.foo.BlargException", "wibble wibble!!")
	bw.WriteByte(byte(0)) // indicates end of exception class/msg array
	bw.WriteBytes([]byte("this is a stacktrace simulator\nEOL"))

	var serverExc error
	serverExc = obinary.ReadErrorResponse(rw.NewReader(buf))

	e, ok := serverExc.(orient.OServerException)
	if !ok {
		t.Fatal("wrong exception type")
	}
	equals(t, 1, len(e.Exceptions))

	equals(t, "org.foo.BlargException", e.Exceptions[0].ExcClass())
	equals(t, "wibble wibble!!", e.Exceptions[0].ExcMessage())
}
func (f BinaryRecordFormat) ToStream(w io.Writer, rec orient.ORecord) error {
	doc, ok := rec.(*orient.Document)
	if !ok {
		return orient.ErrTypeSerialization{Val: rec, Serializer: f}
	}
	// TODO: can send empty document to stream if serialization fails?
	bw := rw.NewWriter(w)
	bw.WriteByte(byte(binaryFormatCurrentVersion))
	off := rw.SizeByte
	// TODO: apply partial serialization to prevent infinite recursion of records
	ser := binaryFormatVerions[binaryFormatCurrentVersion]()
	ser.SetGlobalPropertyFunc(f.fnc)
	if err := bw.Err(); err != nil {
		return err
	}
	if err := ser.Serialize(doc, w, off, false); err != nil {
		return err
	}
	return bw.Err()
}
func (f binaryRecordFormatV0) writeEmbeddedCollection(w *rw.Writer, off int, o interface{}, linkedType orient.OType) error {
	mv := reflect.ValueOf(o)
	// TODO: handle OEmbeddedList
	if mv.Kind() != reflect.Slice && mv.Kind() != reflect.Array {
		panic(fmt.Sprintf("only maps are supported as %v, got %T", orient.EMBEDDEDMAP, o))
	}

	buf := bytes.NewBuffer(nil)
	bw := rw.NewWriter(buf)
	bw.WriteVarint(int64(mv.Len()))
	// TODO @orient: manage embedded type from schema and auto-determined.
	f.writeOType(bw, orient.ANY)
	for i := 0; i < mv.Len(); i++ {
		item := mv.Index(i).Interface()
		// TODO @orient: manage in a better way null entry
		if item == nil {
			f.writeOType(bw, orient.ANY)
			continue
		}
		var tp orient.OType = linkedType
		if tp == orient.UNKNOWN {
			tp = f.getTypeFromValueEmbedded(item)
		}
		if tp != orient.UNKNOWN {
			f.writeOType(bw, tp)
			ptr := buf.Len()
			if err := f.writeSingleValue(bw, off+ptr, item, tp, orient.UNKNOWN); err != nil {
				return err
			}
		} else {
			panic(orient.ErrTypeSerialization{Val: item, Serializer: f})
		}
	}
	if err := bw.Err(); err != nil {
		return err
	}
	return w.WriteRawBytes(buf.Bytes())
}
Exemple #10
0
func TestReadErrorResponseWithMultipleExceptions(t *testing.T) {
	buf := new(bytes.Buffer)
	bw := rw.NewWriter(buf)
	bw.WriteByte(byte(1)) // indicates more exceptions to come
	bw.WriteStrings("org.foo.BlargException", "Too many blorgles!!")
	bw.WriteByte(byte(1)) // indicates more exceptions to come
	bw.WriteStrings("org.foo.FeebleException", "Not enough juice")
	bw.WriteByte(byte(1)) // indicates more exceptions to come
	bw.WriteStrings("org.foo.WobbleException", "Orbital decay")
	bw.WriteByte(byte(0)) // indicates end of exceptions
	bw.WriteBytes([]byte("this is a stacktrace simulator\nEOL"))

	serverExc := obinary.ReadErrorResponse(rw.NewReader(buf))

	e, ok := serverExc.(orient.OServerException)
	if !ok {
		t.Fatal("wrong exception type")
	}

	equals(t, "org.foo.BlargException", e.Exceptions[0].ExcClass())
	equals(t, "Not enough juice", e.Exceptions[1].ExcMessage())
	equals(t, "org.foo.WobbleException", e.Exceptions[2].ExcClass())
	equals(t, "Orbital decay", e.Exceptions[2].ExcMessage())
}
Exemple #11
0
// Dial creates a new binary connection to OrientDB server.
// The Client returned is ready to make calls to the OrientDB but has not
// yet established a database session or a session with the OrientDB server.
// After this, the user needs to call either OpenDatabase or CreateServerSession.
func Dial(addr string) (*Client, error) {
	addr, err := validateAddr(addr)
	if err != nil {
		return nil, err
	}
	conn, err := net.DialTimeout("tcp", addr, time.Minute)
	if err != nil {
		return nil, err
	}
	c := &Client{
		addr: addr, conn: conn, done: make(chan struct{}),
		br: bufio.NewReader(conn), bw: bufio.NewWriter(conn),
	}
	c.pr = rw.NewReader(c.br)
	c.pw = rw.NewWriter(c.bw)
	if err := c.handshakeVersion(); err != nil {
		conn.Close()
		return nil, err
	}
	c.sess = make(map[int32]*session)
	c.root = c.newSess(noSessionId)
	go c.run()
	return c, nil
}
Exemple #12
0
func (rid RID) ToStream(w io.Writer) error {
	bw := rw.NewWriter(w)
	bw.WriteShort(rid.ClusterID)
	bw.WriteLong(rid.ClusterPos)
	return bw.Err()
}
func (f binaryRecordFormatV0) writeEmbeddedMap(w *rw.Writer, off int, o interface{}) error {
	mv := reflect.ValueOf(o)
	if mv.Kind() != reflect.Map {
		panic(fmt.Sprintf("only maps are supported as %v, got %T", orient.EMBEDDEDMAP, o))
	}

	buf := bytes.NewBuffer(nil)
	bw := rw.NewWriter(buf)

	type item struct {
		Pos  int
		Val  interface{}
		Type orient.OType
		Ptr  int
	}

	items := make([]item, 0, mv.Len())

	bw.WriteVarint(int64(mv.Len()))

	keys := mv.MapKeys()

	for _, kv := range keys {
		k := kv.Interface()
		v := mv.MapIndex(kv).Interface()
		// TODO @orient: check skip of complex types
		// FIXME @orient: changed to support only string key on map
		f.writeOType(bw, orient.STRING)
		f.writeString(bw, fmt.Sprint(k)) // convert key to string
		it := item{Pos: buf.Len(), Val: v}
		bw.WriteInt(0) // ptr placeholder
		tp := f.getTypeFromValueEmbedded(v)
		if tp == orient.UNKNOWN {
			panic(orient.ErrTypeSerialization{Val: v, Serializer: f})
		}
		it.Type = tp
		f.writeOType(bw, tp)
		items = append(items, it)
	}

	for i := range items {
		ptr := buf.Len()
		if err := f.writeSingleValue(bw, off+ptr, items[i].Val, items[i].Type, orient.UNKNOWN); err != nil {
			return err
		}
		if ptr != buf.Len() {
			items[i].Ptr = ptr
		} else {
			items[i].Ptr = 0
		}
	}
	if err := bw.Err(); err != nil {
		return err
	}
	data := buf.Bytes()
	for i := range items {
		if items[i].Ptr > 0 {
			rw.Order.PutUint32(data[items[i].Pos:], uint32(int32(items[i].Ptr+off)))
		}
	}
	return w.WriteRawBytes(data)
}
func (f binaryRecordFormatV0) Serialize(doc *orient.Document, w io.Writer, off int, classOnly bool) error {
	buf := bytes.NewBuffer(nil)
	bw := rw.NewWriter(buf)

	if _, err := f.serializeClass(bw, doc); err != nil {
		return err
	}
	if classOnly {
		f.writeEmptyString(bw)
		if err := bw.Err(); err != nil {
			return err
		}
		return rw.NewWriter(w).WriteRawBytes(buf.Bytes())
	}
	fields := doc.FieldsArray()

	type item struct {
		Pos   int
		Ptr   int
		Field *orient.DocEntry
		Type  orient.OType
	}

	var (
		items = make([]item, 0, len(fields))
	)
	for _, entry := range fields {
		it := item{Field: entry}
		// TODO: use global properties for serialization, if class is known
		f.writeString(bw, entry.Name)
		it.Pos = buf.Len() // save buffer offset of pointer
		bw.WriteInt(0)     // placeholder for data pointer
		tp := f.getFieldType(entry)
		if tp == orient.UNKNOWN {
			return fmt.Errorf("Can't serialize type %T with Document binary serializer", entry.Type)
		}
		bw.WriteByte(byte(tp))
		it.Type = tp
		items = append(items, it)
	}
	f.writeEmptyString(bw)
	for i, it := range items {
		if it.Field.Value == nil {
			continue
		}
		ptr := buf.Len()
		if err := f.writeSingleValue(bw, off+ptr, it.Field.Value, it.Type, f.getLinkedType(doc, it.Type, it.Field.Name)); err != nil {
			return err
		}
		if buf.Len() != ptr {
			items[i].Ptr = ptr
		} else {
			items[i].Ptr = 0
		}
	}
	if err := bw.Err(); err != nil {
		return err
	}
	data := buf.Bytes()
	for _, it := range items {
		if it.Ptr != 0 {
			rw.Order.PutUint32(data[it.Pos:], uint32(int32(it.Ptr+off)))
		}
	}
	return rw.NewWriter(w).WriteRawBytes(data)
}