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