common.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. package common
  2. import (
  3. "context"
  4. "database/sql"
  5. "fmt"
  6. "io"
  7. "net/url"
  8. "github.com/amacneil/dbmate/pkg/dbmate"
  9. _ "github.com/amacneil/dbmate/pkg/driver/mysql"
  10. _ "github.com/amacneil/dbmate/pkg/driver/postgres"
  11. _ "github.com/amacneil/dbmate/pkg/driver/sqlite"
  12. "golang.org/x/exp/slices"
  13. )
  14. type Engine interface {
  15. Begin(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error)
  16. Close() error
  17. Exec(ctx context.Context, query string, args ...any) (sql.Result, error)
  18. Ping(context.Context) error
  19. Prepare(ctx context.Context, query string) (*sql.Stmt, error)
  20. Query(ctx context.Context, query string, args ...any) (*sql.Rows, error)
  21. QueryRow(ctx context.Context, query string, args ...any) *sql.Row
  22. Transaction(ctx context.Context, queries qFunc) error
  23. }
  24. func ParseUrl(dbURL string) (*url.URL, error) {
  25. databaseURL, err := url.Parse(dbURL)
  26. if err != nil {
  27. return nil, fmt.Errorf("unable to parse URL: %w", err)
  28. }
  29. if databaseURL.Scheme == "" {
  30. return nil, fmt.Errorf("protocol scheme is not defined")
  31. }
  32. protocols := []string{"mysql", "postgres", "postgresql", "sqlite", "sqlite3"}
  33. if !slices.Contains(protocols, databaseURL.Scheme) {
  34. return nil, fmt.Errorf("unsupported protocol scheme: %s", databaseURL.Scheme)
  35. }
  36. return databaseURL, nil
  37. }
  38. func OpenDB(databaseURL *url.URL, migrationsDir string) (*sql.DB, error) {
  39. mate := dbmate.New(databaseURL)
  40. mate.AutoDumpSchema = false
  41. mate.Log = io.Discard
  42. if migrationsDir != "" {
  43. mate.MigrationsDir = migrationsDir
  44. }
  45. driver, err := mate.GetDriver()
  46. if err != nil {
  47. return nil, fmt.Errorf("DB get driver error: %w", err)
  48. }
  49. if err := mate.CreateAndMigrate(); err != nil {
  50. return nil, fmt.Errorf("DB migration error: %w", err)
  51. }
  52. db, err := driver.Open()
  53. if err != nil {
  54. return nil, fmt.Errorf("DB open error: %w", err)
  55. }
  56. return db, nil
  57. }