ref: 3b44bb05f74ebd2734f12808c813dae2995b41b1
parent: e42ad9964d9c9372ecb63c860ed2c91b09b373b2
author: Runxi Yu <me@runxiyu.org>
date: Fri Feb 20 19:11:00 EST 2026
objectdb: Add Reader-based methods
--- a/objectdb/chain.go
+++ b/objectdb/chain.go
@@ -3,6 +3,7 @@
import (
"errors"
"fmt"
+ "io"
"codeberg.org/lindenii/furgit/objectid"
"codeberg.org/lindenii/furgit/objecttype"
@@ -52,6 +53,42 @@
continue
}
return objecttype.TypeInvalid, nil, fmt.Errorf("objectdb: backend %d read bytes content: %w", i, err)+ }
+ return objecttype.TypeInvalid, nil, ErrObjectNotFound
+}
+
+// ReadReaderFull reads a full serialized object stream from the first backend that has it.
+func (chain *Chain) ReadReaderFull(id objectid.ObjectID) (io.ReadCloser, error) {+ for i, backend := range chain.backends {+ if backend == nil {+ continue
+ }
+ reader, err := backend.ReadReaderFull(id)
+ if err == nil {+ return reader, nil
+ }
+ if errors.Is(err, ErrObjectNotFound) {+ continue
+ }
+ return nil, fmt.Errorf("objectdb: backend %d read reader full: %w", i, err)+ }
+ return nil, ErrObjectNotFound
+}
+
+// ReadReaderContent reads an object's type and content stream from the first backend that has it.
+func (chain *Chain) ReadReaderContent(id objectid.ObjectID) (objecttype.Type, io.ReadCloser, error) {+ for i, backend := range chain.backends {+ if backend == nil {+ continue
+ }
+ ty, reader, err := backend.ReadReaderContent(id)
+ if err == nil {+ return ty, reader, nil
+ }
+ if errors.Is(err, ErrObjectNotFound) {+ continue
+ }
+ return objecttype.TypeInvalid, nil, fmt.Errorf("objectdb: backend %d read reader content: %w", i, err)}
return objecttype.TypeInvalid, nil, ErrObjectNotFound
}
--- a/objectdb/objectdb.go
+++ b/objectdb/objectdb.go
@@ -3,6 +3,7 @@
import (
"errors"
+ "io"
"codeberg.org/lindenii/furgit/objectid"
"codeberg.org/lindenii/furgit/objecttype"
@@ -19,6 +20,12 @@
ReadBytesFull(id objectid.ObjectID) ([]byte, error)
// ReadBytesContent reads an object's type and content bytes.
ReadBytesContent(id objectid.ObjectID) (objecttype.Type, []byte, error)
+ // ReadReaderFull reads a full serialized object stream as "type size\\x00content".
+ // Caller must close the returned reader.
+ ReadReaderFull(id objectid.ObjectID) (io.ReadCloser, error)
+ // ReadReaderContent reads an object's type and content stream.
+ // Caller must close the returned reader.
+ ReadReaderContent(id objectid.ObjectID) (objecttype.Type, io.ReadCloser, error)
// ReadHeader reads an object's type and declared content length.
ReadHeader(id objectid.ObjectID) (objecttype.Type, int64, error)
// Close releases resources associated with the backend.
--
⑨