162 lines
6.6 KiB
Go
162 lines
6.6 KiB
Go
// internal/config/leveldb.go
|
|
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"codeberg.org/mapleopentech/monorepo/native/desktop/maplefile/pkg/storage/leveldb"
|
|
)
|
|
|
|
// LevelDB support functions - desktop-specific databases
|
|
// These functions return errors instead of using log.Fatalf to allow proper error handling.
|
|
//
|
|
// Storage is organized as follows:
|
|
// - Global storage (session): {appDir}/session/
|
|
// - User-specific storage: {appDir}/users/{emailHash}/{dbName}/
|
|
//
|
|
// This ensures:
|
|
// 1. Different users have isolated data
|
|
// 2. Dev and production modes have separate directories ({appName} vs {appName}-dev)
|
|
// 3. Email addresses are not exposed in directory names (hashed)
|
|
|
|
// getAppDir returns the application data directory path, creating it if needed.
|
|
// Uses 0700 permissions for security (owner read/write/execute only).
|
|
// The directory name is mode-aware: "maplefile-dev" for dev mode, "maplefile" for production.
|
|
func getAppDir() (string, error) {
|
|
configDir, err := os.UserConfigDir()
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to get user config directory: %w", err)
|
|
}
|
|
|
|
appName := GetAppName()
|
|
appDir := filepath.Join(configDir, appName)
|
|
|
|
// Ensure the directory exists with restrictive permissions
|
|
if err := os.MkdirAll(appDir, 0700); err != nil {
|
|
return "", fmt.Errorf("failed to create app directory: %w", err)
|
|
}
|
|
|
|
return appDir, nil
|
|
}
|
|
|
|
// getUserDir returns the user-specific data directory, creating it if needed.
|
|
// Returns an error if userEmail is empty (no user logged in).
|
|
func getUserDir(userEmail string) (string, error) {
|
|
if userEmail == "" {
|
|
return "", fmt.Errorf("no user email provided - user must be logged in")
|
|
}
|
|
|
|
appName := GetAppName()
|
|
userDir, err := GetUserSpecificDataDir(appName, userEmail)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to get user data directory: %w", err)
|
|
}
|
|
|
|
return userDir, nil
|
|
}
|
|
|
|
// =============================================================================
|
|
// GLOBAL STORAGE PROVIDERS (not user-specific)
|
|
// =============================================================================
|
|
|
|
// NewLevelDBConfigurationProviderForSession returns a LevelDB configuration provider for user sessions.
|
|
// Session storage is GLOBAL (not per-user) because it stores the current login session.
|
|
func NewLevelDBConfigurationProviderForSession() (leveldb.LevelDBConfigurationProvider, error) {
|
|
appDir, err := getAppDir()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("session storage: %w", err)
|
|
}
|
|
return leveldb.NewLevelDBConfigurationProvider(appDir, "session"), nil
|
|
}
|
|
|
|
// =============================================================================
|
|
// USER-SPECIFIC STORAGE PROVIDERS
|
|
// These require a logged-in user's email to determine the storage path.
|
|
// =============================================================================
|
|
|
|
// NewLevelDBConfigurationProviderForLocalFilesWithUser returns a LevelDB configuration provider
|
|
// for local file metadata, scoped to a specific user.
|
|
func NewLevelDBConfigurationProviderForLocalFilesWithUser(userEmail string) (leveldb.LevelDBConfigurationProvider, error) {
|
|
userDir, err := getUserDir(userEmail)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("local files storage: %w", err)
|
|
}
|
|
return leveldb.NewLevelDBConfigurationProvider(userDir, "local_files"), nil
|
|
}
|
|
|
|
// NewLevelDBConfigurationProviderForSyncStateWithUser returns a LevelDB configuration provider
|
|
// for sync state, scoped to a specific user.
|
|
func NewLevelDBConfigurationProviderForSyncStateWithUser(userEmail string) (leveldb.LevelDBConfigurationProvider, error) {
|
|
userDir, err := getUserDir(userEmail)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("sync state storage: %w", err)
|
|
}
|
|
return leveldb.NewLevelDBConfigurationProvider(userDir, "sync_state"), nil
|
|
}
|
|
|
|
// NewLevelDBConfigurationProviderForCacheWithUser returns a LevelDB configuration provider
|
|
// for local cache, scoped to a specific user.
|
|
func NewLevelDBConfigurationProviderForCacheWithUser(userEmail string) (leveldb.LevelDBConfigurationProvider, error) {
|
|
userDir, err := getUserDir(userEmail)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cache storage: %w", err)
|
|
}
|
|
return leveldb.NewLevelDBConfigurationProvider(userDir, "cache"), nil
|
|
}
|
|
|
|
// NewLevelDBConfigurationProviderForUserDataWithUser returns a LevelDB configuration provider
|
|
// for user-specific data, scoped to a specific user.
|
|
func NewLevelDBConfigurationProviderForUserDataWithUser(userEmail string) (leveldb.LevelDBConfigurationProvider, error) {
|
|
userDir, err := getUserDir(userEmail)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("user data storage: %w", err)
|
|
}
|
|
return leveldb.NewLevelDBConfigurationProvider(userDir, "user_data"), nil
|
|
}
|
|
|
|
// =============================================================================
|
|
// LEGACY FUNCTIONS (deprecated - use user-specific versions instead)
|
|
// These exist for backward compatibility during migration.
|
|
// =============================================================================
|
|
|
|
// NewLevelDBConfigurationProviderForCache returns a LevelDB configuration provider for local cache.
|
|
// Deprecated: Use NewLevelDBConfigurationProviderForCacheWithUser instead.
|
|
func NewLevelDBConfigurationProviderForCache() (leveldb.LevelDBConfigurationProvider, error) {
|
|
appDir, err := getAppDir()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("cache storage: %w", err)
|
|
}
|
|
return leveldb.NewLevelDBConfigurationProvider(appDir, "cache"), nil
|
|
}
|
|
|
|
// NewLevelDBConfigurationProviderForLocalFiles returns a LevelDB configuration provider for local file metadata.
|
|
// Deprecated: Use NewLevelDBConfigurationProviderForLocalFilesWithUser instead.
|
|
func NewLevelDBConfigurationProviderForLocalFiles() (leveldb.LevelDBConfigurationProvider, error) {
|
|
appDir, err := getAppDir()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("local files storage: %w", err)
|
|
}
|
|
return leveldb.NewLevelDBConfigurationProvider(appDir, "local_files"), nil
|
|
}
|
|
|
|
// NewLevelDBConfigurationProviderForSyncState returns a LevelDB configuration provider for sync state.
|
|
// Deprecated: Use NewLevelDBConfigurationProviderForSyncStateWithUser instead.
|
|
func NewLevelDBConfigurationProviderForSyncState() (leveldb.LevelDBConfigurationProvider, error) {
|
|
appDir, err := getAppDir()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("sync state storage: %w", err)
|
|
}
|
|
return leveldb.NewLevelDBConfigurationProvider(appDir, "sync_state"), nil
|
|
}
|
|
|
|
// NewLevelDBConfigurationProviderForUser returns a LevelDB configuration provider for user data.
|
|
// Deprecated: Use NewLevelDBConfigurationProviderForUserDataWithUser instead.
|
|
func NewLevelDBConfigurationProviderForUser() (leveldb.LevelDBConfigurationProvider, error) {
|
|
appDir, err := getAppDir()
|
|
if err != nil {
|
|
return nil, fmt.Errorf("user storage: %w", err)
|
|
}
|
|
return leveldb.NewLevelDBConfigurationProvider(appDir, "user"), nil
|
|
}
|