// 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} }
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() }