Skip to content

Commit

Permalink
Storage Abstraction (#13)
Browse files Browse the repository at this point in the history
  • Loading branch information
NickyMateev committed Apr 3, 2019
1 parent 8a95c72 commit 9da61a2
Show file tree
Hide file tree
Showing 19 changed files with 435 additions and 168 deletions.
9 changes: 9 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Gopkg.toml
Expand Up @@ -59,3 +59,7 @@
[[constraint]]
name = "github.com/nlopes/slack"
version = "0.5.0"

[[constraint]]
name = "github.com/DATA-DOG/go-sqlmock"
version = "1.3.3"
14 changes: 7 additions & 7 deletions api/api.go
@@ -1,29 +1,29 @@
package api

import (
"database/sql"
"github.com/NickyMateev/Reviewer/api/project"
"github.com/NickyMateev/Reviewer/api/pullrequest"
"github.com/NickyMateev/Reviewer/api/user"
"github.com/NickyMateev/Reviewer/storage"
"github.com/NickyMateev/Reviewer/web"
)

type defaultAPI struct {
db *sql.DB
storage storage.Storage
}

// Default returns an instance of the default API
func Default(db *sql.DB) web.API {
func Default(storage storage.Storage) web.API {
return defaultAPI{
db: db,
storage: storage,
}
}

// Controllers returns the default API's controllers
func (api defaultAPI) Controllers() []web.Controller {
return []web.Controller{
user.Controller(api.db),
project.Controller(api.db),
pullrequest.Controller(api.db),
user.Controller(api.storage),
project.Controller(api.storage),
pullrequest.Controller(api.storage),
}
}
6 changes: 3 additions & 3 deletions api/project/project.go
@@ -1,15 +1,15 @@
package project

import (
"database/sql"
"github.com/NickyMateev/Reviewer/storage"
"github.com/NickyMateev/Reviewer/web"
"net/http"
)

// Controller returns an instance of the Project controller
func Controller(db *sql.DB) *controller {
func Controller(storage storage.Storage) *controller {
return &controller{
db: db,
storage: storage,
}
}

Expand Down
19 changes: 11 additions & 8 deletions api/project/project_controller.go
Expand Up @@ -4,6 +4,7 @@ import (
"database/sql"
"encoding/json"
"github.com/NickyMateev/Reviewer/models"
"github.com/NickyMateev/Reviewer/storage"
"github.com/NickyMateev/Reviewer/web"
"github.com/gorilla/mux"
"github.com/pkg/errors"
Expand All @@ -14,7 +15,7 @@ import (
)

type controller struct {
db *sql.DB
storage storage.Storage
}

func (c *controller) createProject(w http.ResponseWriter, r *http.Request) {
Expand All @@ -36,7 +37,7 @@ func (c *controller) createProject(w http.ResponseWriter, r *http.Request) {
return
}

err = project.Insert(r.Context(), c.db, boil.Infer())
err = project.Insert(r.Context(), c.storage.Get(), boil.Infer())
if err != nil {
log.Println("Error creating new project:", err)
web.WriteResponse(w, http.StatusInternalServerError, struct{}{})
Expand All @@ -51,7 +52,7 @@ func (c *controller) getProject(w http.ResponseWriter, r *http.Request) {
projectID := vars["id"]
log.Println("Getting project with id", projectID)

project, err := models.Projects(qm.Where("id = ?", projectID)).One(r.Context(), c.db)
project, err := models.Projects(qm.Where("id = ?", projectID)).One(r.Context(), c.storage.Get())
if err != nil {
if err == sql.ErrNoRows {
log.Println("Missing project:", err)
Expand All @@ -67,26 +68,28 @@ func (c *controller) getProject(w http.ResponseWriter, r *http.Request) {

func (c *controller) listProject(w http.ResponseWriter, r *http.Request) {
log.Println("Getting all projects")
projects, err := models.Projects().All(r.Context(), c.db)

result := make([]*models.Project, 0)
projects, err := models.Projects().All(r.Context(), c.storage.Get())
if err != nil {
log.Println("Error getting projects:", err)
web.WriteResponse(w, http.StatusInternalServerError, struct{}{})
return
}

if len(projects) == 0 {
projects = []*models.Project{}
if len(projects) > 0 {
result = projects
}

web.WriteResponse(w, http.StatusOK, projects)
web.WriteResponse(w, http.StatusOK, result)
}

func (c *controller) deleteProject(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
projectID := vars["id"]
log.Println("Deleting project with id", projectID)

rows, err := models.Projects(qm.Where("id = ?", projectID)).DeleteAll(r.Context(), c.db)
rows, err := models.Projects(qm.Where("id = ?", projectID)).DeleteAll(r.Context(), c.storage.Get())
if err != nil {
log.Printf("Error deleting project with id %v: %v", projectID, err)
web.WriteResponse(w, http.StatusInternalServerError, struct{}{})
Expand Down
6 changes: 3 additions & 3 deletions api/pullrequest/pullrequest.go
@@ -1,15 +1,15 @@
package pullrequest

import (
"database/sql"
"github.com/NickyMateev/Reviewer/storage"
"github.com/NickyMateev/Reviewer/web"
"net/http"
)

// Controller returns an instance of the Pull Request controller
func Controller(db *sql.DB) *controller {
func Controller(storage storage.Storage) *controller {
return &controller{
db: db,
storage: storage,
}
}

Expand Down
15 changes: 9 additions & 6 deletions api/pullrequest/pullrequest_controller.go
Expand Up @@ -3,6 +3,7 @@ package pullrequest
import (
"database/sql"
"github.com/NickyMateev/Reviewer/models"
"github.com/NickyMateev/Reviewer/storage"
"github.com/NickyMateev/Reviewer/web"
"github.com/gorilla/mux"
"github.com/volatiletech/sqlboiler/queries/qm"
Expand All @@ -11,7 +12,7 @@ import (
)

type controller struct {
db *sql.DB
storage storage.Storage
}

func (c *controller) getPullRequest(w http.ResponseWriter, r *http.Request) {
Expand All @@ -24,7 +25,7 @@ func (c *controller) getPullRequest(w http.ResponseWriter, r *http.Request) {
qm.Load("Author"),
qm.Load("Approvers"),
qm.Load("Commenters"),
qm.Load("Idlers")).One(r.Context(), c.db)
qm.Load("Idlers")).One(r.Context(), c.storage.Get())

if err != nil {
if err == sql.ErrNoRows {
Expand Down Expand Up @@ -62,18 +63,20 @@ func (c *controller) getPullRequest(w http.ResponseWriter, r *http.Request) {

func (c *controller) listPullRequest(w http.ResponseWriter, r *http.Request) {
log.Println("Getting all pull requests")
pullRequests, err := models.PullRequests().All(r.Context(), c.db)

result := make([]*models.PullRequest, 0)
pullRequests, err := models.PullRequests().All(r.Context(), c.storage.Get())
if err != nil {
log.Println("Error getting pull requests:", err)
web.WriteResponse(w, http.StatusInternalServerError, struct{}{})
return
}

if len(pullRequests) == 0 {
pullRequests = []*models.PullRequest{}
if len(pullRequests) > 0 {
result = pullRequests
}

web.WriteResponse(w, http.StatusOK, pullRequests)
web.WriteResponse(w, http.StatusOK, result)
}

func getUserStrings(users models.UserSlice) []string {
Expand Down
6 changes: 3 additions & 3 deletions api/user/user.go
@@ -1,15 +1,15 @@
package user

import (
"database/sql"
"github.com/NickyMateev/Reviewer/storage"
"github.com/NickyMateev/Reviewer/web"
"net/http"
)

// Controller returns an instance of the User controller
func Controller(db *sql.DB) *controller {
func Controller(storage storage.Storage) *controller {
return &controller{
db: db,
storage: storage,
}
}

Expand Down
55 changes: 29 additions & 26 deletions api/user/user_controllers.go
Expand Up @@ -6,6 +6,7 @@ import (
"encoding/json"
"errors"
"github.com/NickyMateev/Reviewer/models"
"github.com/NickyMateev/Reviewer/storage"
"github.com/NickyMateev/Reviewer/web"
"github.com/gorilla/mux"
"github.com/volatiletech/sqlboiler/boil"
Expand All @@ -15,7 +16,7 @@ import (
)

type controller struct {
db *sql.DB
storage storage.Storage
}

func (c *controller) getUser(w http.ResponseWriter, r *http.Request) {
Expand All @@ -27,7 +28,7 @@ func (c *controller) getUser(w http.ResponseWriter, r *http.Request) {
qm.Where("id = ?", userID),
qm.Load("ApprovedPullRequests"),
qm.Load("CommentedPullRequests"),
qm.Load("IdledPullRequests")).One(r.Context(), c.db)
qm.Load("IdledPullRequests")).One(r.Context(), c.storage.Get())
if err != nil {
if err == sql.ErrNoRows {
log.Println("Missing user:", err)
Expand Down Expand Up @@ -62,18 +63,20 @@ func (c *controller) getUser(w http.ResponseWriter, r *http.Request) {

func (c *controller) listUsers(w http.ResponseWriter, r *http.Request) {
log.Println("Getting all users")
users, err := models.Users().All(r.Context(), c.db)

result := make([]*models.User, 0)
users, err := models.Users().All(r.Context(), c.storage.Get())
if err != nil {
log.Println("Error getting users:", err)
web.WriteResponse(w, http.StatusInternalServerError, struct{}{})
return
}

if len(users) == 0 {
users = []*models.User{}
if len(users) > 0 {
result = users
}

web.WriteResponse(w, http.StatusOK, users)
web.WriteResponse(w, http.StatusOK, result)
}

func (c *controller) patchUser(w http.ResponseWriter, r *http.Request) {
Expand All @@ -82,50 +85,50 @@ func (c *controller) patchUser(w http.ResponseWriter, r *http.Request) {
log.Println("Updating user with id", userID)

decoder := json.NewDecoder(r.Body)
user := models.User{}
err := decoder.Decode(&user)
reqUser := models.User{}
err := decoder.Decode(&reqUser)
if err != nil {
log.Println("Error decoding user payload:", err)
web.WriteResponse(w, http.StatusBadRequest, web.ErrorResponse{Error: "decoding error"})
return
}

err = validateUser(&user)
err = validateUser(&reqUser)
if err != nil {
log.Println("Validation error:", err)
web.WriteResponse(w, http.StatusBadRequest, web.ErrorResponse{Error: err.Error()})
return
}

usr, err := models.Users(qm.Where("id = ?", userID)).One(r.Context(), c.db)
if err != nil {
if err == sql.ErrNoRows {
log.Println("Missing user:", err)
web.WriteResponse(w, http.StatusNotFound, web.ErrorResponse{Error: "missing user"})
} else {
log.Printf("Error getting user with id %v: %v\n", userID, err)
web.WriteResponse(w, http.StatusInternalServerError, struct{}{})
var user *models.User
txErr := c.storage.Transaction(r.Context(), func(context context.Context, tx *sql.Tx) error {
var err error
user, err = models.Users(qm.Where("id = ?", userID)).One(context, tx)
if err != nil {
return err
}
return
}
user.Metadata = reqUser.Metadata
_, err = user.Update(context, tx, boil.Infer())
return err
})

usr.Metadata = user.Metadata
_, err = usr.Update(context.Background(), c.db, boil.Infer())
if err != nil {
log.Println("Error updating user with id", usr.ID)
if txErr == sql.ErrNoRows {
log.Println("Missing user:", err)
web.WriteResponse(w, http.StatusNotFound, web.ErrorResponse{Error: "missing user"})
} else if txErr != nil {
log.Printf("Error updating user with id %v: %v\n", userID, err)
web.WriteResponse(w, http.StatusInternalServerError, struct{}{})
return
}

web.WriteResponse(w, http.StatusNoContent, usr)
web.WriteResponse(w, http.StatusOK, user)
}

func (c *controller) deleteUser(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userID := vars["id"]
log.Println("Deleting user with id", userID)

rows, err := models.Users(qm.Where("id = ?", userID)).DeleteAll(r.Context(), c.db)
rows, err := models.Users(qm.Where("id = ?", userID)).DeleteAll(r.Context(), c.storage.Get())
if err != nil {
log.Printf("Error deleting user with id %v: %v", userID, err)
web.WriteResponse(w, http.StatusInternalServerError, struct{}{})
Expand Down

0 comments on commit 9da61a2

Please sign in to comment.