package db import ( "log" "os" "time" "github.com/pkg/errors" "gorm.io/driver/postgres" "gorm.io/driver/sqlite" "gorm.io/gorm" "gorm.io/gorm/logger" ) const ( // EnvDatabaseDriver is the key for the 'database driver' environment variable. EnvDatabaseDriver = "RUSHLINK_DATABASE_DRIVER" // EnvDatabasePath is the key for the 'database path' environment variable. EnvDatabasePath = "RUSHLINK_DATABASE_PATH" // EnvPostgresURL is the key for the 'postgresql URL' environment variable. EnvPostgresURL = "RUSHLINK_POSTGRES_URL" // EnvFileStorePath is the key for the environment variable locating the file store. EnvFileStorePath = "RUSHLINK_FILE_STORE_PATH" ) // Database is the main rushlink database type. // // Open a database using OpenDBFromEnvironment(). Closing is not necessary. // Only one instance of DB should exist in a program at any moment. type Database = gorm.DB var ( gormLogger logger.Interface = logger.New(log.New(os.Stdout, "\r\n", log.LstdFlags), logger.Config{ SlowThreshold: 50 * time.Millisecond, LogLevel: logger.Error, Colorful: true, }) gormConfig = gorm.Config{Logger: gormLogger} ) // OpenDBFromEnvironment tries to open an SQL database, described by func OpenDBFromEnvironment() (*Database, error) { const envNotSetMsg = "%v environment variable is not set" driver, prs := os.LookupEnv(EnvDatabaseDriver) if !prs { return nil, errors.Errorf(envNotSetMsg, EnvDatabaseDriver) } switch driver { case "sqlite": path, prs := os.LookupEnv(EnvDatabasePath) if !prs { return nil, errors.Errorf(envNotSetMsg, EnvDatabasePath) } db, err := gorm.Open(sqlite.Open(path), &gormConfig) if err != nil { return nil, err } return db, nil case "postgres": dsn, prs := os.LookupEnv(EnvPostgresURL) if !prs { return nil, errors.Errorf(envNotSetMsg, EnvPostgresURL) } db, err := gorm.Open(postgres.Open(dsn), &gormConfig) if err != nil { return nil, err } return db, nil default: return nil, errors.Errorf("RUSHLINK_DATABASE_DRIVER should be either 'sqlite' or 'postgres' (not '%v'), "+ "for more info see ", driver) } }