2020-08-06 20:58:47 +03:00
|
|
|
package driver
|
|
|
|
|
|
|
|
import (
|
2023-08-12 21:54:14 +03:00
|
|
|
"log/slog"
|
2020-08-06 20:58:47 +03:00
|
|
|
"sync"
|
|
|
|
|
2023-08-12 21:54:14 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/lg/lga"
|
2020-08-06 20:58:47 +03:00
|
|
|
|
2020-08-23 13:42:15 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/core/errz"
|
2020-08-06 20:58:47 +03:00
|
|
|
"github.com/neilotoole/sq/libsq/source"
|
|
|
|
)
|
|
|
|
|
|
|
|
// NewRegistry returns a new Registry instance that provides
|
|
|
|
// access to driver implementations. Note that Registry
|
2020-08-12 21:24:01 +03:00
|
|
|
// implements Provider.
|
2023-04-02 22:49:45 +03:00
|
|
|
func NewRegistry(log *slog.Logger) *Registry {
|
2020-08-06 20:58:47 +03:00
|
|
|
return &Registry{
|
|
|
|
log: log,
|
2023-04-22 06:36:32 +03:00
|
|
|
providers: map[source.DriverType]Provider{},
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Registry provides access to driver implementations.
|
|
|
|
type Registry struct {
|
2023-04-02 22:49:45 +03:00
|
|
|
log *slog.Logger
|
2020-08-06 20:58:47 +03:00
|
|
|
mu sync.Mutex
|
2023-04-22 06:36:32 +03:00
|
|
|
providers map[source.DriverType]Provider
|
|
|
|
types []source.DriverType
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// AddProvider registers the provider for the specified driver type.
|
|
|
|
// This method has no effect if there's already a provider for typ.
|
2023-04-22 06:36:32 +03:00
|
|
|
func (r *Registry) AddProvider(typ source.DriverType, p Provider) {
|
2020-08-06 20:58:47 +03:00
|
|
|
r.mu.Lock()
|
|
|
|
defer r.mu.Unlock()
|
|
|
|
|
|
|
|
if existingType, ok := r.providers[typ]; ok {
|
2023-04-02 22:49:45 +03:00
|
|
|
r.log.Warn("failed to add driver provider (%T) for driver type %s: provider (%T) already registered", p, typ,
|
2022-12-18 05:43:53 +03:00
|
|
|
existingType)
|
2020-08-06 20:58:47 +03:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
r.types = append(r.types, typ)
|
|
|
|
r.providers[typ] = p
|
|
|
|
}
|
|
|
|
|
2020-08-09 16:46:46 +03:00
|
|
|
// ProviderFor returns the provider for typ, or nil if no
|
|
|
|
// registered provider.
|
2023-04-22 06:36:32 +03:00
|
|
|
func (r *Registry) ProviderFor(typ source.DriverType) Provider {
|
2020-08-06 20:58:47 +03:00
|
|
|
r.mu.Lock()
|
|
|
|
defer r.mu.Unlock()
|
|
|
|
|
2020-08-12 21:24:01 +03:00
|
|
|
p := r.providers[typ]
|
2020-08-09 16:46:46 +03:00
|
|
|
return p
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
// DriverFor implements Provider.
|
2023-04-22 06:36:32 +03:00
|
|
|
func (r *Registry) DriverFor(typ source.DriverType) (Driver, error) {
|
2020-08-06 20:58:47 +03:00
|
|
|
r.mu.Lock()
|
|
|
|
defer r.mu.Unlock()
|
|
|
|
|
|
|
|
p, ok := r.providers[typ]
|
|
|
|
if !ok {
|
2023-04-02 22:49:45 +03:00
|
|
|
return nil, errz.Errorf("no registered driver for {%s}", typ)
|
2020-08-06 20:58:47 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
return p.DriverFor(typ)
|
|
|
|
}
|
|
|
|
|
2023-06-13 19:06:18 +03:00
|
|
|
// SQLDriverFor for is a convenience method for getting a SQLDriver.
|
|
|
|
func (r *Registry) SQLDriverFor(typ source.DriverType) (SQLDriver, error) {
|
|
|
|
drvr, err := r.DriverFor(typ)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
sqlDrvr, ok := drvr.(SQLDriver)
|
|
|
|
if !ok {
|
|
|
|
return nil, errz.Errorf("driver %T is not of type %T", drvr, sqlDrvr)
|
|
|
|
}
|
|
|
|
|
|
|
|
return sqlDrvr, nil
|
|
|
|
}
|
|
|
|
|
2020-08-06 20:58:47 +03:00
|
|
|
// DriversMetadata returns metadata for each registered driver type.
|
|
|
|
func (r *Registry) DriversMetadata() []Metadata {
|
|
|
|
var md []Metadata
|
|
|
|
for _, typ := range r.types {
|
|
|
|
drv, err := r.DriverFor(typ)
|
|
|
|
if err != nil {
|
|
|
|
// Should never happen
|
2023-08-12 21:54:14 +03:00
|
|
|
r.log.Error("Error getting driver", lga.Type, typ, lga.Err, err)
|
2020-08-06 20:58:47 +03:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
md = append(md, drv.DriverMetadata())
|
|
|
|
}
|
|
|
|
|
|
|
|
return md
|
|
|
|
}
|
|
|
|
|
|
|
|
// Drivers returns the registered drivers.
|
|
|
|
func (r *Registry) Drivers() []Driver {
|
|
|
|
var drvrs []Driver
|
2023-08-12 21:54:14 +03:00
|
|
|
|
2020-08-06 20:58:47 +03:00
|
|
|
for _, typ := range r.types {
|
|
|
|
drvr, err := r.DriverFor(typ)
|
|
|
|
if err != nil {
|
|
|
|
// Should never happen
|
2023-08-12 21:54:14 +03:00
|
|
|
r.log.Error("Error getting driver", lga.Type, typ, lga.Err, err)
|
2020-08-06 20:58:47 +03:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
drvrs = append(drvrs, drvr)
|
|
|
|
}
|
|
|
|
|
|
|
|
return drvrs
|
|
|
|
}
|