func (db *DB) Close() {
	if db.closed {
		return
	}
	db.closed = true
	C.leveldb_close(db.Ldb)
}
Close closes the database, rendering it unusable for I/O, by deallocating
the underlying handle.

Any attempts to use the DB after Close is called will panic.
package levigo
import "C"
import (
	"errors"
	"unsafe"
)
type DatabaseError string
func (e DatabaseError) Error() string {
	return string(e)
}
var ErrDBClosed = errors.New("database is closed")
type DB struct {
	Ldb *C.leveldb_t
	closed bool
}
type Range struct {
	Start []byte
	Limit []byte
}
type Snapshot struct {
	snap *C.leveldb_snapshot_t
}
func Open(dbname string, o *Options) (*DB, error) {
	var errStr *C.char
	ldbname := C.CString(dbname)
	defer C.free(unsafe.Pointer(ldbname))
	leveldb := C.leveldb_open(o.Opt, ldbname, &errStr)
	if errStr != nil {
		gs := C.GoString(errStr)
		C.leveldb_free(unsafe.Pointer(errStr))
		return nil, DatabaseError(gs)
	}
	return &DB{leveldb, false}, nil
}
func DestroyDatabase(dbname string, o *Options) error {
	var errStr *C.char
	ldbname := C.CString(dbname)
	defer C.free(unsafe.Pointer(ldbname))
	C.leveldb_destroy_db(o.Opt, ldbname, &errStr)
	if errStr != nil {
		gs := C.GoString(errStr)
		C.leveldb_free(unsafe.Pointer(errStr))
		return DatabaseError(gs)
	}
	return nil
}
func RepairDatabase(dbname string, o *Options) error {
	var errStr *C.char
	ldbname := C.CString(dbname)
	defer C.free(unsafe.Pointer(ldbname))
	C.leveldb_repair_db(o.Opt, ldbname, &errStr)
	if errStr != nil {
		gs := C.GoString(errStr)
		C.leveldb_free(unsafe.Pointer(errStr))
		return DatabaseError(gs)
	}
	return nil
}
func (db *DB) Put(wo *WriteOptions, key, value []byte) error {
	if db.closed {
		panic(ErrDBClosed)
	}
	var errStr *C.char
	var k, v *C.char
	if len(key) != 0 {
		k = (*C.char)(unsafe.Pointer(&key[0]))
	}
	if len(value) != 0 {
		v = (*C.char)(unsafe.Pointer(&value[0]))
	}
	lenk := len(key)
	lenv := len(value)
	C.leveldb_put(
		db.Ldb, wo.Opt, k, C.size_t(lenk), v, C.size_t(lenv), &errStr)
	if errStr != nil {
		gs := C.GoString(errStr)
		C.leveldb_free(unsafe.Pointer(errStr))
		return DatabaseError(gs)
	}
	return nil
}
func (db *DB) Get(ro *ReadOptions, key []byte) ([]byte, error) {
	if db.closed {
		panic(ErrDBClosed)
	}
	var errStr *C.char
	var vallen C.size_t
	var k *C.char
	if len(key) != 0 {
		k = (*C.char)(unsafe.Pointer(&key[0]))
	}
	value := C.leveldb_get(
		db.Ldb, ro.Opt, k, C.size_t(len(key)), &vallen, &errStr)
	if errStr != nil {
		gs := C.GoString(errStr)
		C.leveldb_free(unsafe.Pointer(errStr))
		return nil, DatabaseError(gs)
	}
	if value == nil {
		return nil, nil
	}
	defer C.leveldb_free(unsafe.Pointer(value))
	return C.GoBytes(unsafe.Pointer(value), C.int(vallen)), nil
}
func (db *DB) Delete(wo *WriteOptions, key []byte) error {
	if db.closed {
		panic(ErrDBClosed)
	}
	var errStr *C.char
	var k *C.char
	if len(key) != 0 {
		k = (*C.char)(unsafe.Pointer(&key[0]))
	}
	C.leveldb_delete(
		db.Ldb, wo.Opt, k, C.size_t(len(key)), &errStr)
	if errStr != nil {
		gs := C.GoString(errStr)
		C.leveldb_free(unsafe.Pointer(errStr))
		return DatabaseError(gs)
	}
	return nil
}
func (db *DB) Write(wo *WriteOptions, w *WriteBatch) error {
	if db.closed {
		panic(ErrDBClosed)
	}
	var errStr *C.char
	C.leveldb_write(db.Ldb, wo.Opt, w.wbatch, &errStr)
	if errStr != nil {
		gs := C.GoString(errStr)
		C.leveldb_free(unsafe.Pointer(errStr))
		return DatabaseError(gs)
	}
	return nil
}
func (db *DB) NewIterator(ro *ReadOptions) *Iterator {
	if db.closed {
		panic(ErrDBClosed)
	}
	it := C.leveldb_create_iterator(db.Ldb, ro.Opt)
	return &Iterator{Iter: it}
}
func (db *DB) GetApproximateSizes(ranges []Range) []uint64 {
	starts := make([]*C.char, len(ranges))
	limits := make([]*C.char, len(ranges))
	startLens := make([]C.size_t, len(ranges))
	limitLens := make([]C.size_t, len(ranges))
	for i, r := range ranges {
		starts[i] = C.CString(string(r.Start))
		startLens[i] = C.size_t(len(r.Start))
		limits[i] = C.CString(string(r.Limit))
		limitLens[i] = C.size_t(len(r.Limit))
	}
	sizes := make([]uint64, len(ranges))
	numranges := C.int(len(ranges))
	startsPtr := &starts[0]
	limitsPtr := &limits[0]
	startLensPtr := &startLens[0]
	limitLensPtr := &limitLens[0]
	sizesPtr := (*C.uint64_t)(&sizes[0])
	C.levigo_leveldb_approximate_sizes(
		db.Ldb, numranges, startsPtr, startLensPtr,
		limitsPtr, limitLensPtr, sizesPtr)
	for i := range ranges {
		C.free(unsafe.Pointer(starts[i]))
		C.free(unsafe.Pointer(limits[i]))
	}
	return sizes
}
func (db *DB) PropertyValue(propName string) string {
	if db.closed {
		panic(ErrDBClosed)
	}
	cname := C.CString(propName)
	value := C.GoString(C.leveldb_property_value(db.Ldb, cname))
	C.free(unsafe.Pointer(cname))
	return value
}
func (db *DB) NewSnapshot() *Snapshot {
	if db.closed {
		panic(ErrDBClosed)
	}
	return &Snapshot{C.leveldb_create_snapshot(db.Ldb)}
}
func (db *DB) ReleaseSnapshot(snap *Snapshot) {
	if db.closed {
		panic(ErrDBClosed)
	}
	C.leveldb_release_snapshot(db.Ldb, snap.snap)
}
func (db *DB) CompactRange(r Range) {
	if db.closed {
		panic(ErrDBClosed)
	}
	var start, limit *C.char
	if len(r.Start) != 0 {
		start = (*C.char)(unsafe.Pointer(&r.Start[0]))
	}
	if len(r.Limit) != 0 {
		limit = (*C.char)(unsafe.Pointer(&r.Limit[0]))
	}
	C.leveldb_compact_range(
		db.Ldb, start, C.size_t(len(r.Start)), limit, C.size_t(len(r.Limit)))
}