mirror of
https://github.com/lightningnetwork/lnd.git
synced 2024-11-19 18:10:34 +01:00
84 lines
2.2 KiB
Go
84 lines
2.2 KiB
Go
|
//go:build kvdb_sqlite && !(windows && (arm || 386)) && !(linux && (ppc64 || mips || mipsle || mips64))
|
||
|
|
||
|
package sqlite
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"fmt"
|
||
|
"net/url"
|
||
|
"path/filepath"
|
||
|
|
||
|
"github.com/btcsuite/btcwallet/walletdb"
|
||
|
"github.com/lightningnetwork/lnd/kvdb/sqlbase"
|
||
|
_ "modernc.org/sqlite" // Register relevant drivers.
|
||
|
)
|
||
|
|
||
|
const (
|
||
|
// sqliteOptionPrefix is the string prefix sqlite uses to set various
|
||
|
// options. This is used in the following format:
|
||
|
// * sqliteOptionPrefix || option_name = option_value.
|
||
|
sqliteOptionPrefix = "_pragma"
|
||
|
|
||
|
// sqliteTxLockImmediate is a dsn option used to ensure that write
|
||
|
// transactions are started immediately.
|
||
|
sqliteTxLockImmediate = "_txlock=immediate"
|
||
|
)
|
||
|
|
||
|
// NewSqliteBackend returns a db object initialized with the passed backend
|
||
|
// config. If a sqlite connection cannot be established, then an error is
|
||
|
// returned.
|
||
|
func NewSqliteBackend(ctx context.Context, cfg *Config, dbPath, fileName,
|
||
|
prefix string) (walletdb.DB, error) {
|
||
|
|
||
|
// First, we add a set of mandatory pragma options to the query.
|
||
|
pragmaOptions := []struct {
|
||
|
name string
|
||
|
value string
|
||
|
}{
|
||
|
{
|
||
|
name: "busy_timeout",
|
||
|
value: fmt.Sprintf(
|
||
|
"%d", cfg.BusyTimeout.Milliseconds(),
|
||
|
),
|
||
|
},
|
||
|
{
|
||
|
name: "foreign_keys",
|
||
|
value: "on",
|
||
|
},
|
||
|
{
|
||
|
name: "journal_mode",
|
||
|
value: "WAL",
|
||
|
},
|
||
|
}
|
||
|
sqliteOptions := make(url.Values)
|
||
|
for _, option := range pragmaOptions {
|
||
|
sqliteOptions.Add(
|
||
|
sqliteOptionPrefix,
|
||
|
fmt.Sprintf("%v=%v", option.name, option.value),
|
||
|
)
|
||
|
}
|
||
|
|
||
|
// Then we add any user specified pragma options. Note that these can
|
||
|
// be of the form: "key=value", "key(N)" or "key".
|
||
|
for _, option := range cfg.PragmaOptions {
|
||
|
sqliteOptions.Add(sqliteOptionPrefix, option)
|
||
|
}
|
||
|
|
||
|
// Construct the DSN which is just the database file name, appended
|
||
|
// with the series of pragma options as a query URL string. For more
|
||
|
// details on the formatting here, see the modernc.org/sqlite docs:
|
||
|
// https://pkg.go.dev/modernc.org/sqlite#Driver.Open.
|
||
|
dsn := fmt.Sprintf(
|
||
|
"%v?%v&%v", filepath.Join(dbPath, fileName),
|
||
|
sqliteOptions.Encode(), sqliteTxLockImmediate,
|
||
|
)
|
||
|
sqlCfg := &sqlbase.Config{
|
||
|
DriverName: "sqlite",
|
||
|
Dsn: dsn,
|
||
|
Timeout: cfg.Timeout,
|
||
|
TableNamePrefix: prefix,
|
||
|
}
|
||
|
|
||
|
return sqlbase.NewSqlBackend(ctx, sqlCfg)
|
||
|
}
|