Implementing the repository pattern in Go with both in-memory and MySQL repositories

Implementing the repository pattern in Go with both in-memory and MySQL repositories
  1. – We define the User struct representing a user entity.
  2. – We define the UserRepository interface with methods for managing users.
  3. – We implement InMemoryUserRepository and MySQLUserRepository to provide in-memory and MySQL-based repositories, respectively.
  4. – NewInMemoryUserRepository and NewMySQLUserRepository are constructor functions for creating instances of the respective repositories.
  5. – We demonstrate how to use both repositories in the main function by inserting users, getting a user by ID, and getting all users.
package main import ( "database/sql" "errors" "fmt" _ "github.com/go-sql-driver/mysql"
) // User represents a user entity
type User struct { ID int Username string Email string
} // UserRepository defines the methods a user repository must implement
type UserRepository interface { Insert(user *User) error GetByID(id int) (*User, error) GetAll() ([]*User, error)
} // InMemoryUserRepository is an in-memory implementation of UserRepository
type InMemoryUserRepository struct { users []*User
} // NewInMemoryUserRepository creates a new instance of InMemoryUserRepository
func NewInMemoryUserRepository() *InMemoryUserRepository { return &InMemoryUserRepository{ users: make([]*User, 0), }
} // Insert inserts a new user into the repository
func (repo *InMemoryUserRepository) Insert(user *User) error { repo.users = append(repo.users, user) return nil
} // GetByID retrieves a user by its ID from the repository
func (repo *InMemoryUserRepository) GetByID(id int) (*User, error) { for _, user := range repo.users { if user.ID == id { return user, nil } } return nil, errors.New("user not found")
} // GetAll retrieves all users from the repository
func (repo *InMemoryUserRepository) GetAll() ([]*User, error) { return repo.users, nil
} // MySQLUserRepository is a MySQL implementation of UserRepository
type MySQLUserRepository struct { db *sql.DB
} // NewMySQLUserRepository creates a new instance of MySQLUserRepository
func NewMySQLUserRepository(dataSourceName string) (*MySQLUserRepository, error) { db, err := sql.Open("mysql", dataSourceName) if err != nil { return nil, err } return &MySQLUserRepository{ db: db, }, nil
} // Insert inserts a new user into the MySQL repository
func (repo *MySQLUserRepository) Insert(user *User) error { _, err := repo.db.Exec("INSERT INTO users (id, username, email) VALUES (?, ?, ?)", user.ID, user.Username, user.Email) if err != nil { return err } return nil
} // GetByID retrieves a user by its ID from the MySQL repository
func (repo *MySQLUserRepository) GetByID(id int) (*User, error) { row := repo.db.QueryRow("SELECT id, username, email FROM users WHERE id = ?", id) user := &User{} err := row.Scan(&user.ID, &user.Username, &user.Email) if err != nil { return nil, err } return user, nil
} // GetAll retrieves all users from the MySQL repository
func (repo *MySQLUserRepository) GetAll() ([]*User, error) { rows, err := repo.db.Query("SELECT id, username, email FROM users") if err != nil { return nil, err } defer rows.Close() var users []*User for rows.Next() { user := &User{} err := rows.Scan(&user.ID, &user.Username, &user.Email) if err != nil { return nil, err } users = append(users, user) } return users, nil
} func main() { // Example usage of in-memory repository memRepo := NewInMemoryUserRepository() memRepo.Insert(&User{ID: 1, Username: "user1", Email: "[email protected]"}) memRepo.Insert(&User{ID: 2, Username: "user2", Email: "[email protected]"}) user, err := memRepo.GetByID(1) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("In-Memory User:", user) } allUsers, err := memRepo.GetAll() if err != nil { fmt.Println("Error:", err) } else { fmt.Println("In-Memory All Users:", allUsers) } // Example usage of MySQL repository mysqlRepo, err := NewMySQLUserRepository("user:password@tcp(127.0.0.1:3306)/database_name") if err != nil { fmt.Println("Error:", err) return } mysqlRepo.Insert(&User{ID: 3, Username: "user3", Email: "[email protected]"}) mysqlRepo.Insert(&User{ID: 4, Username: "user4", Email: "[email protected]"}) user, err = mysqlRepo.GetByID(3) if err != nil { fmt.Println("Error:", err) } else { fmt.Println("MySQL User:", user) } allUsers, err = mysqlRepo.GetAll() if err != nil { fmt.Println("Error:", err) } else { fmt.Println("MySQL All Users:", allUsers) }
} 
Enter fullscreen mode
Exit fullscreen mode

Discover more from Coursity

Subscribe to get the latest posts to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *