예제 #1
0
파일: link.go 프로젝트: josebalius/orientgo
func (bag *embeddedRidBag) deserializeDelegate(br *rw.Reader) error {
	n := int(br.ReadInt())
	bag.links = make([]OIdentifiable, n)
	for i := range bag.links {
		var rid RID
		if err := rid.FromStream(br); err != nil {
			return err
		}
		bag.links[i] = rid
	}
	return br.Err()
}
예제 #2
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}
}
예제 #3
0
파일: link.go 프로젝트: josebalius/orientgo
func (bag *sbTreeRidBag) deserializeChanges(r *rw.Reader) (err error) {
	n := int(r.ReadInt())
	changes := make(map[RID][]interface{})

	type change struct {
		diff bool
		val  int
	}

	for i := 0; i < n; i++ {
		var rid RID
		if err = rid.FromStream(r); err != nil {
			return err
		}
		chval := int(r.ReadInt())
		chtp := int(r.ReadByte())
		arr := changes[rid]
		switch chtp {
		case 1: // abs
			arr = append(arr, change{diff: false, val: chval})
		case 0: // diff
			arr = append(arr, change{diff: true, val: chval})
		default:
			return fmt.Errorf("unknown change type: %d", chtp)
		}
		changes[rid] = arr
	}
	bag.changes = changes
	return r.Err()
}
예제 #4
0
파일: link.go 프로젝트: josebalius/orientgo
func (bag *sbTreeRidBag) deserializeDelegate(br *rw.Reader) error {
	fileId := br.ReadLong()
	pageIndex := br.ReadLong()
	pageOffset := int(br.ReadInt())
	br.ReadInt() // Cached bag size. Not used after 1.7.5
	if err := br.Err(); err != nil {
		return err
	}
	if fileId == -1 {
		bag.collectionPtr = nil
	} else {
		bag.collectionPtr = newBonsaiCollectionPtr(fileId, pageIndex, pageOffset)
	}
	bag.size = -1
	return bag.deserializeChanges(br)
}
예제 #5
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()
}
예제 #6
0
func (db *Database) readIdentifiable(r *rw.Reader) (orient.OIdentifiable, error) {
	classId := r.ReadShort()
	if err := r.Err(); err != nil {
		return nil, err
	}
	switch classId {
	case RecordNull:
		return nil, nil
	case RecordRID:
		var rid orient.RID
		if err := rid.FromStream(r); err != nil {
			return nil, err
		}
		return rid, nil
	default:
		tp := orient.RecordType(r.ReadByte())
		if err := r.Err(); err != nil {
			return nil, err
		}
		record := orient.NewRecordOfType(tp)
		switch rec := record.(type) {
		case *orient.Document:
			rec.SetSerializer(db.sess.cli.recordFormat)
		}

		var rid orient.RID
		if err := rid.FromStream(r); err != nil {
			return nil, err
		}
		version := int(r.ReadInt())
		content := r.ReadBytes()

		if err := record.Fill(rid, version, content); err != nil {
			return nil, fmt.Errorf("cannot create record %T from content: %s", record, err)
		}
		return record, nil
	}
}