github.com/safedep/dry@v0.0.0-20241016050132-a15651f0548b/db/url.go (about)

     1  package db
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"net/url"
     7  	"os"
     8  )
     9  
    10  const (
    11  	databaseDSNEnvKey          = "DATABASE_URL"
    12  	databaseTestDSNEnvKey      = "DATABASE_TEST_URL"
    13  	databaseMigrationDSNEnvKey = "SCHEMA_MIGRATION_DATABASE_URL"
    14  )
    15  
    16  var (
    17  	errDatabaseDSNNotSet     = errors.New("database DSN environment variable not set")
    18  	errDatabaseDSNEmpty      = errors.New("database DSN environment variable is empty")
    19  	errDatabaseSchemeInvalid = errors.New("database DSN scheme is empty")
    20  )
    21  
    22  // DatabaseURL returns the DSN to connect to the database
    23  // using a conventional environment variable.
    24  func DatabaseURL() (string, error) {
    25  	return getDSNFromEnv(databaseDSNEnvKey)
    26  }
    27  
    28  // DatabaseTestURL returns the DSN to connect to the test database
    29  // using a conventional environment variable.
    30  func DatabaseTestURL() (string, error) {
    31  	return getDSNFromEnv(databaseTestDSNEnvKey)
    32  }
    33  
    34  // DatabaseMigrationURL returns the DSN to connect to the database
    35  // for schema migration using a conventional environment variable.
    36  // If the schema migration DSN is not set, it will fallback to the
    37  // regular database DSN.
    38  func DatabaseMigrationURL() (string, error) {
    39  	dsn, err := getDSNFromEnv(databaseMigrationDSNEnvKey)
    40  	if err != nil {
    41  		return DatabaseURL()
    42  	}
    43  
    44  	return dsn, err
    45  }
    46  
    47  func getDSNFromEnv(key string) (string, error) {
    48  	dsn, ok := os.LookupEnv(key)
    49  	if !ok {
    50  		return "", errDatabaseDSNNotSet
    51  	}
    52  
    53  	if dsn == "" {
    54  		return "", errDatabaseDSNEmpty
    55  	}
    56  
    57  	parsedDSN, err := url.Parse(dsn)
    58  	if err != nil {
    59  		return "", fmt.Errorf("failed to parse database DSN: %w", err)
    60  	}
    61  
    62  	if parsedDSN.Scheme == "" {
    63  		return "", errDatabaseSchemeInvalid
    64  	}
    65  
    66  	return dsn, nil
    67  }