munin/internal/store/backend_sqlite.go
2026-10-19 10:13:56 +02:00

81 lines
2.8 KiB
Go

package store
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
)
// SQLiteBackend legt die Kontroll-Datenbank und jeden Workspace als eigene
// SQLite-Datei ab. Das ist der Standard und der bisherige Aufbau
// (AUSBAUSTUFEN.md 4.4).
type SQLiteBackend struct {
controlPath string // z.B. "<DATA_DIR>/control.db"
workspaceDir string // z.B. "<DATA_DIR>/workspaces", muss existieren
}
// NewSQLite legt einen SQLite-Speicher an. Der Workspace-Ordner muss bereits
// existieren — das übernimmt main.go beim Start.
//
// Wer nur Workspaces braucht (etwa ein Test des workspace.Manager), kann
// controlPath leer lassen; OpenControl meldet dann einen Fehler.
func NewSQLite(controlPath, workspaceDir string) *SQLiteBackend {
return &SQLiteBackend{controlPath: controlPath, workspaceDir: workspaceDir}
}
func (s *SQLiteBackend) OpenControl() (*ControlStore, error) {
if s.controlPath == "" {
return nil, errors.New("SQLite-Speicher ohne Pfad zur Kontroll-Datenbank")
}
return OpenControl(s.controlPath)
}
func (s *SQLiteBackend) OpenWorkspace(workspaceID string) (*Store, error) {
return Open(s.workspaceFile(workspaceID))
}
// DeleteWorkspace entfernt die Workspace-Datei unwiederbringlich von der
// Platte — samt WAL/SHM-Nebendateien, die SQLite im laufenden Betrieb
// danebenlegt.
func (s *SQLiteBackend) DeleteWorkspace(workspaceID string) error {
filePath := s.workspaceFile(workspaceID)
for _, suffix := range []string{"", "-wal", "-shm"} {
if err := os.Remove(filePath + suffix); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("Workspace-Datei konnte nicht gelöscht werden: %w", err)
}
}
return nil
}
// CheckCapacity: Jede SQLite-Datei hat ihre eigenen Verbindungen, eine
// gemeinsame Obergrenze gibt es nicht.
func (s *SQLiteBackend) CheckCapacity(context.Context, int) error { return nil }
// Capacity: SQLite kennt keine gemeinsame Grenze.
func (s *SQLiteBackend) Capacity(context.Context) (Capacity, error) {
return Capacity{}, nil
}
// Location nennt die Datei relativ zum Datenverzeichnis, z.B.
// "workspaces/mue9bh3x-1c0e1120.db" — der volle Pfad stünde schon im
// Startprotokoll und wäre in der Tabelle nur lang.
func (s *SQLiteBackend) Location(workspaceID string) string {
return filepath.Join(filepath.Base(s.workspaceDir), workspaceID+".db")
}
func (s *SQLiteBackend) Description() string {
return fmt.Sprintf("SQLite — Workspaces: %s, Kontrolle: %s", s.workspaceDir, s.controlPath)
}
// Hints: Beim SQLite-Speicher gibt es beim Start nichts zu prüfen. Eine
// zu große WAL-Datei zeigt die Systemseite je Workspace (Store.DiskUsage).
func (s *SQLiteBackend) Hints() []string { return nil }
// Close: Der SQLite-Speicher hält selbst nichts offen.
func (s *SQLiteBackend) Close() error { return nil }
func (s *SQLiteBackend) workspaceFile(workspaceID string) string {
return filepath.Join(s.workspaceDir, workspaceID+".db")
}