rethink.go 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. package rethink
  2. import (
  3. "errors"
  4. "time"
  5. r "github.com/dancannon/gorethink"
  6. "github.com/torkelo/grafana-pro/pkg/log"
  7. "github.com/torkelo/grafana-pro/pkg/models"
  8. )
  9. var (
  10. session *r.Session
  11. dbName string = "grafana"
  12. )
  13. func Init() {
  14. log.Info("Initializing rethink storage")
  15. var err error
  16. session, err = r.Connect(r.ConnectOpts{
  17. Address: "localhost:28015",
  18. Database: dbName,
  19. MaxIdle: 10,
  20. IdleTimeout: time.Second * 10,
  21. })
  22. if err != nil {
  23. log.Error(3, "Failed to connect to rethink database %v", err)
  24. }
  25. createRethinkDBTablesAndIndices()
  26. models.GetAccount = GetAccount
  27. models.GetAccountByLogin = GetAccountByLogin
  28. models.GetDashboard = GetDashboard
  29. models.SearchQuery = SearchQuery
  30. models.DeleteDashboard = DeleteDashboard
  31. models.SaveDashboard = SaveDashboard
  32. }
  33. func createRethinkDBTablesAndIndices() {
  34. r.DbCreate(dbName).Exec(session)
  35. // create tables
  36. r.Db(dbName).TableCreate("dashboards").Exec(session)
  37. r.Db(dbName).TableCreate("accounts").Exec(session)
  38. r.Db(dbName).TableCreate("master").Exec(session)
  39. // create dashboard accountId + slug index
  40. r.Db(dbName).Table("dashboards").IndexCreateFunc("AccountIdSlug", func(row r.Term) interface{} {
  41. return []interface{}{row.Field("AccountId"), row.Field("Slug")}
  42. }).Exec(session)
  43. r.Db(dbName).Table("dashboards").IndexCreate("AccountId").Exec(session)
  44. r.Db(dbName).Table("accounts").IndexCreate("Login").Exec(session)
  45. // create account collaborator index
  46. r.Db(dbName).Table("accounts").
  47. IndexCreateFunc("CollaboratorAccountId", func(row r.Term) interface{} {
  48. return row.Field("Collaborators").Map(func(row r.Term) interface{} {
  49. return row.Field("AccountId")
  50. })
  51. }, r.IndexCreateOpts{Multi: true}).Exec(session)
  52. // make sure master ids row exists
  53. _, err := r.Table("master").Insert(map[string]interface{}{"id": "ids", "NextAccountId": 0}).RunWrite(session)
  54. if err != nil {
  55. log.Error(3, "Failed to insert master ids row", err)
  56. }
  57. }
  58. func getNextAccountId() (int, error) {
  59. resp, err := r.Table("master").Get("ids").Update(map[string]interface{}{
  60. "NextAccountId": r.Row.Field("NextAccountId").Add(1),
  61. }, r.UpdateOpts{ReturnChanges: true}).RunWrite(session)
  62. if err != nil {
  63. return 0, err
  64. }
  65. change := resp.Changes[0]
  66. if change.NewValue == nil {
  67. return 0, errors.New("Failed to get new value after incrementing account id")
  68. }
  69. return int(change.NewValue.(map[string]interface{})["NextAccountId"].(float64)), nil
  70. }
  71. func CreateAccount(account *models.Account) error {
  72. accountId, err := getNextAccountId()
  73. if err != nil {
  74. return err
  75. }
  76. account.Id = accountId
  77. account.UsingAccountId = accountId
  78. resp, err := r.Table("accounts").Insert(account).RunWrite(session)
  79. if err != nil {
  80. return err
  81. }
  82. if resp.Inserted == 0 {
  83. return errors.New("Failed to insert acccount")
  84. }
  85. return nil
  86. }
  87. func GetAccountByLogin(emailOrName string) (*models.Account, error) {
  88. resp, err := r.Table("accounts").GetAllByIndex("Login", emailOrName).Run(session)
  89. if err != nil {
  90. return nil, err
  91. }
  92. var account models.Account
  93. err = resp.One(&account)
  94. if err != nil {
  95. return nil, models.ErrAccountNotFound
  96. }
  97. return &account, nil
  98. }
  99. func GetAccount(id int) (*models.Account, error) {
  100. resp, err := r.Table("accounts").Get(id).Run(session)
  101. if err != nil {
  102. return nil, err
  103. }
  104. var account models.Account
  105. err = resp.One(&account)
  106. if err != nil {
  107. return nil, errors.New("Not found")
  108. }
  109. return &account, nil
  110. }
  111. func UpdateAccount(account *models.Account) error {
  112. resp, err := r.Table("accounts").Update(account).RunWrite(session)
  113. if err != nil {
  114. return err
  115. }
  116. if resp.Replaced == 0 && resp.Unchanged == 0 {
  117. return errors.New("Could not find account to update")
  118. }
  119. return nil
  120. }
  121. func getNextDashboardNumber(accountId int) (int, error) {
  122. resp, err := r.Table("accounts").Get(accountId).Update(map[string]interface{}{
  123. "NextDashboardId": r.Row.Field("NextDashboardId").Add(1),
  124. }, r.UpdateOpts{ReturnChanges: true}).RunWrite(session)
  125. if err != nil {
  126. return 0, err
  127. }
  128. change := resp.Changes[0]
  129. if change.NewValue == nil {
  130. return 0, errors.New("Failed to get next dashboard id, no new value after update")
  131. }
  132. return int(change.NewValue.(map[string]interface{})["NextDashboardId"].(float64)), nil
  133. }
  134. func GetOtherAccountsFor(accountId int) ([]*models.OtherAccount, error) {
  135. resp, err := r.Table("accounts").
  136. GetAllByIndex("CollaboratorAccountId", accountId).
  137. Map(func(row r.Term) interface{} {
  138. return map[string]interface{}{
  139. "id": row.Field("id"),
  140. "Name": row.Field("Email"),
  141. "Role": row.Field("Collaborators").Filter(map[string]interface{}{
  142. "AccountId": accountId,
  143. }).Nth(0).Field("Role"),
  144. }
  145. }).Run(session)
  146. if err != nil {
  147. return nil, err
  148. }
  149. var list []*models.OtherAccount
  150. err = resp.All(&list)
  151. if err != nil {
  152. return nil, errors.New("Failed to read available accounts")
  153. }
  154. return list, nil
  155. }