package datamysql import ( "database/sql" "fmt" "sync" "time" "bitbucket.org/nemt/nemt-portal-api/domain/contract" "bitbucket.org/nemt/nemt-portal-api/infra/config" "bitbucket.org/nemt/nemt-portal-api/infra/errors" "github.com/go-sql-driver/mysql" ) var ( instance *Conn once sync.Once connErr error ) // Conn is the MySQL connection manager type Conn struct { db *sql.DB users *userRepo rides *rideRepo visit *visitRepo provider *providerRepo notification *notificationRepo profile *profileRepo organization *organizationRepo } // Begin starts a transaction func (c *Conn) Begin() (contract.TransactionManager, error) { tx, err := c.db.Begin() if err != nil { return nil, errors.Wrap(err) } return newTransaction(tx), nil } // Close closes the db connection func (c *Conn) Close() (err error) { return c.db.Close() } // Users returns the users set func (c *Conn) Users() contract.UserRepo { return c.users } // Rides returns the rides set func (c *Conn) Rides() contract.RideRepo { return c.rides } // Visits returns the rides set func (c *Conn) Visits() contract.VisitRepo { return c.visit } // Provider returns the rides set func (c *Conn) Provider() contract.ProviderRepo { return c.provider } // Provider returns the rides set func (c *Conn) Profile() contract.ProfileRepo { return c.profile } // Provider returns the rides set func (c *Conn) Notification() contract.NotificationRepo { return c.notification } // Provider returns the rides set func (c *Conn) Organization() contract.OrganizationRepo { return c.organization } // Instance returns an instance of a DataManager func Instance(cfg *config.Config) (contract.DataManager, error) { once.Do(func() { db, err := sql.Open("mysql", getMySQLConfig(cfg).FormatDSN()) if err != nil { connErr = errors.Wrap(err) return } err = db.Ping() if err != nil { connErr = errors.Wrap(err) return } connMaxLifetime := time.Duration(cfg.DB.MaxLifeInMinutes) * time.Minute db.SetConnMaxLifetime(connMaxLifetime) db.SetMaxIdleConns(cfg.DB.MaxIdleConns) db.SetMaxOpenConns(cfg.DB.MaxOpenConns) instance = new(Conn) instance.db = db instance.users = newUserRepo(db) instance.rides = newRideRepo(db) instance.visit = newVisitRepo(db) instance.provider = newProviderRepo(db) instance.notification = newNotificationRepo(db) instance.profile = newProfileRepo(db) instance.organization = newOrganizationRepo(db) }) return instance, connErr } // getMySQLConfig returns the configuration for MySQL driver func getMySQLConfig(cfg *config.Config) *mysql.Config { loc, _ := time.LoadLocation("UTC") return &mysql.Config{ Net: "tcp", Addr: fmt.Sprintf("%s:%d", cfg.DB.Host, cfg.DB.Port), DBName: cfg.DB.Name, User: cfg.DB.User, Passwd: cfg.DB.Pass, ParseTime: true, Strict: true, Loc: loc, } }