diff options
Diffstat (limited to 'store')
-rw-r--r-- | store/sql_command_store.go | 173 | ||||
-rw-r--r-- | store/sql_command_store_test.go | 155 | ||||
-rw-r--r-- | store/sql_store.go | 8 | ||||
-rw-r--r-- | store/sql_user_store.go | 21 | ||||
-rw-r--r-- | store/sql_user_store_test.go | 2 | ||||
-rw-r--r-- | store/sql_webhook_store.go | 27 | ||||
-rw-r--r-- | store/sql_webhook_store_test.go | 34 | ||||
-rw-r--r-- | store/store.go | 15 |
8 files changed, 374 insertions, 61 deletions
diff --git a/store/sql_command_store.go b/store/sql_command_store.go new file mode 100644 index 000000000..760235e10 --- /dev/null +++ b/store/sql_command_store.go @@ -0,0 +1,173 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package store + +import ( + "github.com/mattermost/platform/model" +) + +type SqlCommandStore struct { + *SqlStore +} + +func NewSqlCommandStore(sqlStore *SqlStore) CommandStore { + s := &SqlCommandStore{sqlStore} + + for _, db := range sqlStore.GetAllConns() { + tableo := db.AddTableWithName(model.Command{}, "Commands").SetKeys(false, "Id") + tableo.ColMap("Id").SetMaxSize(26) + tableo.ColMap("Token").SetMaxSize(26) + tableo.ColMap("CreatorId").SetMaxSize(26) + tableo.ColMap("TeamId").SetMaxSize(26) + tableo.ColMap("Trigger").SetMaxSize(128) + tableo.ColMap("URL").SetMaxSize(1024) + tableo.ColMap("Method").SetMaxSize(1) + tableo.ColMap("Username").SetMaxSize(64) + tableo.ColMap("IconURL").SetMaxSize(1024) + tableo.ColMap("AutoCompleteDesc").SetMaxSize(1024) + tableo.ColMap("AutoCompleteHint").SetMaxSize(1024) + tableo.ColMap("DisplayName").SetMaxSize(64) + } + + return s +} + +func (s SqlCommandStore) UpgradeSchemaIfNeeded() { +} + +func (s SqlCommandStore) CreateIndexesIfNotExists() { + s.CreateIndexIfNotExists("idx_command_team_id", "Commands", "TeamId") +} + +func (s SqlCommandStore) Save(command *model.Command) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + if len(command.Id) > 0 { + result.Err = model.NewLocAppError("SqlCommandStore.Save", "store.sql_command.save.saving_overwrite.app_error", nil, "id="+command.Id) + storeChannel <- result + close(storeChannel) + return + } + + command.PreSave() + if result.Err = command.IsValid(); result.Err != nil { + storeChannel <- result + close(storeChannel) + return + } + + if err := s.GetMaster().Insert(command); err != nil { + result.Err = model.NewLocAppError("SqlCommandStore.Save", "store.sql_command.save.saving.app_error", nil, "id="+command.Id+", "+err.Error()) + } else { + result.Data = command + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (s SqlCommandStore) Get(id string) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + var command model.Command + + if err := s.GetReplica().SelectOne(&command, "SELECT * FROM Commands WHERE Id = :Id AND DeleteAt = 0", map[string]interface{}{"Id": id}); err != nil { + result.Err = model.NewLocAppError("SqlCommandStore.Get", "store.sql_command.save.get.app_error", nil, "id="+id+", err="+err.Error()) + } + + result.Data = &command + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (s SqlCommandStore) GetByTeam(teamId string) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + var commands []*model.Command + + if _, err := s.GetReplica().Select(&commands, "SELECT * FROM Commands WHERE TeamId = :TeamId AND DeleteAt = 0", map[string]interface{}{"TeamId": teamId}); err != nil { + result.Err = model.NewLocAppError("SqlCommandStore.GetByTeam", "store.sql_command.save.get_team.app_error", nil, "teamId="+teamId+", err="+err.Error()) + } + + result.Data = commands + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (s SqlCommandStore) Delete(commandId string, time int64) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + _, err := s.GetMaster().Exec("Update Commands SET DeleteAt = :DeleteAt, UpdateAt = :UpdateAt WHERE Id = :Id", map[string]interface{}{"DeleteAt": time, "UpdateAt": time, "Id": commandId}) + if err != nil { + result.Err = model.NewLocAppError("SqlCommandStore.Delete", "store.sql_command.save.delete.app_error", nil, "id="+commandId+", err="+err.Error()) + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (s SqlCommandStore) PermanentDeleteByUser(userId string) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + _, err := s.GetMaster().Exec("DELETE FROM Commands WHERE CreatorId = :UserId", map[string]interface{}{"UserId": userId}) + if err != nil { + result.Err = model.NewLocAppError("SqlCommandStore.DeleteByUser", "store.sql_command.save.delete_perm.app_error", nil, "id="+userId+", err="+err.Error()) + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} + +func (s SqlCommandStore) Update(hook *model.Command) StoreChannel { + storeChannel := make(StoreChannel) + + go func() { + result := StoreResult{} + + hook.UpdateAt = model.GetMillis() + + if _, err := s.GetMaster().Update(hook); err != nil { + result.Err = model.NewLocAppError("SqlCommandStore.Update", "store.sql_command.save.update.app_error", nil, "id="+hook.Id+", "+err.Error()) + } else { + result.Data = hook + } + + storeChannel <- result + close(storeChannel) + }() + + return storeChannel +} diff --git a/store/sql_command_store_test.go b/store/sql_command_store_test.go new file mode 100644 index 000000000..b4610d4aa --- /dev/null +++ b/store/sql_command_store_test.go @@ -0,0 +1,155 @@ +// Copyright (c) 2016 Mattermost, Inc. All Rights Reserved. +// See License.txt for license information. + +package store + +import ( + "github.com/mattermost/platform/model" + "testing" +) + +func TestCommandStoreSave(t *testing.T) { + Setup() + + o1 := model.Command{} + o1.CreatorId = model.NewId() + o1.Method = model.COMMAND_METHOD_POST + o1.TeamId = model.NewId() + o1.URL = "http://nowhere.com/" + + if err := (<-store.Command().Save(&o1)).Err; err != nil { + t.Fatal("couldn't save item", err) + } + + if err := (<-store.Command().Save(&o1)).Err; err == nil { + t.Fatal("shouldn't be able to update from save") + } +} + +func TestCommandStoreGet(t *testing.T) { + Setup() + + o1 := &model.Command{} + o1.CreatorId = model.NewId() + o1.Method = model.COMMAND_METHOD_POST + o1.TeamId = model.NewId() + o1.URL = "http://nowhere.com/" + + o1 = (<-store.Command().Save(o1)).Data.(*model.Command) + + if r1 := <-store.Command().Get(o1.Id); r1.Err != nil { + t.Fatal(r1.Err) + } else { + if r1.Data.(*model.Command).CreateAt != o1.CreateAt { + t.Fatal("invalid returned command") + } + } + + if err := (<-store.Command().Get("123")).Err; err == nil { + t.Fatal("Missing id should have failed") + } +} + +func TestCommandStoreGetByTeam(t *testing.T) { + Setup() + + o1 := &model.Command{} + o1.CreatorId = model.NewId() + o1.Method = model.COMMAND_METHOD_POST + o1.TeamId = model.NewId() + o1.URL = "http://nowhere.com/" + + o1 = (<-store.Command().Save(o1)).Data.(*model.Command) + + if r1 := <-store.Command().GetByTeam(o1.TeamId); r1.Err != nil { + t.Fatal(r1.Err) + } else { + if r1.Data.([]*model.Command)[0].CreateAt != o1.CreateAt { + t.Fatal("invalid returned command") + } + } + + if result := <-store.Command().GetByTeam("123"); result.Err != nil { + t.Fatal(result.Err) + } else { + if len(result.Data.([]*model.Command)) != 0 { + t.Fatal("no commands should have returned") + } + } +} + +func TestCommandStoreDelete(t *testing.T) { + Setup() + + o1 := &model.Command{} + o1.CreatorId = model.NewId() + o1.Method = model.COMMAND_METHOD_POST + o1.TeamId = model.NewId() + o1.URL = "http://nowhere.com/" + + o1 = (<-store.Command().Save(o1)).Data.(*model.Command) + + if r1 := <-store.Command().Get(o1.Id); r1.Err != nil { + t.Fatal(r1.Err) + } else { + if r1.Data.(*model.Command).CreateAt != o1.CreateAt { + t.Fatal("invalid returned command") + } + } + + if r2 := <-store.Command().Delete(o1.Id, model.GetMillis()); r2.Err != nil { + t.Fatal(r2.Err) + } + + if r3 := (<-store.Command().Get(o1.Id)); r3.Err == nil { + t.Log(r3.Data) + t.Fatal("Missing id should have failed") + } +} + +func TestCommandStoreDeleteByUser(t *testing.T) { + Setup() + + o1 := &model.Command{} + o1.CreatorId = model.NewId() + o1.Method = model.COMMAND_METHOD_POST + o1.TeamId = model.NewId() + o1.URL = "http://nowhere.com/" + + o1 = (<-store.Command().Save(o1)).Data.(*model.Command) + + if r1 := <-store.Command().Get(o1.Id); r1.Err != nil { + t.Fatal(r1.Err) + } else { + if r1.Data.(*model.Command).CreateAt != o1.CreateAt { + t.Fatal("invalid returned command") + } + } + + if r2 := <-store.Command().PermanentDeleteByUser(o1.CreatorId); r2.Err != nil { + t.Fatal(r2.Err) + } + + if r3 := (<-store.Command().Get(o1.Id)); r3.Err == nil { + t.Log(r3.Data) + t.Fatal("Missing id should have failed") + } +} + +func TestCommandStoreUpdate(t *testing.T) { + Setup() + + o1 := &model.Command{} + o1.CreatorId = model.NewId() + o1.Method = model.COMMAND_METHOD_POST + o1.TeamId = model.NewId() + o1.URL = "http://nowhere.com/" + + o1 = (<-store.Command().Save(o1)).Data.(*model.Command) + + o1.Token = model.NewId() + + if r2 := <-store.Command().Update(o1); r2.Err != nil { + t.Fatal(r2.Err) + } +} diff --git a/store/sql_store.go b/store/sql_store.go index 335cb207c..8517eb1a2 100644 --- a/store/sql_store.go +++ b/store/sql_store.go @@ -47,6 +47,7 @@ type SqlStore struct { oauth OAuthStore system SystemStore webhook WebhookStore + command CommandStore preference PreferenceStore } @@ -100,6 +101,7 @@ func NewSqlStore() Store { sqlStore.oauth = NewSqlOAuthStore(sqlStore) sqlStore.system = NewSqlSystemStore(sqlStore) sqlStore.webhook = NewSqlWebhookStore(sqlStore) + sqlStore.command = NewSqlCommandStore(sqlStore) sqlStore.preference = NewSqlPreferenceStore(sqlStore) err := sqlStore.master.CreateTablesIfNotExists() @@ -116,6 +118,7 @@ func NewSqlStore() Store { sqlStore.oauth.(*SqlOAuthStore).UpgradeSchemaIfNeeded() sqlStore.system.(*SqlSystemStore).UpgradeSchemaIfNeeded() sqlStore.webhook.(*SqlWebhookStore).UpgradeSchemaIfNeeded() + sqlStore.command.(*SqlCommandStore).UpgradeSchemaIfNeeded() sqlStore.preference.(*SqlPreferenceStore).UpgradeSchemaIfNeeded() sqlStore.team.(*SqlTeamStore).CreateIndexesIfNotExists() @@ -127,6 +130,7 @@ func NewSqlStore() Store { sqlStore.oauth.(*SqlOAuthStore).CreateIndexesIfNotExists() sqlStore.system.(*SqlSystemStore).CreateIndexesIfNotExists() sqlStore.webhook.(*SqlWebhookStore).CreateIndexesIfNotExists() + sqlStore.command.(*SqlCommandStore).CreateIndexesIfNotExists() sqlStore.preference.(*SqlPreferenceStore).CreateIndexesIfNotExists() sqlStore.preference.(*SqlPreferenceStore).DeleteUnusedFeatures() @@ -511,6 +515,10 @@ func (ss SqlStore) Webhook() WebhookStore { return ss.webhook } +func (ss SqlStore) Command() CommandStore { + return ss.command +} + func (ss SqlStore) Preference() PreferenceStore { return ss.preference } diff --git a/store/sql_user_store.go b/store/sql_user_store.go index 0b6970c96..b1544289d 100644 --- a/store/sql_user_store.go +++ b/store/sql_user_store.go @@ -305,7 +305,7 @@ func (us SqlUserStore) UpdateFailedPasswordAttempts(userId string, attempts int) return storeChannel } -func (us SqlUserStore) UpdateAuthData(userId, service, authData string) StoreChannel { +func (us SqlUserStore) UpdateAuthData(userId, service, authData, email string) StoreChannel { storeChannel := make(StoreChannel) @@ -314,7 +314,24 @@ func (us SqlUserStore) UpdateAuthData(userId, service, authData string) StoreCha updateAt := model.GetMillis() - if _, err := us.GetMaster().Exec("UPDATE Users SET Password = '', LastPasswordUpdate = :LastPasswordUpdate, UpdateAt = :UpdateAt, FailedAttempts = 0, AuthService = :AuthService, AuthData = :AuthData WHERE Id = :UserId", map[string]interface{}{"LastPasswordUpdate": updateAt, "UpdateAt": updateAt, "UserId": userId, "AuthService": service, "AuthData": authData}); err != nil { + query := ` + UPDATE + Users + SET + Password = '', + LastPasswordUpdate = :LastPasswordUpdate, + UpdateAt = :UpdateAt, + FailedAttempts = 0, + AuthService = :AuthService, + AuthData = :AuthData` + + if len(email) != 0 { + query += ", Email = :Email" + } + + query += " WHERE Id = :UserId" + + if _, err := us.GetMaster().Exec(query, map[string]interface{}{"LastPasswordUpdate": updateAt, "UpdateAt": updateAt, "UserId": userId, "AuthService": service, "AuthData": authData, "Email": email}); err != nil { result.Err = model.NewLocAppError("SqlUserStore.UpdateAuthData", "store.sql_user.update_auth_data.app_error", nil, "id="+userId+", "+err.Error()) } else { result.Data = userId diff --git a/store/sql_user_store_test.go b/store/sql_user_store_test.go index d1ee5e647..2350bad30 100644 --- a/store/sql_user_store_test.go +++ b/store/sql_user_store_test.go @@ -402,7 +402,7 @@ func TestUserStoreUpdateAuthData(t *testing.T) { service := "someservice" authData := "1" - if err := (<-store.User().UpdateAuthData(u1.Id, service, authData)).Err; err != nil { + if err := (<-store.User().UpdateAuthData(u1.Id, service, authData, "")).Err; err != nil { t.Fatal(err) } diff --git a/store/sql_webhook_store.go b/store/sql_webhook_store.go index 5298b0b94..740c9a33f 100644 --- a/store/sql_webhook_store.go +++ b/store/sql_webhook_store.go @@ -134,7 +134,7 @@ func (s SqlWebhookStore) PermanentDeleteIncomingByUser(userId string) StoreChann return storeChannel } -func (s SqlWebhookStore) GetIncomingByUser(userId string) StoreChannel { +func (s SqlWebhookStore) GetIncomingByTeam(teamId string) StoreChannel { storeChannel := make(StoreChannel) go func() { @@ -142,8 +142,8 @@ func (s SqlWebhookStore) GetIncomingByUser(userId string) StoreChannel { var webhooks []*model.IncomingWebhook - if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM IncomingWebhooks WHERE UserId = :UserId AND DeleteAt = 0", map[string]interface{}{"UserId": userId}); err != nil { - result.Err = model.NewLocAppError("SqlWebhookStore.GetIncomingByUser", "store.sql_webhooks.get_incoming_by_user.app_error", nil, "userId="+userId+", err="+err.Error()) + if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM IncomingWebhooks WHERE TeamId = :TeamId AND DeleteAt = 0", map[string]interface{}{"TeamId": teamId}); err != nil { + result.Err = model.NewLocAppError("SqlWebhookStore.GetIncomingByUser", "store.sql_webhooks.get_incoming_by_user.app_error", nil, "teamId="+teamId+", err="+err.Error()) } result.Data = webhooks @@ -231,27 +231,6 @@ func (s SqlWebhookStore) GetOutgoing(id string) StoreChannel { return storeChannel } -func (s SqlWebhookStore) GetOutgoingByCreator(userId string) StoreChannel { - storeChannel := make(StoreChannel) - - go func() { - result := StoreResult{} - - var webhooks []*model.OutgoingWebhook - - if _, err := s.GetReplica().Select(&webhooks, "SELECT * FROM OutgoingWebhooks WHERE CreatorId = :UserId AND DeleteAt = 0", map[string]interface{}{"UserId": userId}); err != nil { - result.Err = model.NewLocAppError("SqlWebhookStore.GetOutgoingByCreator", "store.sql_webhooks.get_outgoing_by_creator.app_error", nil, "userId="+userId+", err="+err.Error()) - } - - result.Data = webhooks - - storeChannel <- result - close(storeChannel) - }() - - return storeChannel -} - func (s SqlWebhookStore) GetOutgoingByChannel(channelId string) StoreChannel { storeChannel := make(StoreChannel) diff --git a/store/sql_webhook_store_test.go b/store/sql_webhook_store_test.go index 089e38244..251ecf597 100644 --- a/store/sql_webhook_store_test.go +++ b/store/sql_webhook_store_test.go @@ -48,7 +48,7 @@ func TestWebhookStoreGetIncoming(t *testing.T) { } } -func TestWebhookStoreGetIncomingByUser(t *testing.T) { +func TestWebhookStoreGetIncomingByTeam(t *testing.T) { Setup() o1 := &model.IncomingWebhook{} @@ -58,7 +58,7 @@ func TestWebhookStoreGetIncomingByUser(t *testing.T) { o1 = (<-store.Webhook().SaveIncoming(o1)).Data.(*model.IncomingWebhook) - if r1 := <-store.Webhook().GetIncomingByUser(o1.UserId); r1.Err != nil { + if r1 := <-store.Webhook().GetIncomingByTeam(o1.TeamId); r1.Err != nil { t.Fatal(r1.Err) } else { if r1.Data.([]*model.IncomingWebhook)[0].CreateAt != o1.CreateAt { @@ -66,7 +66,7 @@ func TestWebhookStoreGetIncomingByUser(t *testing.T) { } } - if result := <-store.Webhook().GetIncomingByUser("123"); result.Err != nil { + if result := <-store.Webhook().GetIncomingByTeam("123"); result.Err != nil { t.Fatal(result.Err) } else { if len(result.Data.([]*model.IncomingWebhook)) != 0 { @@ -201,34 +201,6 @@ func TestWebhookStoreGetOutgoingByChannel(t *testing.T) { } } -func TestWebhookStoreGetOutgoingByCreator(t *testing.T) { - Setup() - - o1 := &model.OutgoingWebhook{} - o1.ChannelId = model.NewId() - o1.CreatorId = model.NewId() - o1.TeamId = model.NewId() - o1.CallbackURLs = []string{"http://nowhere.com/"} - - o1 = (<-store.Webhook().SaveOutgoing(o1)).Data.(*model.OutgoingWebhook) - - if r1 := <-store.Webhook().GetOutgoingByCreator(o1.CreatorId); r1.Err != nil { - t.Fatal(r1.Err) - } else { - if r1.Data.([]*model.OutgoingWebhook)[0].CreateAt != o1.CreateAt { - t.Fatal("invalid returned webhook") - } - } - - if result := <-store.Webhook().GetOutgoingByCreator("123"); result.Err != nil { - t.Fatal(result.Err) - } else { - if len(result.Data.([]*model.OutgoingWebhook)) != 0 { - t.Fatal("no webhooks should have returned") - } - } -} - func TestWebhookStoreGetOutgoingByTeam(t *testing.T) { Setup() diff --git a/store/store.go b/store/store.go index cfc679706..b6b86e0d9 100644 --- a/store/store.go +++ b/store/store.go @@ -37,6 +37,7 @@ type Store interface { OAuth() OAuthStore System() SystemStore Webhook() WebhookStore + Command() CommandStore Preference() PreferenceStore MarkSystemRanUnitTests() Close() @@ -111,7 +112,7 @@ type UserStore interface { UpdateLastActivityAt(userId string, time int64) StoreChannel UpdateUserAndSessionActivity(userId string, sessionId string, time int64) StoreChannel UpdatePassword(userId, newPassword string) StoreChannel - UpdateAuthData(userId, service, authData string) StoreChannel + UpdateAuthData(userId, service, authData, email string) StoreChannel Get(id string) StoreChannel GetProfiles(teamId string) StoreChannel GetByEmail(teamId string, email string) StoreChannel @@ -170,13 +171,12 @@ type SystemStore interface { type WebhookStore interface { SaveIncoming(webhook *model.IncomingWebhook) StoreChannel GetIncoming(id string) StoreChannel - GetIncomingByUser(userId string) StoreChannel + GetIncomingByTeam(teamId string) StoreChannel GetIncomingByChannel(channelId string) StoreChannel DeleteIncoming(webhookId string, time int64) StoreChannel PermanentDeleteIncomingByUser(userId string) StoreChannel SaveOutgoing(webhook *model.OutgoingWebhook) StoreChannel GetOutgoing(id string) StoreChannel - GetOutgoingByCreator(userId string) StoreChannel GetOutgoingByChannel(channelId string) StoreChannel GetOutgoingByTeam(teamId string) StoreChannel DeleteOutgoing(webhookId string, time int64) StoreChannel @@ -186,6 +186,15 @@ type WebhookStore interface { AnalyticsOutgoingCount(teamId string) StoreChannel } +type CommandStore interface { + Save(webhook *model.Command) StoreChannel + Get(id string) StoreChannel + GetByTeam(teamId string) StoreChannel + Delete(commandId string, time int64) StoreChannel + PermanentDeleteByUser(userId string) StoreChannel + Update(hook *model.Command) StoreChannel +} + type PreferenceStore interface { Save(preferences *model.Preferences) StoreChannel Get(userId string, category string, name string) StoreChannel |