summaryrefslogtreecommitdiff
path: root/odb.go
diff options
context:
space:
mode:
Diffstat (limited to 'odb.go')
-rw-r--r--odb.go95
1 files changed, 70 insertions, 25 deletions
diff --git a/odb.go b/odb.go
index daf63dd..7076e20 100644
--- a/odb.go
+++ b/odb.go
@@ -5,18 +5,49 @@ package git
#include <git2/errors.h>
extern int _go_git_odb_foreach(git_odb *db, void *payload);
+extern void _go_git_odb_backend_free(git_odb_backend *backend);
*/
import "C"
import (
- "unsafe"
"reflect"
"runtime"
+ "unsafe"
)
type Odb struct {
ptr *C.git_odb
}
+type OdbBackend struct {
+ ptr *C.git_odb_backend
+}
+
+func NewOdb() (odb *Odb, err error) {
+ odb = new(Odb)
+
+ ret := C.git_odb_new(&odb.ptr)
+ if ret < 0 {
+ return nil, MakeGitError(ret)
+ }
+
+ runtime.SetFinalizer(odb, (*Odb).Free)
+ return odb, nil
+}
+
+func NewOdbBackendFromC(ptr *C.git_odb_backend) (backend *OdbBackend) {
+ backend = &OdbBackend{ptr}
+ return backend
+}
+
+func (v *Odb) AddBackend(backend *OdbBackend, priority int) (err error) {
+ ret := C.git_odb_add_backend(v.ptr, backend.ptr, C.int(priority))
+ if ret < 0 {
+ backend.Free()
+ return MakeGitError(ret)
+ }
+ return nil
+}
+
func (v *Odb) Exists(oid *Oid) bool {
ret := C.git_odb_exists(v.ptr, oid.toC())
return ret != 0
@@ -32,10 +63,10 @@ func (v *Odb) Write(data []byte, otype ObjectType) (oid *Oid, err error) {
ret := C.git_odb_write(oid.toC(), v.ptr, unsafe.Pointer(hdr.Data), C.size_t(hdr.Len), C.git_otype(otype))
if ret < 0 {
- err = MakeGitError(ret)
+ return nil, MakeGitError(ret)
}
- return
+ return oid, nil
}
func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) {
@@ -50,33 +81,43 @@ func (v *Odb) Read(oid *Oid) (obj *OdbObject, err error) {
}
runtime.SetFinalizer(obj, (*OdbObject).Free)
- return
+ return obj, nil
+}
+
+type OdbForEachCallback func(id *Oid) error
+
+type foreachData struct {
+ callback OdbForEachCallback
+ err error
}
//export odbForEachCb
func odbForEachCb(id *C.git_oid, payload unsafe.Pointer) int {
- ch := *(*chan *Oid)(payload)
- oid := newOidFromC(id)
- // Because the channel is unbuffered, we never read our own data. If ch is
- // readable, the user has sent something on it, which means we should
- // abort.
- select {
- case ch <- oid:
- case <-ch:
- return -1
+ data := (*foreachData)(payload)
+
+ err := data.callback(newOidFromC(id))
+ if err != nil {
+ data.err = err
+ return C.GIT_EUSER
}
- return 0;
-}
-func (v *Odb) forEachWrap(ch chan *Oid) {
- C._go_git_odb_foreach(v.ptr, unsafe.Pointer(&ch))
- close(ch)
+ return 0
}
-func (v *Odb) ForEach() chan *Oid {
- ch := make(chan *Oid, 0)
- go v.forEachWrap(ch)
- return ch
+func (v *Odb) ForEach(callback OdbForEachCallback) error {
+ data := foreachData {
+ callback: callback,
+ err: nil,
+ }
+
+ ret := C._go_git_odb_foreach(v.ptr, unsafe.Pointer(&data))
+ if ret == C.GIT_EUSER {
+ return data.err
+ } else if ret < 0 {
+ return MakeGitError(ret)
+ }
+
+ return nil
}
// Hash determines the object-ID (sha1) of a data buffer.
@@ -90,9 +131,9 @@ func (v *Odb) Hash(data []byte, otype ObjectType) (oid *Oid, err error) {
ret := C.git_odb_hash(oid.toC(), ptr, C.size_t(header.Len), C.git_otype(otype));
if ret < 0 {
- err = MakeGitError(ret)
+ return nil, MakeGitError(ret)
}
- return
+ return oid, nil
}
// NewReadStream opens a read stream from the ODB. Reading from it will give you the
@@ -122,6 +163,10 @@ func (v *Odb) NewWriteStream(size int, otype ObjectType) (*OdbWriteStream, error
return stream, nil
}
+func (v *OdbBackend) Free() {
+ C._go_git_odb_backend_free(v.ptr)
+}
+
type OdbObject struct {
ptr *C.git_odb_object
}
@@ -185,7 +230,7 @@ func (stream *OdbReadStream) Free() {
type OdbWriteStream struct {
ptr *C.git_odb_stream
- Id Oid
+ Id Oid
}
// Write writes to the stream