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  }