func (p *LevelDBWal) Write(l *kt.Log) (err error) {
	if atomic.LoadUint32(&p.closed) == 1 {
		err = ErrWalClosed
		return
	}
	atomic.CompareAndSwapUint32(&p.read, 0, 1)
	if l == nil {
		err = ErrInvalidLog
		return
	}
	headerKey := append(append([]byte(nil), logHeaderKeyPrefix...), p.uint64ToBytes(l.Index)...)
	if _, err = p.db.Get(headerKey, nil); err != nil && err != leveldb.ErrNotFound {
		err = errors.Wrap(err, "access leveldb failed")
		return
	} else if err == nil {
		err = ErrAlreadyExists
		return
	}
	dataKey := append(append([]byte(nil), logDataKeyPrefix...), p.uint64ToBytes(l.Index)...)
	var enc *bytes.Buffer
	if enc, err = utils.EncodeMsgPack(l.Data); err != nil {
		err = errors.Wrap(err, "encode log data failed")
		return
	}
	if err = p.db.Put(dataKey, enc.Bytes(), nil); err != nil {
		err = errors.Wrap(err, "write log data failed")
		return
	}
	l.DataLength = uint64(enc.Len())
	if enc, err = utils.EncodeMsgPack(l.LogHeader); err != nil {
		err = errors.Wrap(err, "encode log header failed")
		return
	}
	if err = p.db.Put(headerKey, enc.Bytes(), nil); err != nil {
		err = errors.Wrap(err, "encode log header failed")
		return
	}
	return
}
Write implements Wal.Write.
package wal
import (
	"bytes"
	"encoding/binary"
	"io"
	"sync"
	"sync/atomic"
	"github.com/pkg/errors"
	"github.com/syndtr/goleveldb/leveldb"
	"github.com/syndtr/goleveldb/leveldb/iterator"
	"github.com/syndtr/goleveldb/leveldb/util"
	kt "github.com/SQLess/SQLess/kayak/types"
	"github.com/SQLess/SQLess/utils"
	"github.com/SQLess/SQLess/utils/log"
)
var (
	logHeaderKeyPrefix = []byte{'L', 'H'}
	logDataKeyPrefix = []byte{'L', 'D'}
)
type LevelDBWal struct {
	db       *leveldb.DB
	it       iterator.Iterator
	closed   uint32
	readLock sync.Mutex
	read     uint32
}
func NewLevelDBWal(filename string) (p *LevelDBWal, err error) {
	p = &LevelDBWal{}
	if p.db, err = leveldb.OpenFile(filename, nil); err != nil {
		err = errors.Wrap(err, "open database failed")
		return
	}
	return
}