81 lines
2.8 KiB
Go
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")
|
|
}
|