Metadata options to control journaling and WAL
Signed-off-by: ItalyPaleAle <43508+ItalyPaleAle@users.noreply.github.com>
This commit is contained in:
parent
37cee72884
commit
5811cb0dba
|
@ -76,7 +76,13 @@ func (a *sqliteDBAccess) Init(md state.Metadata) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
db, err := sql.Open("sqlite", a.getConnectionString())
|
connString, err := a.getConnectionString()
|
||||||
|
if err != nil {
|
||||||
|
// Already logged
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
db, err := sql.Open("sqlite", connString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
a.logger.Error(err)
|
a.logger.Error(err)
|
||||||
return err
|
return err
|
||||||
|
@ -100,7 +106,11 @@ func (a *sqliteDBAccess) Init(md state.Metadata) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *sqliteDBAccess) getConnectionString() string {
|
func (a *sqliteDBAccess) getConnectionString() (string, error) {
|
||||||
|
// Check if we're using the in-memory database
|
||||||
|
lc := strings.ToLower(a.metadata.ConnectionString)
|
||||||
|
isMemoryDB := strings.HasPrefix(lc, ":memory:") || strings.HasPrefix(lc, "file::memory:")
|
||||||
|
|
||||||
// Get the "query string" from the connection string if present
|
// Get the "query string" from the connection string if present
|
||||||
idx := strings.IndexRune(a.metadata.ConnectionString, '?')
|
idx := strings.IndexRune(a.metadata.ConnectionString, '?')
|
||||||
var qs url.Values
|
var qs url.Values
|
||||||
|
@ -126,11 +136,32 @@ func (a *sqliteDBAccess) getConnectionString() string {
|
||||||
|
|
||||||
// Add pragma values
|
// Add pragma values
|
||||||
if len(qs["_pragma"]) == 0 {
|
if len(qs["_pragma"]) == 0 {
|
||||||
qs["_pragma"] = make([]string, 0, 1)
|
qs["_pragma"] = make([]string, 0, 2)
|
||||||
|
} else {
|
||||||
|
for _, p := range qs["_pragma"] {
|
||||||
|
p = strings.ToLower(p)
|
||||||
|
if strings.HasPrefix(p, "busy_timeout") {
|
||||||
|
a.logger.Error("Cannot set `_pragma=busy_timeout` option in the connection string; please use the `busyTimeout` metadata property instead")
|
||||||
|
return "", errors.New("found forbidden option '_pragma=busy_timeout' in the connection string")
|
||||||
|
} else if strings.HasPrefix(p, "journal_mode") {
|
||||||
|
a.logger.Error("Cannot set `_pragma=journal_mode` option in the connection string; please use the `disableWAL` metadata property instead")
|
||||||
|
return "", errors.New("found forbidden option '_pragma=journal_mode' in the connection string")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if a.metadata.busyTimeout > 0 {
|
if a.metadata.busyTimeout > 0 {
|
||||||
qs["_pragma"] = append(qs["_pragma"], fmt.Sprintf("busy_timeout(%d)", a.metadata.busyTimeout.Milliseconds()))
|
qs["_pragma"] = append(qs["_pragma"], fmt.Sprintf("busy_timeout(%d)", a.metadata.busyTimeout.Milliseconds()))
|
||||||
}
|
}
|
||||||
|
if isMemoryDB {
|
||||||
|
// For in-memory databases, set the journal to MEMORY, the only allowed option besides OFF (which would make transactions ineffective)
|
||||||
|
qs["_pragma"] = append(qs["_pragma"], "journal_mode(MEMORY)")
|
||||||
|
} else if a.metadata.DisableWAL {
|
||||||
|
// Set the journaling mode to "DELETE" (the default) if WAL is disabled
|
||||||
|
qs["_pragma"] = append(qs["_pragma"], "journal_mode(DELETE)")
|
||||||
|
} else {
|
||||||
|
// Enable WAL
|
||||||
|
qs["_pragma"] = append(qs["_pragma"], "journal_mode(WAL)")
|
||||||
|
}
|
||||||
|
|
||||||
// Build the final connection string
|
// Build the final connection string
|
||||||
connString := a.metadata.ConnectionString
|
connString := a.metadata.ConnectionString
|
||||||
|
@ -140,12 +171,12 @@ func (a *sqliteDBAccess) getConnectionString() string {
|
||||||
connString += "?" + qs.Encode()
|
connString += "?" + qs.Encode()
|
||||||
|
|
||||||
// If the connection string doesn't begin with "file:", add the prefix
|
// If the connection string doesn't begin with "file:", add the prefix
|
||||||
if !strings.HasPrefix(connString, "file:") {
|
if !strings.HasPrefix(lc, "file:") {
|
||||||
a.logger.Info("prefix 'file:' added to the connection string")
|
a.logger.Info("prefix 'file:' added to the connection string")
|
||||||
connString = "file:" + connString
|
connString = "file:" + connString
|
||||||
}
|
}
|
||||||
|
|
||||||
return connString
|
return connString, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *sqliteDBAccess) Ping(parentCtx context.Context) error {
|
func (a *sqliteDBAccess) Ping(parentCtx context.Context) error {
|
||||||
|
|
|
@ -39,6 +39,7 @@ type sqliteMetadataStruct struct {
|
||||||
TimeoutInSeconds string `json:"timeoutInSeconds" mapstructure:"timeoutInSeconds"`
|
TimeoutInSeconds string `json:"timeoutInSeconds" mapstructure:"timeoutInSeconds"`
|
||||||
CleanupIntervalStr string `json:"cleanupInterval" mapstructure:"cleanupInterval"` // Cleanup interval as a time.Duration string
|
CleanupIntervalStr string `json:"cleanupInterval" mapstructure:"cleanupInterval"` // Cleanup interval as a time.Duration string
|
||||||
BusyTimeoutStr string `json:"busyTimeout" mapstructure:"busyTimeout"` // Busy timeout as a time.Duration string
|
BusyTimeoutStr string `json:"busyTimeout" mapstructure:"busyTimeout"` // Busy timeout as a time.Duration string
|
||||||
|
DisableWAL bool `json:"disableWAL" mapstructure:"disableWAL"` // Disable WAL journaling. You should not use WAL if the database is stored on a network filesystem (or data corruption may happen). This is ignored if the database is in-memory.
|
||||||
|
|
||||||
timeout time.Duration
|
timeout time.Duration
|
||||||
cleanupInterval time.Duration
|
cleanupInterval time.Duration
|
||||||
|
@ -49,8 +50,12 @@ func (m *sqliteMetadataStruct) InitWithMetadata(meta state.Metadata) error {
|
||||||
// Reset the object
|
// Reset the object
|
||||||
m.ConnectionString = ""
|
m.ConnectionString = ""
|
||||||
m.TableName = defaultTableName
|
m.TableName = defaultTableName
|
||||||
m.cleanupInterval = defaultCleanupInternal
|
m.TimeoutInSeconds = ""
|
||||||
|
m.CleanupIntervalStr = ""
|
||||||
|
m.BusyTimeoutStr = ""
|
||||||
|
m.DisableWAL = false
|
||||||
m.timeout = defaultTimeout
|
m.timeout = defaultTimeout
|
||||||
|
m.cleanupInterval = defaultCleanupInternal
|
||||||
m.busyTimeout = defaultBusyTimeout
|
m.busyTimeout = defaultBusyTimeout
|
||||||
|
|
||||||
// Decode the metadata
|
// Decode the metadata
|
||||||
|
|
Loading…
Reference in New Issue