diff --git a/config.yml b/config.yml index df0b400..4acf3e3 100644 --- a/config.yml +++ b/config.yml @@ -17,8 +17,8 @@ opengist-home: # Secret key used for session store & encrypt MFA data on database. Default: secret-key: -# URI of the database. Default: opengist.db (SQLite) -# SQLite: file name +# URI of the database. Default: opengist.db (SQLite) is placed in opengist-home +# SQLite: file:/path/to/database # PostgreSQL: postgres://user:password@host:port/database # MySQL/MariaDB: mysql://user:password@host:port/database db-uri: opengist.db diff --git a/docs/configuration/databases/sqlite.md b/docs/configuration/databases/sqlite.md index ff3be8f..d5367ca 100644 --- a/docs/configuration/databases/sqlite.md +++ b/docs/configuration/databases/sqlite.md @@ -5,7 +5,7 @@ By default, Opengist uses SQLite as the database backend. Because SQLite is a file-based database, there is not much configuration to tweak. The configuration `db-uri`/`OG_DB_URI` refers to the path of the SQLite database file relative in the `$opengist-home/` directory (default `opengist.db`), -although it can be left untouched. +although it can be left untouched. You can also use an absolute path outside the `$opengist-home/` directory. The SQLite journal mode is set to [`WAL` (Write-Ahead Logging)](https://www.sqlite.org/pragma.html#pragma_journal_mode) by default and can be changed. @@ -14,6 +14,9 @@ The SQLite journal mode is set to [`WAL` (Write-Ahead Logging)](https://www.sqli # default db-uri: opengist.db sqlite.journal-mode: WAL + +# absolute path outside the $opengist-home/ directory +db-uri: file:/home/user/opengist.db ``` #### Environment variable diff --git a/internal/db/db.go b/internal/db/db.go index 6c7f85c..3b5c027 100644 --- a/internal/db/db.go +++ b/internal/db/db.go @@ -46,25 +46,24 @@ var DatabaseInfo *databaseInfo func parseDBURI(uri string) (*databaseInfo, error) { info := &databaseInfo{} - if !strings.Contains(uri, "://") { - info.Type = SQLite - if uri == "file::memory:" { - info.Database = "file::memory:" - return info, nil - } - info.Database = filepath.Join(config.GetHomeDir(), uri) - return info, nil - } u, err := url.Parse(uri) if err != nil { return nil, fmt.Errorf("invalid URI: %v", err) } + if u.Scheme == "" { + info.Type = SQLite + info.Database = filepath.Join(config.GetHomeDir(), uri) + return info, nil + } + switch u.Scheme { case "postgres", "postgresql": info.Type = PostgreSQL case "mysql", "mariadb": info.Type = MySQL + case "file": + info.Type = SQLite default: return nil, fmt.Errorf("unknown database: %v", err) } @@ -83,6 +82,8 @@ func parseDBURI(uri string) (*databaseInfo, error) { switch info.Type { case PostgreSQL, MySQL: info.Database = strings.TrimPrefix(u.Path, "/") + case SQLite: + info.Database = u.String() default: return nil, fmt.Errorf("unknown database: %v", err) } @@ -190,12 +191,21 @@ func setupSQLite(dbInfo databaseInfo, sharedCache bool) error { log.Warn().Msg("Invalid SQLite journal mode: " + journalMode) } - sharedCacheStr := "" - if sharedCache { - sharedCacheStr = "&cache=shared" + u, err := url.Parse(dbInfo.Database) + if err != nil { + return err } - db, err = gorm.Open(sqlite.Open(dbInfo.Database+"?_fk=true&_journal_mode="+journalMode+sharedCacheStr), &gorm.Config{ + u.Scheme = "file" + q := u.Query() + q.Set("_fk", "true") + q.Set("_journal_mode", journalMode) + if sharedCache { + q.Set("cache", "shared") + } + u.RawQuery = q.Encode() + dsn := u.String() + db, err = gorm.Open(sqlite.Open(dsn), &gorm.Config{ Logger: logger.Default.LogMode(logger.Silent), TranslateError: true, })