github.com/mattermost/mattermost-server/v5@v5.39.3/store/sqlstore/system_store.go (about) 1 // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved. 2 // See LICENSE.txt for license information. 3 4 package sqlstore 5 6 import ( 7 "context" 8 "database/sql" 9 "fmt" 10 "strconv" 11 "strings" 12 "time" 13 14 "github.com/pkg/errors" 15 16 "github.com/mattermost/mattermost-server/v5/model" 17 "github.com/mattermost/mattermost-server/v5/store" 18 "github.com/mattermost/mattermost-server/v5/utils" 19 ) 20 21 type SqlSystemStore struct { 22 *SqlStore 23 } 24 25 func newSqlSystemStore(sqlStore *SqlStore) store.SystemStore { 26 s := &SqlSystemStore{sqlStore} 27 28 for _, db := range sqlStore.GetAllConns() { 29 table := db.AddTableWithName(model.System{}, "Systems").SetKeys(false, "Name") 30 table.ColMap("Name").SetMaxSize(64) 31 table.ColMap("Value").SetMaxSize(1024) 32 } 33 34 return s 35 } 36 37 func (s SqlSystemStore) createIndexesIfNotExists() { 38 } 39 40 func (s SqlSystemStore) Save(system *model.System) error { 41 if err := s.GetMaster().Insert(system); err != nil { 42 return errors.Wrapf(err, "failed to save system property with name=%s", system.Name) 43 } 44 return nil 45 } 46 47 func (s SqlSystemStore) SaveOrUpdate(system *model.System) error { 48 if err := s.GetMaster().SelectOne(&model.System{}, "SELECT * FROM Systems WHERE Name = :Name", map[string]interface{}{"Name": system.Name}); err == nil { 49 if _, err := s.GetMaster().Update(system); err != nil { 50 return errors.Wrapf(err, "failed to update system property with name=%s", system.Name) 51 } 52 } else { 53 if err := s.GetMaster().Insert(system); err != nil { 54 return errors.Wrapf(err, "failed to save system property with name=%s", system.Name) 55 } 56 } 57 return nil 58 } 59 60 func (s SqlSystemStore) SaveOrUpdateWithWarnMetricHandling(system *model.System) error { 61 if err := s.GetMaster().SelectOne(&model.System{}, "SELECT * FROM Systems WHERE Name = :Name", map[string]interface{}{"Name": system.Name}); err == nil { 62 if _, err := s.GetMaster().Update(system); err != nil { 63 return errors.Wrapf(err, "failed to update system property with name=%s", system.Name) 64 } 65 } else { 66 if err := s.GetMaster().Insert(system); err != nil { 67 return errors.Wrapf(err, "failed to save system property with name=%s", system.Name) 68 } 69 } 70 71 if strings.HasPrefix(system.Name, model.WARN_METRIC_STATUS_STORE_PREFIX) && (system.Value == model.WARN_METRIC_STATUS_RUNONCE || system.Value == model.WARN_METRIC_STATUS_LIMIT_REACHED) { 72 if err := s.SaveOrUpdate(&model.System{Name: model.SYSTEM_WARN_METRIC_LAST_RUN_TIMESTAMP_KEY, Value: strconv.FormatInt(utils.MillisFromTime(time.Now()), 10)}); err != nil { 73 return errors.Wrapf(err, "failed to save system property with name=%s", model.SYSTEM_WARN_METRIC_LAST_RUN_TIMESTAMP_KEY) 74 } 75 } 76 77 return nil 78 } 79 80 func (s SqlSystemStore) Update(system *model.System) error { 81 if _, err := s.GetMaster().Update(system); err != nil { 82 return errors.Wrapf(err, "failed to update system property with name=%s", system.Name) 83 } 84 return nil 85 } 86 87 func (s SqlSystemStore) Get() (model.StringMap, error) { 88 var systems []model.System 89 props := make(model.StringMap) 90 if _, err := s.GetReplica().Select(&systems, "SELECT * FROM Systems"); err != nil { 91 return nil, errors.Wrap(err, "failed to system properties") 92 } 93 for _, prop := range systems { 94 props[prop.Name] = prop.Value 95 } 96 97 return props, nil 98 } 99 100 func (s SqlSystemStore) GetByName(name string) (*model.System, error) { 101 var system model.System 102 if err := s.GetMaster().SelectOne(&system, "SELECT * FROM Systems WHERE Name = :Name", map[string]interface{}{"Name": name}); err != nil { 103 if err == sql.ErrNoRows { 104 return nil, store.NewErrNotFound("System", fmt.Sprintf("name=%s", system.Name)) 105 } 106 return nil, errors.Wrapf(err, "failed to get system property with name=%s", system.Name) 107 } 108 109 return &system, nil 110 } 111 112 func (s SqlSystemStore) PermanentDeleteByName(name string) (*model.System, error) { 113 var system model.System 114 if _, err := s.GetMaster().Exec("DELETE FROM Systems WHERE Name = :Name", map[string]interface{}{"Name": name}); err != nil { 115 return nil, errors.Wrapf(err, "failed to permanent delete system property with name=%s", system.Name) 116 } 117 118 return &system, nil 119 } 120 121 // InsertIfExists inserts a given system value if it does not already exist. If a value 122 // already exists, it returns the old one, else returns the new one. 123 func (s SqlSystemStore) InsertIfExists(system *model.System) (*model.System, error) { 124 tx, err := s.GetMaster().BeginTx(context.Background(), &sql.TxOptions{ 125 Isolation: sql.LevelSerializable, 126 }) 127 if err != nil { 128 return nil, errors.Wrap(err, "begin_transaction") 129 } 130 defer finalizeTransaction(tx) 131 132 var origSystem model.System 133 if err := tx.SelectOne(&origSystem, `SELECT * FROM Systems 134 WHERE Name = :Name`, 135 map[string]interface{}{"Name": system.Name}); err != nil && err != sql.ErrNoRows { 136 return nil, errors.Wrapf(err, "failed to get system property with name=%s", system.Name) 137 } 138 139 if origSystem.Value != "" { 140 // Already a value exists, return that. 141 return &origSystem, nil 142 } 143 144 // Key does not exist, need to insert. 145 if err := tx.Insert(system); err != nil { 146 return nil, errors.Wrapf(err, "failed to save system property with name=%s", system.Name) 147 } 148 149 if err := tx.Commit(); err != nil { 150 return nil, errors.Wrap(err, "commit_transaction") 151 } 152 return system, nil 153 }