Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 09d8567
Showing
16 changed files
with
383 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
vendor/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
version: '2' | ||
services: | ||
db: | ||
image: mysql:5.7 | ||
environment: | ||
MYSQL_DATABASE: sample | ||
MYSQL_ALLOW_EMPTY_PASSWORD: "yes" | ||
volumes: | ||
- db-data:/var/lib/mysql | ||
- ./mysql:/docker-entrypoint-initdb.d | ||
ports: | ||
- "3306:3306" | ||
app: | ||
image: golang:1.6 | ||
environment: | ||
MYAPP_DATABASE_HOST: db | ||
command: "go run server.go" | ||
volumes: | ||
- ./src:/go/src | ||
working_dir: /go/src/app | ||
ports: | ||
- "8080:8080" | ||
links: | ||
- db | ||
|
||
volumes: | ||
db-data: |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
CREATE TABLE users ( | ||
id bigint(20) unsigned NOT NULL AUTO_INCREMENT, | ||
first_name VARCHAR(20) NOT NULL, | ||
last_name VARCHAR(20) NOT NULL, | ||
PRIMARY KEY (id) | ||
); | ||
|
||
insert into users(first_name, last_name) values("Patricia", "Smith"); | ||
insert into users(first_name, last_name) values("Linda", "Johnson"); | ||
insert into users(first_name, last_name) values("Mary", "William"); | ||
insert into users(first_name, last_name) values("Robert", "Jones"); | ||
insert into users(first_name, last_name) values("James", "Brown"); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package domain | ||
|
||
import "fmt" | ||
|
||
type Users []User | ||
|
||
type User struct { | ||
ID int | ||
FirstName string | ||
LastName string | ||
FullName string | ||
} | ||
|
||
func (u *User) Build() *User { | ||
u.FullName = fmt.Sprintf("%s %s", u.FirstName, u.LastName) | ||
return u | ||
} |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
package: . | ||
import: | ||
- package: github.com/go-sql-driver/mysql | ||
version: v1.3 | ||
- package: gopkg.in/gin-gonic/gin.v1 | ||
version: v1.1.4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package infrastructure | ||
|
||
import ( | ||
gin "gopkg.in/gin-gonic/gin.v1" | ||
|
||
"app/interfaces/controllers" | ||
) | ||
|
||
var Router *gin.Engine | ||
|
||
func init() { | ||
router := gin.Default() | ||
|
||
userController := controllers.NewUserController(NewSqlHandler()) | ||
|
||
router.POST("/users", func(c *gin.Context) { userController.Create(c) }) | ||
router.GET("/users", func(c *gin.Context) { userController.Index(c) }) | ||
router.GET("/users/:id", func(c *gin.Context) { userController.Show(c) }) | ||
|
||
Router = router | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
package infrastructure | ||
|
||
import ( | ||
"database/sql" | ||
|
||
_ "github.com/go-sql-driver/mysql" | ||
|
||
"app/interfaces/database" | ||
) | ||
|
||
type SqlHandler struct { | ||
Conn *sql.DB | ||
} | ||
|
||
func NewSqlHandler() database.SqlHandler { | ||
conn, err := sql.Open("mysql", "root:@tcp(db:3306)/sample") | ||
if err != nil { | ||
panic(err.Error) | ||
} | ||
sqlHandler := new(SqlHandler) | ||
sqlHandler.Conn = conn | ||
return sqlHandler | ||
} | ||
|
||
func (handler *SqlHandler) Execute(statement string, args ...interface{}) (database.Result, error) { | ||
res := SqlResult{} | ||
result, err := handler.Conn.Exec(statement, args...) | ||
if err != nil { | ||
return res, err | ||
} | ||
res.Result = result | ||
return res, nil | ||
} | ||
|
||
func (handler *SqlHandler) Query(statement string, args ...interface{}) (database.Row, error) { | ||
rows, err := handler.Conn.Query(statement, args...) | ||
if err != nil { | ||
return new(SqlRow), err | ||
} | ||
row := new(SqlRow) | ||
row.Rows = rows | ||
return row, nil | ||
} | ||
|
||
type SqlResult struct { | ||
Result sql.Result | ||
} | ||
|
||
func (r SqlResult) LastInsertId() (int64, error) { | ||
return r.Result.LastInsertId() | ||
} | ||
|
||
func (r SqlResult) RowsAffected() (int64, error) { | ||
return r.Result.RowsAffected() | ||
} | ||
|
||
type SqlRow struct { | ||
Rows *sql.Rows | ||
} | ||
|
||
func (r SqlRow) Scan(dest ...interface{}) error { | ||
return r.Rows.Scan(dest...) | ||
} | ||
|
||
func (r SqlRow) Next() bool { | ||
return r.Rows.Next() | ||
} | ||
|
||
func (r SqlRow) Close() error { | ||
return r.Rows.Close() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package controllers | ||
|
||
type Context interface { | ||
Param(string) string | ||
Bind(interface{}) error | ||
Status(int) | ||
JSON(int, interface{}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package controllers | ||
|
||
type Error struct { | ||
Message string | ||
} | ||
|
||
func NewError(err error) *Error { | ||
return &Error{ | ||
Message: err.Error(), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
package controllers | ||
|
||
import ( | ||
"app/domain" | ||
"app/interfaces/database" | ||
"app/usecase" | ||
"strconv" | ||
) | ||
|
||
type UserController struct { | ||
Interactor usecase.UserInteractor | ||
} | ||
|
||
func NewUserController(sqlHandler database.SqlHandler) *UserController { | ||
return &UserController{ | ||
Interactor: usecase.UserInteractor{ | ||
UserRepository: &database.UserRepository{ | ||
SqlHandler: sqlHandler, | ||
}, | ||
}, | ||
} | ||
} | ||
|
||
func (controller *UserController) Create(c Context) { | ||
u := domain.User{} | ||
c.Bind(&u) | ||
user, err := controller.Interactor.Add(u) | ||
if err != nil { | ||
c.JSON(500, NewError(err)) | ||
return | ||
} | ||
c.JSON(201, user) | ||
} | ||
|
||
func (controller *UserController) Index(c Context) { | ||
users, err := controller.Interactor.Users() | ||
if err != nil { | ||
c.JSON(500, NewError(err)) | ||
return | ||
} | ||
c.JSON(200, users) | ||
} | ||
|
||
func (controller *UserController) Show(c Context) { | ||
id, _ := strconv.Atoi(c.Param("id")) | ||
user, err := controller.Interactor.UserById(id) | ||
if err != nil { | ||
c.JSON(500, NewError(err)) | ||
return | ||
} | ||
c.JSON(200, user) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package database | ||
|
||
type SqlHandler interface { | ||
Execute(string, ...interface{}) (Result, error) | ||
Query(string, ...interface{}) (Row, error) | ||
} | ||
|
||
type Result interface { | ||
LastInsertId() (int64, error) | ||
RowsAffected() (int64, error) | ||
} | ||
|
||
type Row interface { | ||
Scan(...interface{}) error | ||
Next() bool | ||
Close() error | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package database | ||
|
||
import "app/domain" | ||
|
||
type UserRepository struct { | ||
SqlHandler | ||
} | ||
|
||
func (repo *UserRepository) Store(u domain.User) (id int, err error) { | ||
result, err := repo.Execute( | ||
"INSERT INTO users (first_name, last_name) VALUES (?,?)", u.FirstName, u.LastName, | ||
) | ||
if err != nil { | ||
return | ||
} | ||
id64, err := result.LastInsertId() | ||
if err != nil { | ||
return | ||
} | ||
id = int(id64) | ||
return | ||
} | ||
|
||
func (repo *UserRepository) FindById(identifier int) (user domain.User, err error) { | ||
row, err := repo.Query("SELECT id, first_name, last_name FROM users WHERE id = ?", identifier) | ||
defer row.Close() | ||
if err != nil { | ||
return | ||
} | ||
var id int | ||
var firstName string | ||
var lastName string | ||
row.Next() | ||
if err = row.Scan(&id, &firstName, &lastName); err != nil { | ||
return | ||
} | ||
user.ID = id | ||
user.FirstName = firstName | ||
user.LastName = lastName | ||
user.Build() | ||
return | ||
} | ||
|
||
func (repo *UserRepository) FindAll() (users domain.Users, err error) { | ||
rows, err := repo.Query("SELECT id, first_name, last_name FROM users") | ||
defer rows.Close() | ||
if err != nil { | ||
return | ||
} | ||
for rows.Next() { | ||
var id int | ||
var firstName string | ||
var lastName string | ||
if err := rows.Scan(&id, &firstName, &lastName); err != nil { | ||
continue | ||
} | ||
user := domain.User{ | ||
ID: id, | ||
FirstName: firstName, | ||
LastName: lastName, | ||
} | ||
users = append(users, *user.Build()) | ||
} | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
package main | ||
|
||
import "app/infrastructure" | ||
|
||
func main() { | ||
infrastructure.Router.Run() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package usecase | ||
|
||
import "app/domain" | ||
|
||
type UserInteractor struct { | ||
UserRepository UserRepository | ||
} | ||
|
||
func (interactor *UserInteractor) Add(u domain.User) (user domain.User, err error) { | ||
identifier, err := interactor.UserRepository.Store(u) | ||
if err != nil { | ||
return | ||
} | ||
user, err = interactor.UserRepository.FindById(identifier) | ||
return | ||
} | ||
|
||
func (interactor *UserInteractor) Users() (user domain.Users, err error) { | ||
user, err = interactor.UserRepository.FindAll() | ||
return | ||
} | ||
|
||
func (interactor *UserInteractor) UserById(identifier int) (user domain.User, err error) { | ||
user, err = interactor.UserRepository.FindById(identifier) | ||
return | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
package usecase | ||
|
||
import "app/domain" | ||
|
||
type UserRepository interface { | ||
Store(domain.User) (int, error) | ||
FindById(int) (domain.User, error) | ||
FindAll() (domain.Users, error) | ||
} |