func (s *storeBase) Stop(_ context.Context) error {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	if s.db != nil {
		err := s.db.Close()
		s.db = nil
		return err
	}
	return nil
}
Stop closes the SQL
package sql
import (
	"context"
	"database/sql"
	"os"
	"sync"
	"time"
	"github.com/rs/zerolog"
	"github.com/iotexproject/iotex-core/pkg/lifecycle"
)
type Store interface {
	lifecycle.StartStopper
	GetDB() *sql.DB
	Transact(txFunc func(*sql.Tx) error) (err error)
	SetMaxOpenConns(int)
}
type storeBase struct {
	mutex      sync.RWMutex
	db         *sql.DB
	maxConns   int
	connectStr string
	dbName     string
	driverName string
	readOnly   bool
}
var logger = zerolog.New(os.Stderr).Level(zerolog.InfoLevel).With().Timestamp().Logger()
func newStoreBase(driverName string, connectStr string, dbName string, readOnly bool) Store {
	return &storeBase{db: nil, connectStr: connectStr, dbName: dbName, driverName: driverName, readOnly: readOnly}
}
func (s *storeBase) Start(ctx context.Context) error {
	s.mutex.Lock()
	defer s.mutex.Unlock()
	if s.db != nil {
		return nil
	}
	if !s.readOnly {
		db, err := sql.Open(s.driverName, s.connectStr)
		if err != nil {
			return err
		}
		if _, err = db.Exec("CREATE DATABASE IF NOT EXISTS " + s.dbName); err != nil {
			return err
		}
		db.Close()
	}
	db, err := sql.Open(s.driverName, s.connectStr+s.dbName+"?autocommit=false&parseTime=true")
	if err != nil {
		return err
	}
	s.db = db
	s.db.SetMaxOpenConns(s.maxConns)
	s.db.SetMaxIdleConns(10)
	s.db.SetConnMaxLifetime(5 * time.Minute)
	return nil
}