1
0
mirror of https://github.com/pocket-id/pocket-id.git synced 2026-02-11 11:49:19 +00:00

Merge branch 'main' into v2-main

This commit is contained in:
Elias Schneider
2025-11-30 18:28:00 +01:00
29 changed files with 1159 additions and 1153 deletions

View File

@@ -59,6 +59,12 @@ func ConnectDatabase() (db *gorm.DB, err error) {
return nil, err
}
if !isMemoryDB {
if err := ensureSqliteDatabaseDir(dbPath); err != nil {
return nil, err
}
}
// Before we connect, also make sure that there's a temporary folder for SQLite to write its data
err = ensureSqliteTempDir(filepath.Dir(dbPath))
if err != nil {
@@ -292,6 +298,27 @@ func isSqliteInMemory(connString string) bool {
return len(qs["mode"]) > 0 && qs["mode"][0] == "memory"
}
// ensureSqliteDatabaseDir creates the parent directory for the SQLite database file if it doesn't exist yet
func ensureSqliteDatabaseDir(dbPath string) error {
dir := filepath.Dir(dbPath)
info, err := os.Stat(dir)
switch {
case err == nil:
if !info.IsDir() {
return fmt.Errorf("SQLite database directory '%s' is not a directory", dir)
}
return nil
case os.IsNotExist(err):
if err := os.MkdirAll(dir, 0700); err != nil {
return fmt.Errorf("failed to create SQLite database directory '%s': %w", dir, err)
}
return nil
default:
return fmt.Errorf("failed to check SQLite database directory '%s': %w", dir, err)
}
}
// ensureSqliteTempDir ensures that SQLite has a directory where it can write temporary files if needed
// The default directory may not be writable when using a container with a read-only root file system
// See: https://www.sqlite.org/tempfiles.html

View File

@@ -2,6 +2,8 @@ package bootstrap
import (
"net/url"
"os"
"path/filepath"
"testing"
"github.com/stretchr/testify/assert"
@@ -84,6 +86,29 @@ func TestIsSqliteInMemory(t *testing.T) {
}
}
func TestEnsureSqliteDatabaseDir(t *testing.T) {
t.Run("creates missing directory", func(t *testing.T) {
tempDir := t.TempDir()
dbPath := filepath.Join(tempDir, "nested", "pocket-id.db")
err := ensureSqliteDatabaseDir(dbPath)
require.NoError(t, err)
info, err := os.Stat(filepath.Dir(dbPath))
require.NoError(t, err)
assert.True(t, info.IsDir())
})
t.Run("fails when parent is file", func(t *testing.T) {
tempDir := t.TempDir()
filePath := filepath.Join(tempDir, "file.txt")
require.NoError(t, os.WriteFile(filePath, []byte("test"), 0o600))
err := ensureSqliteDatabaseDir(filepath.Join(filePath, "data.db"))
require.Error(t, err)
})
}
func TestConvertSqlitePragmaArgs(t *testing.T) {
tests := []struct {
name string

View File

@@ -89,7 +89,8 @@ func defaultConfig() EnvConfigSchema {
AppEnv: AppEnvProduction,
LogLevel: "info",
DbProvider: "sqlite",
FileBackend: "fs",
FileBackend: "filesystem",
FileBackend: "filesystem",
AppURL: AppUrl,
Port: "1411",
Host: "0.0.0.0",
@@ -164,12 +165,12 @@ func ValidateEnvConfig(config *EnvConfigSchema) error {
switch config.FileBackend {
case "s3", "database":
case "", "fs":
case "", "filesystem":
if config.UploadPath == "" {
config.UploadPath = defaultFsUploadPath
}
default:
return errors.New("invalid FILE_BACKEND value. Must be 'fs', 'database', or 's3'")
return errors.New("invalid FILE_BACKEND value. Must be 'filesystem', 'database', or 's3'")
}
// Validate LOCAL_IPV6_RANGES

View File

@@ -153,12 +153,12 @@ func TestParseEnvConfig(t *testing.T) {
EnvConfig = defaultConfig()
t.Setenv("DB_CONNECTION_STRING", "file:test.db")
t.Setenv("APP_URL", "http://localhost:3000")
t.Setenv("FILE_BACKEND", "FS")
t.Setenv("FILE_BACKEND", "FILESYSTEM")
t.Setenv("UPLOAD_PATH", "")
err := parseAndValidateEnvConfig(t)
require.NoError(t, err)
assert.Equal(t, "fs", EnvConfig.FileBackend)
assert.Equal(t, "filesystem", EnvConfig.FileBackend)
assert.Equal(t, defaultFsUploadPath, EnvConfig.UploadPath)
})

View File

@@ -8,7 +8,7 @@ import (
)
var (
TypeFileSystem = "fs"
TypeFileSystem = "filesystem"
TypeS3 = "s3"
)