github.com/qichengzx/mattermost-server@v4.5.1-0.20180604164826-2c75247c97d0+incompatible/store/sqlstore/plugin_store.go (about) 1 // Copyright (c) 2017-present Mattermost, Inc. All Rights Reserved. 2 // See License.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "database/sql" 8 "fmt" 9 "net/http" 10 11 "github.com/mattermost/mattermost-server/model" 12 "github.com/mattermost/mattermost-server/store" 13 ) 14 15 type SqlPluginStore struct { 16 SqlStore 17 } 18 19 func NewSqlPluginStore(sqlStore SqlStore) store.PluginStore { 20 s := &SqlPluginStore{sqlStore} 21 22 for _, db := range sqlStore.GetAllConns() { 23 table := db.AddTableWithName(model.PluginKeyValue{}, "PluginKeyValueStore").SetKeys(false, "PluginId", "Key") 24 table.ColMap("PluginId").SetMaxSize(190) 25 table.ColMap("Key").SetMaxSize(50) 26 table.ColMap("Value").SetMaxSize(8192) 27 } 28 29 return s 30 } 31 32 func (ps SqlPluginStore) CreateIndexesIfNotExists() { 33 } 34 35 func (ps SqlPluginStore) SaveOrUpdate(kv *model.PluginKeyValue) store.StoreChannel { 36 return store.Do(func(result *store.StoreResult) { 37 if result.Err = kv.IsValid(); result.Err != nil { 38 return 39 } 40 41 if ps.DriverName() == model.DATABASE_DRIVER_POSTGRES { 42 // Unfortunately PostgreSQL pre-9.5 does not have an atomic upsert, so we use 43 // separate update and insert queries to accomplish our upsert 44 if rowsAffected, err := ps.GetMaster().Update(kv); err != nil { 45 result.Err = model.NewAppError("SqlPluginStore.SaveOrUpdate", "store.sql_plugin_store.save.app_error", nil, err.Error(), http.StatusInternalServerError) 46 return 47 } else if rowsAffected == 0 { 48 // No rows were affected by the update, so let's try an insert 49 if err := ps.GetMaster().Insert(kv); err != nil { 50 // If the error is from unique constraints violation, it's the result of a 51 // valid race and we can report success. Otherwise we have a real error and 52 // need to return it 53 if !IsUniqueConstraintError(err, []string{"PRIMARY", "PluginId", "Key", "PKey"}) { 54 result.Err = model.NewAppError("SqlPluginStore.SaveOrUpdate", "store.sql_plugin_store.save.app_error", nil, err.Error(), http.StatusInternalServerError) 55 return 56 } 57 } 58 } 59 } else if ps.DriverName() == model.DATABASE_DRIVER_MYSQL { 60 if _, err := ps.GetMaster().Exec("INSERT INTO PluginKeyValueStore (PluginId, PKey, PValue) VALUES(:PluginId, :Key, :Value) ON DUPLICATE KEY UPDATE PValue = :Value", map[string]interface{}{"PluginId": kv.PluginId, "Key": kv.Key, "Value": kv.Value}); err != nil { 61 result.Err = model.NewAppError("SqlPluginStore.SaveOrUpdate", "store.sql_plugin_store.save.app_error", nil, err.Error(), http.StatusInternalServerError) 62 return 63 } 64 } 65 66 result.Data = kv 67 }) 68 } 69 70 func (ps SqlPluginStore) Get(pluginId, key string) store.StoreChannel { 71 return store.Do(func(result *store.StoreResult) { 72 var kv *model.PluginKeyValue 73 74 if err := ps.GetReplica().SelectOne(&kv, "SELECT * FROM PluginKeyValueStore WHERE PluginId = :PluginId AND PKey = :Key", map[string]interface{}{"PluginId": pluginId, "Key": key}); err != nil { 75 if err == sql.ErrNoRows { 76 result.Err = model.NewAppError("SqlPluginStore.Get", "store.sql_plugin_store.get.app_error", nil, fmt.Sprintf("plugin_id=%v, key=%v, err=%v", pluginId, key, err.Error()), http.StatusNotFound) 77 } else { 78 result.Err = model.NewAppError("SqlPluginStore.Get", "store.sql_plugin_store.get.app_error", nil, fmt.Sprintf("plugin_id=%v, key=%v, err=%v", pluginId, key, err.Error()), http.StatusInternalServerError) 79 } 80 } else { 81 result.Data = kv 82 } 83 }) 84 } 85 86 func (ps SqlPluginStore) Delete(pluginId, key string) store.StoreChannel { 87 return store.Do(func(result *store.StoreResult) { 88 if _, err := ps.GetMaster().Exec("DELETE FROM PluginKeyValueStore WHERE PluginId = :PluginId AND PKey = :Key", map[string]interface{}{"PluginId": pluginId, "Key": key}); err != nil { 89 result.Err = model.NewAppError("SqlPluginStore.Delete", "store.sql_plugin_store.delete.app_error", nil, fmt.Sprintf("plugin_id=%v, key=%v, err=%v", pluginId, key, err.Error()), http.StatusInternalServerError) 90 } else { 91 result.Data = true 92 } 93 }) 94 }