github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/health/checks/mysql.go (about) 1 package checks 2 3 import ( 4 "context" 5 "database/sql" 6 "fmt" 7 8 _ "github.com/go-sql-driver/mysql" // import mysql driver 9 ) 10 11 type MySQLCheck struct { 12 Ctx context.Context 13 ConnectionString string 14 DB *sql.DB 15 Error error 16 } 17 18 func NewMySQLCheck(ctx context.Context, db *sql.DB, connectionString string) MySQLCheck { 19 return MySQLCheck{ 20 Ctx: ctx, 21 ConnectionString: connectionString, 22 DB: db, 23 Error: nil, 24 } 25 } 26 27 func CheckMySQLStatus(ctx context.Context, db *sql.DB, connectionString string) error { 28 check := NewMySQLCheck(ctx, db, connectionString) 29 return check.CheckStatus() 30 } 31 32 func (check *MySQLCheck) CheckbyConnectionString() error { 33 34 defer func() { 35 if r := recover(); r != nil { 36 return 37 } 38 }() 39 40 var checkErr error 41 checkErr = nil 42 43 ctx := check.Ctx 44 db, err := sql.Open("mysql", check.ConnectionString) 45 if err != nil { 46 checkErr = fmt.Errorf("MySQL health check failed on connect: %w", err) 47 check.Error = checkErr 48 return checkErr 49 } 50 defer func() { 51 defer func() { 52 if r := recover(); r != nil { 53 return 54 } 55 }() 56 // override checkErr only if there were no other errors 57 if cerr := db.Close(); cerr != nil && checkErr == nil { 58 checkErr = fmt.Errorf("MySQL health check failed on connection closing: %w", cerr) 59 check.Error = checkErr 60 return 61 } 62 }() 63 64 if err = db.PingContext(ctx); err != nil { 65 checkErr = fmt.Errorf("MySQL health check failed on ping: %w", err) 66 check.Error = checkErr 67 return checkErr 68 } 69 70 rows, err := db.QueryContext(ctx, `SELECT VERSION()`) 71 if err != nil { 72 checkErr = fmt.Errorf("MySQL health check failed on select: %w", err) 73 check.Error = checkErr 74 return checkErr 75 } 76 defer func() { 77 // override checkErr only if there were no other errors 78 if err = rows.Close(); err != nil && checkErr == nil { 79 checkErr = fmt.Errorf("MySQL health check failed on rows closing: %w", err) 80 check.Error = checkErr 81 return 82 } 83 }() 84 85 return nil 86 87 } 88 89 func (check *MySQLCheck) CheckStatus() error { 90 defer func() { 91 if err := recover(); err != nil { 92 check.Error = fmt.Errorf("MySQL health check failed on connect: %w", err) 93 return 94 } 95 }() 96 97 ctx := check.Ctx 98 db := check.DB 99 err := db.PingContext(ctx) 100 if err != nil { 101 check.Error = fmt.Errorf("MySQL health check failed on ping: %w", err) 102 return check.Error 103 } 104 rows, err := db.QueryContext(ctx, `SELECT VERSION()`) 105 defer rows.Close() 106 107 if err != nil { 108 check.Error = fmt.Errorf("MySQL health check failed on select: %w", err) 109 return check.Error 110 } 111 112 err = rows.Close() 113 if err != nil { 114 check.Error = fmt.Errorf("MySQL health check failed on rows closing: %w", err) 115 return check.Error 116 } 117 118 return nil 119 }