Database: MySQL
SQLite here is for demonstration only. If you want a more production-ready database, try MySQL or mongoDB.
Switch to MySQL
- Install MySQL on your machine and start it.
Note: Remember to create indexes on tables based on your need in a production project.
- Add gorm's mysql dependency:
go get -u gorm.io/driver/mysql
- Update code.
Add infrastructure/database/mysql.go:
/*
Package database does all db persistence implementations.
*/
package database
import (
"context"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"literank.com/rest-books/domain/model"
)
type MySQLPersistence struct {
db *gorm.DB
}
func NewMySQLPersistence(dsn string) (*MySQLPersistence, error) {
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
return nil, err
}
// Auto Migrate the data structs
db.AutoMigrate(&model.Book{})
return &MySQLPersistence{db}, nil
}
func (s *MySQLPersistence) CreateBook(ctx context.Context, b *model.Book) (uint, error) {
if err := s.db.WithContext(ctx).Create(b).Error; err != nil {
return 0, err
}
return b.ID, nil
}
func (s *MySQLPersistence) UpdateBook(ctx context.Context, id uint, b *model.Book) error {
var book model.Book
if err := s.db.WithContext(ctx).First(&book, id).Error; err != nil {
return err
}
return s.db.WithContext(ctx).Model(book).Updates(b).Error
}
func (s *MySQLPersistence) DeleteBook(ctx context.Context, id uint) error {
return s.db.WithContext(ctx).Delete(&model.Book{}, id).Error
}
func (s *MySQLPersistence) GetBook(ctx context.Context, id uint) (*model.Book, error) {
var book model.Book
if err := s.db.WithContext(ctx).First(&book, id).Error; err != nil {
return nil, err
}
return &book, nil
}
func (s *MySQLPersistence) GetBooks(ctx context.Context) ([]*model.Book, error) {
books := make([]*model.Book, 0)
if err := s.db.WithContext(ctx).Find(&books).Error; err != nil {
return nil, err
}
return books, nil
}
Notice that the key difference is that we use mysql.Open(dsn)
instead of sqlite.Open(fileName)
in gorm.Open(mysql.Open(dsn), &gorm.Config{})
.
DSN stands for Data Source Name. It's a string that provides the necessary information for an application to connect to a specific database instance.
Add DSN
config item into the DBConfig
struct in infrastructure/config/config.go:
type DBConfig struct {
FileName string `json:"file_name" yaml:"file_name"`
+ DSN string `json:"dsn" yaml:"dsn"`
}
Update WireHelper
to switch the dependency in application/wire_helper.go:
@@ -8,11 +8,11 @@ import (
// WireHelper is the helper for dependency injection
type WireHelper struct {
- persistence *database.SQLitePersistence
+ persistence *database.MySQLPersistence
}
func NewWireHelper(c *config.Config) (*WireHelper, error) {
- db, err := database.NewSQLitePersistence(c.DB.FileName)
+ db, err := database.NewMySQLPersistence(c.DB.DSN)
if err != nil {
return nil, err
}
Put in a DSN
value in main.go:
@@ -15,6 +15,7 @@ func main() {
},
DB: config.DBConfig{
FileName: "test.db",
+ DSN: "test_user:test_pass@tcp(127.0.0.1:3306)/lr_book?charset=utf8mb4&parseTime=True&loc=Local",
},
}
// Prepare dependencies
Voila! Your api server is powered by MySQL now!