munin/internal/store/speicher_sqlite.go

81 lines
2.9 KiB
Go

package store
import (
"context"
"errors"
"fmt"
"os"
"path/filepath"
)
// SQLiteSpeicher 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 SQLiteSpeicher struct {
controlPfad string // z.B. "<DATA_DIR>/control.db"
workspaceOrdner 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
// controlPfad leer lassen; OpenControl meldet dann einen Fehler.
func NewSQLite(controlPfad, workspaceOrdner string) *SQLiteSpeicher {
return &SQLiteSpeicher{controlPfad: controlPfad, workspaceOrdner: workspaceOrdner}
}
func (s *SQLiteSpeicher) OpenControl() (*ControlStore, error) {
if s.controlPfad == "" {
return nil, errors.New("SQLite-Speicher ohne Pfad zur Kontroll-Datenbank")
}
return OpenControl(s.controlPfad)
}
func (s *SQLiteSpeicher) OpenWorkspace(workspaceID string) (*Store, error) {
return Open(s.workspaceDatei(workspaceID))
}
// DeleteWorkspace entfernt die Workspace-Datei unwiederbringlich von der
// Platte — samt WAL/SHM-Nebendateien, die SQLite im laufenden Betrieb
// danebenlegt.
func (s *SQLiteSpeicher) DeleteWorkspace(workspaceID string) error {
pfad := s.workspaceDatei(workspaceID)
for _, endung := range []string{"", "-wal", "-shm"} {
if err := os.Remove(pfad + endung); err != nil && !os.IsNotExist(err) {
return fmt.Errorf("Workspace-Datei konnte nicht gelöscht werden: %w", err)
}
}
return nil
}
// PruefeKapazitaet: Jede SQLite-Datei hat ihre eigenen Verbindungen, eine
// gemeinsame Obergrenze gibt es nicht.
func (s *SQLiteSpeicher) PruefeKapazitaet(context.Context, int) error { return nil }
// Kapazitaet: SQLite kennt keine gemeinsame Grenze.
func (s *SQLiteSpeicher) Kapazitaet(context.Context) (Kapazitaet, error) {
return Kapazitaet{}, nil
}
// Ort 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 *SQLiteSpeicher) Ort(workspaceID string) string {
return filepath.Join(filepath.Base(s.workspaceOrdner), workspaceID+".db")
}
func (s *SQLiteSpeicher) Beschreibung() string {
return fmt.Sprintf("SQLite — Workspaces: %s, Kontrolle: %s", s.workspaceOrdner, s.controlPfad)
}
// Hinweise: Beim SQLite-Speicher gibt es beim Start nichts zu prüfen. Eine
// zu große WAL-Datei zeigt die Systemseite je Workspace (Store.Belegung).
func (s *SQLiteSpeicher) Hinweise() []string { return nil }
// Close: Der SQLite-Speicher hält selbst nichts offen.
func (s *SQLiteSpeicher) Close() error { return nil }
func (s *SQLiteSpeicher) workspaceDatei(workspaceID string) string {
return filepath.Join(s.workspaceOrdner, workspaceID+".db")
}