func (p *PolicyOperator) Restore(rc io.ReadCloser) error {
	p.l.Lock()
	defer p.l.Unlock()
	dbPath := p.db.Path()
	err := p.db.Close()
	if err != nil {
		p.logger.Error("failed to close database file", zap.Error(err))
		return err
	}
	gz, err := gzip.NewReader(rc)
	if err != nil {
		p.logger.Error("failed to new gzip", zap.Error(err))
		return err
	}
	buf := new(bytes.Buffer)
	if _, err := io.Copy(buf, gz); err != nil {
		p.logger.Error("failed to copy data", zap.Error(err))
		return err
	}
	err = gz.Close()
	if err != nil {
		p.logger.Error("failed to close the gzip", zap.Error(err))
		return err
	}
	err = ioutil.WriteFile(dbPath, buf.Bytes(), 0600)
	if err != nil {
		p.logger.Error("failed to restore the database file", zap.Error(err))
		return err
	}
	err = p.openDBFile(dbPath)
	if err != nil {
		p.logger.Error("failed to open the database file", zap.Error(err))
		return err
	}
	err = p.loadPolicy()
	if err != nil {
		p.logger.Error("failed to load policy from bolt", zap.Error(err))
		return errors.Wrapf(err, "failed to load policy from bolt")
	}
	return nil
}
Restore is used to restore a database from io.ReadCloser.
package store
import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"io/ioutil"
	"path/filepath"
	"strconv"
	"sync"
	"time"
	"github.com/casbin/casbin/v2"
	jsoniter "github.com/json-iterator/go"
	"github.com/pkg/errors"
	bolt "go.etcd.io/bbolt"
	"go.uber.org/zap"
)
const (
	databaseFilename = "casbin.db"
)
var (
	policyBucketName = []byte("policy_rules")
)
type PolicyOperator struct {
	enforcer casbin.IDistributedEnforcer
	db       *bolt.DB
	l        *sync.Mutex
	logger   *zap.Logger
}
func NewPolicyOperator(logger *zap.Logger, path string, e casbin.IDistributedEnforcer) (*PolicyOperator, error) {
	p := &PolicyOperator{
		enforcer: e,
		l:        &sync.Mutex{},
		logger:   logger,
	}
	dbPath := filepath.Join(path, databaseFilename)
	if err := p.openDBFile(dbPath); err != nil {
		return nil, errors.Wrapf(err, "failed to open bolt file")
	}
	return p, nil
}
func (p *PolicyOperator) openDBFile(dbPath string) error {
	if len(dbPath) == 0 {
		return errors.New("dbPath cannot be an empty")
	}
	boltDB, err := bolt.Open(dbPath, 0666, &bolt.Options{Timeout: 1 * time.Second})
	if err != nil {
		return err
	}
	p.db = boltDB
	return p.createBucket(policyBucketName)
}