Esempio n. 1
0
// ReadErrorResponse reads an "Exception" message from the OrientDB server.
// The OrientDB server can return multiple exceptions, all of which are
// incorporated into a single OServerException Error struct.
// If error (the second return arg) is not nil, then there was a
// problem reading the server exception on the wire.
func readErrorResponse(r *rw.Reader) (serverException error) {
	var (
		exClass, exMsg string
	)
	exc := make([]orient.Exception, 0, 1) // usually only one ?
	for {
		// before class/message combo there is a 1 (continue) or 0 (no more)
		marker := r.ReadByte()
		if marker == byte(0) {
			break
		}
		exClass = r.ReadString()
		exMsg = r.ReadString()
		exc = append(exc, orient.UnknownException{Class: exClass, Message: exMsg})
	}

	// Next there *may* a serialized exception of bytes, but it is only
	// useful to Java clients, so read and ignore if present.
	// If there is no serialized exception, EOF will be returned
	_ = r.ReadBytes()

	for _, e := range exc {
		switch e.ExcClass() {
		case "com.orientechnologies.orient.core.storage.ORecordDuplicatedException":
			return ODuplicatedRecordException{OServerException: orient.OServerException{Exceptions: exc}}
		}
	}
	return orient.OServerException{Exceptions: exc}
}
Esempio n. 2
0
func (db *Database) readSynchResult(r *rw.Reader) (result interface{}, err error) {
	resType := rune(r.ReadByte())
	if err = r.Err(); err != nil {
		return nil, err
	}
	switch resType {
	case 'n': // null result
		result = nil
	case 'r': // single record
		rec, err := db.readIdentifiable(r)
		if err != nil {
			return nil, err
		}
		if rec, ok := rec.(orient.ORecord); ok {
			db.updateCachedRecord(rec)
		}
		result = rec
	case 'l', 's': // collection of records
		n := int(r.ReadInt())
		recs := make([]orient.OIdentifiable, n) // TODO: do something special for Set type?
		for i := range recs {
			rec, err := db.readIdentifiable(r)
			if err != nil {
				return nil, err
			}
			if rec, ok := rec.(orient.ORecord); ok {
				db.updateCachedRecord(rec)
			}
			recs[i] = rec
		}
		result = recs
	case 'i':
		var recs []orient.OIdentifiable
		for {
			status := r.ReadByte()
			if status <= 0 {
				break
			}
			if rec, err := db.readIdentifiable(r); err != nil {
				return nil, err
			} else if rec == nil {
				continue
			} else if status == 1 {
				if rec, ok := rec.(orient.ORecord); ok {
					db.updateCachedRecord(rec)
				}
				recs = append(recs, rec)
			}
		}
		result = recs
	case 'a': // serialized type
		s := r.ReadString()
		if err = r.Err(); err != nil {
			return nil, err
		}
		result = stringRecordFormatAbs{}.FieldTypeFromStream(stringRecordFormatAbs{}.GetType(s), s)
	default:
		panic(fmt.Errorf("readSynchResult: not supported result type %v", resType))
	}
	if db.sess.cli.curProtoVers >= ProtoVersion17 {
		for {
			status := r.ReadByte()
			if status <= 0 {
				break
			}
			rec, err := db.readIdentifiable(r)
			if err != nil {
				return result, err
			}
			if rec != nil && status == 2 {
				if rec, ok := rec.(orient.ORecord); ok {
					db.updateCachedRecord(rec)
				}
			}
		}
	}
	return result, r.Err()
}