Captain Hook - Web hook server
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

125 lines
2.6 KiB

  1. package main
  2. import (
  3. "database/sql"
  4. "fmt"
  5. "io/ioutil"
  6. "log"
  7. "os"
  8. "strconv"
  9. "strings"
  10. "time"
  11. _ "github.com/go-sql-driver/mysql"
  12. "github.com/pkg/errors"
  13. )
  14. func connectDB() (*sql.DB, error) {
  15. // Get user credentials
  16. user, exists := os.LookupEnv("MYSQL_USER")
  17. checkExists(exists, "Couldn't find database user")
  18. password, exists := os.LookupEnv("MYSQL_PASSWORD")
  19. checkExists(exists, "Couldn't find database password")
  20. // Get database params
  21. dbServer, exists := os.LookupEnv("MYSQL_SERVER")
  22. checkExists(exists, "Couldn't find database server")
  23. dbPort, exists := os.LookupEnv("MYSQL_PORT")
  24. checkExists(exists, "Couldn't find database port")
  25. dbName, exists := os.LookupEnv("MYSQL_DATABASE")
  26. checkExists(exists, "Couldn't find database name")
  27. connectionString := fmt.Sprintf(
  28. "%s:%s@tcp(%s:%s)/%s",
  29. user,
  30. password,
  31. dbServer,
  32. dbPort,
  33. dbName,
  34. )
  35. // Check how many times to try the db before quitting
  36. attemptsStr, exists := os.LookupEnv("DB_ATTEMPTS")
  37. if !exists {
  38. attemptsStr = "5"
  39. }
  40. attempts, err := strconv.Atoi(attemptsStr)
  41. if err != nil {
  42. attempts = 5
  43. }
  44. timeoutStr, exists := os.LookupEnv("DB_CONNECTION_TIMEOUT")
  45. if !exists {
  46. timeoutStr = "5"
  47. }
  48. timeout, err := strconv.Atoi(timeoutStr)
  49. if err != nil {
  50. timeout = 5
  51. }
  52. db, err = sql.Open("mysql", connectionString)
  53. if err != nil {
  54. return db, err
  55. }
  56. for i := 1; i <= attempts; i++ {
  57. //// DEBUG: Making sure table is good
  58. // if err := dropDB(db); err != nil {
  59. // log.Fatal(err)
  60. // }
  61. // Create database if it doesn't exist
  62. err = createDB(db)
  63. if err != nil {
  64. // Check to see if the error is a connection issue
  65. if !strings.HasPrefix(err.Error(), "dial") {
  66. return db, err
  67. }
  68. if i != attempts {
  69. log.Printf(
  70. "WARNING: Could not connect to db on attempt %d. Trying again in %d seconds.\n",
  71. i,
  72. timeout,
  73. )
  74. } else {
  75. return db, errors.Errorf("Could not connect to db after %d attempts\n", attempts)
  76. }
  77. time.Sleep(time.Duration(timeout) * time.Second)
  78. } else {
  79. // No error to worry about
  80. break
  81. }
  82. }
  83. log.Println("Connection to db succeeded!")
  84. return db, nil
  85. }
  86. func pingDB(db *sql.DB) {
  87. for {
  88. if err := db.Ping(); err != nil {
  89. log.Println("Failed to connect to database, Connection died")
  90. }
  91. time.Sleep(time.Second*5)
  92. }
  93. }
  94. func execSQL(db *sql.DB, name string) error {
  95. b, err := ioutil.ReadFile(name)
  96. if err != nil {
  97. return err
  98. }
  99. statement, err := db.Prepare(string(b))
  100. if err != nil {
  101. return err
  102. }
  103. statement.Exec()
  104. return nil
  105. }
  106. func createDB(db *sql.DB) error {
  107. return execSQL(db, "sql/setup.sql")
  108. }
  109. func dropDB(db *sql.DB) error {
  110. return execSQL(db, "sql/drop.sql")
  111. }