You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.4 KiB
93 lines
2.4 KiB
//go:build !(js && wasm) |
|
|
|
package database |
|
|
|
import ( |
|
"context" |
|
"sort" |
|
"sync" |
|
|
|
"lol.mleku.dev/errorf" |
|
) |
|
|
|
// DriverFactory is the signature for database driver factory functions. |
|
type DriverFactory func(ctx context.Context, cancel context.CancelFunc, cfg *DatabaseConfig) (Database, error) |
|
|
|
// DriverInfo contains metadata about a registered driver. |
|
type DriverInfo struct { |
|
Name string |
|
Description string |
|
Factory DriverFactory |
|
} |
|
|
|
var ( |
|
driversMu sync.RWMutex |
|
drivers = make(map[string]*DriverInfo) |
|
) |
|
|
|
// RegisterDriver registers a database driver with the given name and factory. |
|
// This is typically called from init() in the driver package. |
|
func RegisterDriver(name, description string, factory DriverFactory) { |
|
driversMu.Lock() |
|
defer driversMu.Unlock() |
|
drivers[name] = &DriverInfo{ |
|
Name: name, |
|
Description: description, |
|
Factory: factory, |
|
} |
|
} |
|
|
|
// GetDriver returns the factory for the named driver, or nil if not found. |
|
func GetDriver(name string) DriverFactory { |
|
driversMu.RLock() |
|
defer driversMu.RUnlock() |
|
if info, ok := drivers[name]; ok { |
|
return info.Factory |
|
} |
|
return nil |
|
} |
|
|
|
// HasDriver returns true if the named driver is registered. |
|
func HasDriver(name string) bool { |
|
driversMu.RLock() |
|
defer driversMu.RUnlock() |
|
_, ok := drivers[name] |
|
return ok |
|
} |
|
|
|
// ListDrivers returns a sorted list of registered driver names. |
|
func ListDrivers() []string { |
|
driversMu.RLock() |
|
defer driversMu.RUnlock() |
|
names := make([]string, 0, len(drivers)) |
|
for name := range drivers { |
|
names = append(names, name) |
|
} |
|
sort.Strings(names) |
|
return names |
|
} |
|
|
|
// ListDriversWithInfo returns information about all registered drivers. |
|
func ListDriversWithInfo() []*DriverInfo { |
|
driversMu.RLock() |
|
defer driversMu.RUnlock() |
|
infos := make([]*DriverInfo, 0, len(drivers)) |
|
for _, info := range drivers { |
|
infos = append(infos, info) |
|
} |
|
// Sort by name for consistent output |
|
sort.Slice(infos, func(i, j int) bool { |
|
return infos[i].Name < infos[j].Name |
|
}) |
|
return infos |
|
} |
|
|
|
// NewFromDriver creates a database using the named driver. |
|
// Returns an error if the driver is not registered. |
|
func NewFromDriver(ctx context.Context, cancel context.CancelFunc, driverName string, cfg *DatabaseConfig) (Database, error) { |
|
factory := GetDriver(driverName) |
|
if factory == nil { |
|
return nil, errorf.E("database driver %q not available; registered: %v", driverName, ListDrivers()) |
|
} |
|
return factory(ctx, cancel, cfg) |
|
}
|
|
|