github.com/icyphox/x@v0.0.355-0.20220311094250-029bd783e8b8/dbal/driver.go (about) 1 package dbal 2 3 import ( 4 "strings" 5 "sync" 6 7 "github.com/pkg/errors" 8 ) 9 10 var ( 11 drivers = make([]func() Driver, 0) 12 dmtx sync.Mutex 13 14 // ErrNoResponsibleDriverFound is returned when no driver was found for the provided DSN. 15 ErrNoResponsibleDriverFound = errors.New("dsn value requested an unknown driver") 16 ErrSQLiteSupportMissing = errors.New(`the DSN connection string looks like a SQLite connection, but SQLite support was not built into the binary. Please check if you have downloaded the correct binary or are using the correct Docker Image. Binary archives and Docker Images indicate SQLite support by appending the -sqlite suffix`) 17 ) 18 19 // Driver represents a driver 20 type Driver interface { 21 // CanHandle returns true if the driver is capable of handling the given DSN or false otherwise. 22 CanHandle(dsn string) bool 23 24 // Ping returns nil if the driver has connectivity and is healthy or an error otherwise. 25 Ping() error 26 } 27 28 // RegisterDriver registers a driver 29 func RegisterDriver(d func() Driver) { 30 dmtx.Lock() 31 drivers = append(drivers, d) 32 dmtx.Unlock() 33 } 34 35 // GetDriverFor returns a driver for the given DSN or ErrNoResponsibleDriverFound if no driver was found. 36 func GetDriverFor(dsn string) (Driver, error) { 37 for _, f := range drivers { 38 driver := f() 39 if driver.CanHandle(dsn) { 40 return driver, nil 41 } 42 } 43 44 if IsSQLite(dsn) { 45 return nil, ErrSQLiteSupportMissing 46 } 47 48 return nil, ErrNoResponsibleDriverFound 49 } 50 51 // IsSQLite returns true if the connection is a SQLite string. 52 func IsSQLite(dsn string) bool { 53 scheme := strings.Split(dsn, "://")[0] 54 return scheme == "sqlite" || scheme == "sqlite3" 55 }