Просмотр исходного кода

Refactoring data access to command query model, and adding tests for sql code

Torkel Ödegaard 11 лет назад
Родитель
Сommit
36c46112df
4 измененных файлов с 107 добавлено и 34 удалено
  1. 11 21
      pkg/api/api_account.go
  2. 20 0
      pkg/models/account.go
  3. 44 13
      pkg/stores/sqlstore/accounts.go
  4. 32 0
      pkg/stores/sqlstore/accounts_test.go

+ 11 - 21
pkg/api/api_account.go

@@ -2,32 +2,22 @@ package api
 
 import (
 	"github.com/torkelo/grafana-pro/pkg/api/dtos"
+	"github.com/torkelo/grafana-pro/pkg/bus"
 	"github.com/torkelo/grafana-pro/pkg/middleware"
-	"github.com/torkelo/grafana-pro/pkg/models"
+	m "github.com/torkelo/grafana-pro/pkg/models"
 	"github.com/torkelo/grafana-pro/pkg/utils"
 )
 
 func GetAccount(c *middleware.Context) {
-	model := dtos.AccountInfo{
-		Name:  c.UserAccount.Name,
-		Email: c.UserAccount.Email,
-	}
+	query := m.GetAccountInfoQuery{Id: c.UserAccount.Id}
+	err := bus.Dispatch(&query)
 
-	collaborators, err := models.GetCollaboratorsForAccount(c.UserAccount.Id)
 	if err != nil {
 		c.JsonApiErr(500, "Failed to fetch collaboratos", err)
 		return
 	}
 
-	for _, collaborator := range collaborators {
-		model.Collaborators = append(model.Collaborators, &dtos.Collaborator{
-			AccountId: collaborator.AccountId,
-			Role:      collaborator.Role,
-			Email:     collaborator.Email,
-		})
-	}
-
-	c.JSON(200, model)
+	c.JSON(200, query.Result)
 }
 
 func AddCollaborator(c *middleware.Context) {
@@ -38,7 +28,7 @@ func AddCollaborator(c *middleware.Context) {
 		return
 	}
 
-	accountToAdd, err := models.GetAccountByLogin(model.Email)
+	accountToAdd, err := m.GetAccountByLogin(model.Email)
 	if err != nil {
 		c.JsonApiErr(404, "Collaborator not found", nil)
 		return
@@ -49,9 +39,9 @@ func AddCollaborator(c *middleware.Context) {
 		return
 	}
 
-	var collaborator = models.NewCollaborator(accountToAdd.Id, c.UserAccount.Id, models.ROLE_READ_WRITE)
+	var collaborator = m.NewCollaborator(accountToAdd.Id, c.UserAccount.Id, m.ROLE_READ_WRITE)
 
-	err = models.AddCollaborator(collaborator)
+	err = m.AddCollaborator(collaborator)
 	if err != nil {
 		c.JsonApiErr(500, "Could not add collaborator", err)
 		return
@@ -62,7 +52,7 @@ func AddCollaborator(c *middleware.Context) {
 
 func GetOtherAccounts(c *middleware.Context) {
 
-	otherAccounts, err := models.GetOtherAccountsFor(c.UserAccount.Id)
+	otherAccounts, err := m.GetOtherAccountsFor(c.UserAccount.Id)
 	if err != nil {
 		c.JSON(500, utils.DynMap{"message": err.Error()})
 		return
@@ -92,7 +82,7 @@ func SetUsingAccount(c *middleware.Context) {
 	usingAccountId := c.ParamsInt64(":id")
 
 	account := c.UserAccount
-	otherAccounts, err := models.GetOtherAccountsFor(c.UserAccount.Id)
+	otherAccounts, err := m.GetOtherAccountsFor(c.UserAccount.Id)
 
 	if err != nil {
 		c.JSON(500, utils.DynMap{"message": err.Error()})
@@ -113,7 +103,7 @@ func SetUsingAccount(c *middleware.Context) {
 	}
 
 	account.UsingAccountId = usingAccountId
-	err = models.SaveAccount(account)
+	err = m.SaveAccount(account)
 	if err != nil {
 		c.JSON(500, utils.DynMap{"message": err.Error()})
 		return

+ 20 - 0
pkg/models/account.go

@@ -42,3 +42,23 @@ type Account struct {
 	Created time.Time
 	Updated time.Time
 }
+
+// api projection model
+type CollaboratorDTO struct {
+	AccountId int64  `json:"accountId"`
+	Email     string `json:"email"`
+	Role      string `json:"role"`
+}
+
+// api view projection
+type AccountDTO struct {
+	Email         string             `json:"email"`
+	Name          string             `json:"name"`
+	Collaborators []*CollaboratorDTO `json:"collaborators"`
+}
+
+// returns a view projection
+type GetAccountInfoQuery struct {
+	Id     int64
+	Result AccountDTO
+}

+ 44 - 13
pkg/stores/sqlstore/sqlstore_accounts.go → pkg/stores/sqlstore/accounts.go

@@ -1,8 +1,39 @@
 package sqlstore
 
-import "github.com/torkelo/grafana-pro/pkg/models"
+import (
+	"github.com/torkelo/grafana-pro/pkg/bus"
+	m "github.com/torkelo/grafana-pro/pkg/models"
+)
 
-func SaveAccount(account *models.Account) error {
+func init() {
+	bus.AddHandler("sql", GetAccountInfo)
+}
+
+func GetAccountInfo(query *m.GetAccountInfoQuery) error {
+	var account m.Account
+	has, err := x.Id(query.Id).Get(&account)
+
+	if err != nil {
+		return err
+	} else if has == false {
+		return m.ErrAccountNotFound
+	}
+
+	query.Result = m.AccountDTO{
+		Name:          account.Name,
+		Email:         account.Email,
+		Collaborators: make([]*m.CollaboratorDTO, 0),
+	}
+
+	sess := x.Table("collaborator")
+	sess.Join("INNER", "account", "account.id=collaborator.account_Id")
+	sess.Where("collaborator.for_account_id=?", query.Id)
+	err = sess.Find(&query.Result.Collaborators)
+
+	return err
+}
+
+func SaveAccount(account *m.Account) error {
 	var err error
 
 	sess := x.NewSession()
@@ -28,16 +59,16 @@ func SaveAccount(account *models.Account) error {
 	return nil
 }
 
-func GetAccount(id int64) (*models.Account, error) {
+func GetAccount(id int64) (*m.Account, error) {
 	var err error
 
-	var account models.Account
+	var account m.Account
 	has, err := x.Id(id).Get(&account)
 
 	if err != nil {
 		return nil, err
 	} else if has == false {
-		return nil, models.ErrAccountNotFound
+		return nil, m.ErrAccountNotFound
 	}
 
 	if account.UsingAccountId == 0 {
@@ -47,23 +78,23 @@ func GetAccount(id int64) (*models.Account, error) {
 	return &account, nil
 }
 
-func GetAccountByLogin(emailOrLogin string) (*models.Account, error) {
+func GetAccountByLogin(emailOrLogin string) (*m.Account, error) {
 	var err error
 
-	account := &models.Account{Login: emailOrLogin}
+	account := &m.Account{Login: emailOrLogin}
 	has, err := x.Get(account)
 
 	if err != nil {
 		return nil, err
 	} else if has == false {
-		return nil, models.ErrAccountNotFound
+		return nil, m.ErrAccountNotFound
 	}
 
 	return account, nil
 }
 
-func GetCollaboratorsForAccount(accountId int64) ([]*models.CollaboratorInfo, error) {
-	collaborators := make([]*models.CollaboratorInfo, 0)
+func GetCollaboratorsForAccount(accountId int64) ([]*m.CollaboratorInfo, error) {
+	collaborators := make([]*m.CollaboratorInfo, 0)
 
 	sess := x.Table("collaborator")
 	sess.Join("INNER", "account", "account.id=collaborator.account_Id")
@@ -73,7 +104,7 @@ func GetCollaboratorsForAccount(accountId int64) ([]*models.CollaboratorInfo, er
 	return collaborators, err
 }
 
-func AddCollaborator(collaborator *models.Collaborator) error {
+func AddCollaborator(collaborator *m.Collaborator) error {
 	var err error
 
 	sess := x.NewSession()
@@ -93,8 +124,8 @@ func AddCollaborator(collaborator *models.Collaborator) error {
 	return nil
 }
 
-func GetOtherAccountsFor(accountId int64) ([]*models.OtherAccount, error) {
-	collaborators := make([]*models.OtherAccount, 0)
+func GetOtherAccountsFor(accountId int64) ([]*m.OtherAccount, error) {
+	collaborators := make([]*m.OtherAccount, 0)
 	sess := x.Table("collaborator")
 	sess.Join("INNER", "account", "collaborator.for_account_id=account.id")
 	sess.Where("account_id=?", accountId)

+ 32 - 0
pkg/stores/sqlstore/accounts_test.go

@@ -0,0 +1,32 @@
+package sqlstore
+
+import (
+	"testing"
+
+	. "github.com/smartystreets/goconvey/convey"
+
+	m "github.com/torkelo/grafana-pro/pkg/models"
+)
+
+func TestAccountDataAccess(t *testing.T) {
+
+	Convey("Testing Account DB Access", t, func() {
+		InitTestDB(t)
+
+		Convey("Can save account", func() {
+			account := m.Account{
+				Login: "login",
+				Email: "login@test.com",
+				Name:  "name",
+			}
+
+			err := SaveAccount(&account)
+
+			query := m.GetAccountInfoQuery{Id: account.Id}
+			err = GetAccountInfo(&query)
+
+			So(err, ShouldBeNil)
+			So(query.Result.Name, ShouldEqual, "name")
+		})
+	})
+}