Files
OpenFlare/backend/core/extpoints/migration.go
T

95 lines
2.4 KiB
Go

// Copyright 2026 Arctel.net
// SPDX-License-Identifier: Apache-2.0
// Package extpoints defines extension points for router, migrations, tasks, schedules, and settings.
package extpoints
import (
"io/fs"
"sync"
)
// MigrationEntry contains the migration filesystem and configuration for a plugin.
type MigrationEntry struct {
PluginID string
FS fs.FS
Dir string
}
// MigrationExtension defines the interface for registering and querying plugin migrations.
type MigrationExtension interface {
Register(pluginID string, fsys fs.FS, dir ...string)
Unregister(pluginID string) bool
Entries() []MigrationEntry
Get(pluginID string) (MigrationEntry, bool)
}
// MigrationRegistry implements MigrationExtension.
type MigrationRegistry struct {
mu sync.RWMutex
entries []MigrationEntry
lookup map[string]MigrationEntry
}
// NewMigrationRegistry creates a new MigrationRegistry.
func NewMigrationRegistry() *MigrationRegistry {
return &MigrationRegistry{
lookup: make(map[string]MigrationEntry),
}
}
// Register registers an embedded migration filesystem for a plugin.
func (m *MigrationRegistry) Register(pluginID string, fsys fs.FS, dir ...string) {
m.mu.Lock()
defer m.mu.Unlock()
migrationDir := "migrations"
if len(dir) > 0 && dir[0] != "" {
migrationDir = dir[0]
}
entry := MigrationEntry{
PluginID: pluginID,
FS: fsys,
Dir: migrationDir,
}
// If entry already exists, update in-place; otherwise append
if _, exists := m.lookup[pluginID]; exists {
for i, e := range m.entries {
if e.PluginID == pluginID {
m.entries[i] = entry
break
}
}
} else {
m.entries = append(m.entries, entry)
}
m.lookup[pluginID] = entry
}
// Unregister removes a registered migration entry by plugin ID.
func (m *MigrationRegistry) Unregister(pluginID string) bool {
return unregisterEntry(&m.mu, m.lookup, &m.entries, pluginID, func(e MigrationEntry) bool {
return e.PluginID == pluginID
})
}
// Entries returns a copy of all registered migration entries in registration order.
func (m *MigrationRegistry) Entries() []MigrationEntry {
m.mu.RLock()
defer m.mu.RUnlock()
res := make([]MigrationEntry, len(m.entries))
copy(res, m.entries)
return res
}
// Get retrieves the migration entry for a specific plugin ID.
func (m *MigrationRegistry) Get(pluginID string) (MigrationEntry, bool) {
m.mu.RLock()
defer m.mu.RUnlock()
e, ok := m.lookup[pluginID]
return e, ok
}