summaryrefslogtreecommitdiffstats
path: root/store
diff options
context:
space:
mode:
authorHarrison Healey <harrisonmhealey@gmail.com>2016-02-04 11:38:27 -0500
committerHarrison Healey <harrisonmhealey@gmail.com>2016-02-04 11:38:27 -0500
commit4f1dbb8ca9a6cce09c9a20e91e074feaadd755a8 (patch)
treed5811b516ef8b826e6ccd80efdf72c6fe52157a2 /store
parent852acf1bb2818316e40012a385a5e8bec287eb05 (diff)
parentdffc5323ecd9c7bc1af0ea06ef4827078f9bcd52 (diff)
downloadchat-4f1dbb8ca9a6cce09c9a20e91e074feaadd755a8.tar.gz
chat-4f1dbb8ca9a6cce09c9a20e91e074feaadd755a8.tar.bz2
chat-4f1dbb8ca9a6cce09c9a20e91e074feaadd755a8.zip
Merge pull request #2052 from mattermost/PLT-1429
PLT-1429 adding user created slash commands
Diffstat (limited to 'store')
-rw-r--r--store/sql_command_store.go173
-rw-r--r--store/sql_command_store_test.go155
-rw-r--r--store/sql_store.go8
-rw-r--r--store/sql_webhook_store.go27
-rw-r--r--store/sql_webhook_store_test.go34
-rw-r--r--store/store.go13
6 files changed, 353 insertions, 57 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_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 2aa627734..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()
@@ -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