Skip to content

Commit e99ee2a

Browse files
committed
object_db.go: introduce Object()
Historically, callers have been able to access different objects stored in the object database by (1) knowing the type of the object that they desire to open and (2) calling the function associated with that type (e.g., `Blob()`, `Commit()`, and so on) based on that information. Sometimes, however, callers would like to open an object of known existence but unknown type. Let's introduce `Object()` to do just that, and construct a concrete implementation based on the type of object in the header.
1 parent 6b07b01 commit e99ee2a

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

object_db.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,38 @@ func (o *ObjectDatabase) Close() error {
6666
return nil
6767
}
6868

69+
// Object returns an Object (of unknown implementation) satisfying the type
70+
// associated with the object named "sha".
71+
//
72+
// If the object could not be opened, is of unknown type, or could not be
73+
// decoded, than an appropriate error is returned instead.
74+
func (o *ObjectDatabase) Object(sha []byte) (Object, error) {
75+
r, err := o.open(sha)
76+
if err != nil {
77+
return nil, err
78+
}
79+
80+
typ, _, err := r.Header()
81+
if err != nil {
82+
return nil, err
83+
}
84+
85+
var into Object
86+
switch typ {
87+
case BlobObjectType:
88+
into = new(Blob)
89+
case TreeObjectType:
90+
into = new(Tree)
91+
case CommitObjectType:
92+
into = new(Commit)
93+
case TagObjectType:
94+
into = new(Tag)
95+
default:
96+
return nil, fmt.Errorf("gitobj: unknown object type: %s", typ)
97+
}
98+
return into, o.decode(r, into)
99+
}
100+
69101
// Blob returns a *Blob as identified by the SHA given, or an error if one was
70102
// encountered.
71103
func (o *ObjectDatabase) Blob(sha []byte) (*Blob, error) {

object_db_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,32 @@ import (
1515
"github.com/stretchr/testify/require"
1616
)
1717

18+
func TestDecodeObject(t *testing.T) {
19+
sha := "af5626b4a114abcb82d63db7c8082c3c4756e51b"
20+
contents := "Hello, world!\n"
21+
22+
var buf bytes.Buffer
23+
24+
zw := zlib.NewWriter(&buf)
25+
fmt.Fprintf(zw, "blob 14\x00%s", contents)
26+
zw.Close()
27+
28+
odb := &ObjectDatabase{s: newMemoryStorer(map[string]io.ReadWriter{
29+
sha: &buf,
30+
})}
31+
32+
shaHex, _ := hex.DecodeString(sha)
33+
obj, err := odb.Object(shaHex)
34+
blob, ok := obj.(*Blob)
35+
36+
require.NoError(t, err)
37+
require.True(t, ok)
38+
39+
got, err := ioutil.ReadAll(blob.Contents)
40+
assert.Nil(t, err)
41+
assert.Equal(t, contents, string(got))
42+
}
43+
1844
func TestDecodeBlob(t *testing.T) {
1945
sha := "af5626b4a114abcb82d63db7c8082c3c4756e51b"
2046
contents := "Hello, world!\n"

0 commit comments

Comments
 (0)