package main import ( "encoding/json" "expvar" "log" "net/url" "os" "geeks-accelerator/oss/saas-starter-kit/example-project/internal/platform/flag" "geeks-accelerator/oss/saas-starter-kit/example-project/internal/schema" "github.com/kelseyhightower/envconfig" "github.com/lib/pq" _ "github.com/lib/pq" sqltrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/database/sql" sqlxtrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/jmoiron/sqlx" ) // build is the git version of this program. It is set using build flags in the makefile. var build = "develop" // service is the name of the program used for logging, tracing and the // the prefix used for loading env variables // ie: export SCHEMA_ENV=dev var service = "SCHEMA" func main() { // ========================================================================= // Logging log := log.New(os.Stdout, service+" : ", log.LstdFlags|log.Lmicroseconds|log.Lshortfile) // ========================================================================= // Configuration var cfg struct { Env string `default:"dev" envconfig:"ENV"` DB struct { Host string `default:"127.0.0.1:5433" envconfig:"HOST"` User string `default:"postgres" envconfig:"USER"` Pass string `default:"postgres" envconfig:"PASS" json:"-"` // don't print Database string `default:"shared" envconfig:"DATABASE"` Driver string `default:"postgres" envconfig:"DRIVER"` Timezone string `default:"utc" envconfig:"TIMEZONE"` DisableTLS bool `default:"true" envconfig:"DISABLE_TLS"` } } // For additional details refer to https://github.com/kelseyhightower/envconfig if err := envconfig.Process(service, &cfg); err != nil { log.Fatalf("main : Parsing Config : %v", err) } if err := flag.Process(&cfg); err != nil { if err != flag.ErrHelp { log.Fatalf("main : Parsing Command Line : %v", err) } return // We displayed help. } // ========================================================================= // Log App Info // Print the build version for our logs. Also expose it under /debug/vars. expvar.NewString("build").Set(build) log.Printf("main : Started : Application Initializing version %q", build) defer log.Println("main : Completed") // Print the config for our logs. It's important to any credentials in the config // that could expose a security risk are excluded from being json encoded by // applying the tag `json:"-"` to the struct var. { cfgJSON, err := json.MarshalIndent(cfg, "", " ") if err != nil { log.Fatalf("main : Marshalling Config to JSON : %v", err) } log.Printf("main : Config : %v\n", string(cfgJSON)) } // ========================================================================= // Start Database var dbUrl url.URL { // Query parameters. var q url.Values = make(map[string][]string) // Handle SSL Mode if cfg.DB.DisableTLS { q.Set("sslmode", "disable") } else { q.Set("sslmode", "require") } q.Set("timezone", cfg.DB.Timezone) // Construct url. dbUrl = url.URL{ Scheme: cfg.DB.Driver, User: url.UserPassword(cfg.DB.User, cfg.DB.Pass), Host: cfg.DB.Host, Path: cfg.DB.Database, RawQuery: q.Encode(), } } // Register informs the sqlxtrace package of the driver that we will be using in our program. // It uses a default service name, in the below case "postgres.db". To use a custom service // name use RegisterWithServiceName. sqltrace.Register(cfg.DB.Driver, &pq.Driver{}, sqltrace.WithServiceName(service)) masterDb, err := sqlxtrace.Open(cfg.DB.Driver, dbUrl.String()) if err != nil { log.Fatalf("main : Register DB : %s : %v", cfg.DB.Driver, err) } defer masterDb.Close() // ========================================================================= // Start Migrations // Execute the migrations if err = schema.Migrate(masterDb, log); err != nil { log.Fatalf("main : Migrate : %v", err) } log.Printf("main : Migrate : Completed") }