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  }