package main import "C" import ( "errors" "os" "github.com/boltdb/bolt" ) //export GetMagic func GetMagic() int64 { return 0x10203040 } //export Bolt_Options_New func Bolt_Options_New() ObjectReference { b := *bolt.DefaultOptions return gms.Put(&b) } //export Bolt_Options_New_Readonly func Bolt_Options_New_Readonly() ObjectReference { b := *bolt.DefaultOptions b.ReadOnly = true return gms.Put(&b) } //export Recall func Recall(f func(a int64) int64) int64 { return f(3) } //export Bolt_Open func Bolt_Open(path string, mode uint32, opts ObjectReference) (ObjectReference, string) { optsIFC, ok := gms.Get(opts) if !ok { return 0, "" } ptrBoltOps, ok := optsIFC.(*bolt.Options) if !ok { return 0, "" } ptrDB, err := bolt.Open(path, os.FileMode(mode), ptrBoltOps) if err != nil { return 0, err.Error() } dbRef := gms.Put(ptrDB) return dbRef, "" } func withBoltDBReference(b ObjectReference, fn func(db *bolt.DB) error) error { dbIFC, ok := gms.Get(b) if !ok { return NullObjectReference } ptrDB, ok := dbIFC.(*bolt.DB) if !ok { return NullObjectReference } return fn(ptrDB) } //export Bolt_ListBuckets func Bolt_ListBuckets(b ObjectReference, browse []string, withEach func(string)) string { if len(browse) == 0 { return Bolt_ListBucketsAtRoot(b, withEach) } err := withBoltDBReference(b, func(db *bolt.DB) error { return db.View(func(tx *bolt.Tx) error { bucket := tx.Bucket([]byte(browse[0])) if bucket == nil { return errors.New("Unknown bucket") } for i := 1; i < len(browse); i += 1 { bucket = bucket.Bucket([]byte(browse[i])) if bucket == nil { return errors.New("Unknown bucket") } } return bucket.ForEach(func(k, v []byte) error { withEach(string(k)) return nil }) }) }) if err != nil { return err.Error() } return "" } //export Bolt_ListBucketsAtRoot func Bolt_ListBucketsAtRoot(b ObjectReference, withEach func(string)) string { err := withBoltDBReference(b, func(db *bolt.DB) error { return db.View(func(tx *bolt.Tx) error { return tx.ForEach(func(n []byte, bucket *bolt.Bucket) error { withEach(string(n)) return nil }) }) }) if err != nil { return err.Error() } return "" } //export Bolt_Close func Bolt_Close(b ObjectReference) string { err := withBoltDBReference(b, func(db *bolt.DB) error { return db.Close() }) if err != nil { return err.Error() } gms.Delete(b) return "" } func main() { // virtual }