package internal import ( "database/sql" "fmt" "log" "os" "sync" "time" _ "github.com/go-sql-driver/mysql" "github.com/jmoiron/sqlx" ) type database struct { instance *sqlx.DB } type Database interface { GetInstance() *sqlx.DB Close() Query(stmt string) *sqlx.Rows Execute(stmt string) sql.Result FetchRows(stmt string, dest interface{}) } var ( instance *database = nil once sync.Once ) func initialize() { db, err := sqlx.Open("mysql", fmt.Sprintf( "%s:%s@tcp(%s)/%s", os.Getenv("MYSQL_USER"), os.Getenv("MYSQL_PASSWORD"), os.Getenv("MYSQL_HOST"), os.Getenv("MYSQL_DATABASE"))) db.SetConnMaxLifetime(time.Minute * 3) db.SetMaxOpenConns(3) db.SetMaxIdleConns(3) if err != nil { panic(err) } conErr := db.Ping() if conErr != nil { panic(conErr) } log.Println("Connection to db succeded") instance = &database{instance: db} } func InitDatabase() Database { if instance == nil { once.Do(initialize) } return instance } func (db *database) GetInstance() *sqlx.DB { return db.instance } func (db *database) Close() { defer log.Println("Connection to database was closed") err := db.instance.Close() if err != nil { return } } func (db *database) Query(stmt string) *sqlx.Rows { rows, err := db.instance.Queryx(stmt) if err != nil { return nil } return rows } func (db *database) Execute(stmt string) sql.Result { result, err := db.instance.Exec(stmt) if err != nil { log.Println(err) } return result } type FetchRowStruct []interface{} func (db *database) FetchRows(stmt string, dest interface{}) { err := db.instance.Select(dest, stmt) if err != nil { log.Println(err) } }