github.com/mattermosttest/mattermost-server/v5@v5.0.0-20200917143240-9dfa12e121f9/store/sqlstore/job_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 "database/sql" 8 "net/http" 9 10 sq "github.com/Masterminds/squirrel" 11 12 "github.com/mattermost/gorp" 13 "github.com/mattermost/mattermost-server/v5/model" 14 "github.com/mattermost/mattermost-server/v5/store" 15 ) 16 17 type SqlJobStore struct { 18 SqlStore 19 } 20 21 func newSqlJobStore(sqlStore SqlStore) store.JobStore { 22 s := &SqlJobStore{sqlStore} 23 24 for _, db := range sqlStore.GetAllConns() { 25 table := db.AddTableWithName(model.Job{}, "Jobs").SetKeys(false, "Id") 26 table.ColMap("Id").SetMaxSize(26) 27 table.ColMap("Type").SetMaxSize(32) 28 table.ColMap("Status").SetMaxSize(32) 29 table.ColMap("Data").SetMaxSize(1024) 30 } 31 32 return s 33 } 34 35 func (jss SqlJobStore) createIndexesIfNotExists() { 36 jss.CreateIndexIfNotExists("idx_jobs_type", "Jobs", "Type") 37 } 38 39 func (jss SqlJobStore) Save(job *model.Job) (*model.Job, *model.AppError) { 40 if err := jss.GetMaster().Insert(job); err != nil { 41 return nil, model.NewAppError("SqlJobStore.Save", "store.sql_job.save.app_error", nil, "id="+job.Id+", "+err.Error(), http.StatusInternalServerError) 42 } 43 return job, nil 44 } 45 46 func (jss SqlJobStore) UpdateOptimistically(job *model.Job, currentStatus string) (bool, *model.AppError) { 47 sql, args, err := jss.getQueryBuilder(). 48 Update("Jobs"). 49 Set("LastActivityAt", model.GetMillis()). 50 Set("Status", job.Status). 51 Set("Data", job.DataToJson()). 52 Set("Progress", job.Progress). 53 Where(sq.Eq{"Id": job.Id, "Status": currentStatus}).ToSql() 54 if err != nil { 55 return false, model.NewAppError("SqlJobStore.UpdateOptimistically", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 56 } 57 sqlResult, err := jss.GetMaster().Exec(sql, args...) 58 if err != nil { 59 return false, model.NewAppError("SqlJobStore.UpdateOptimistically", "store.sql_job.update.app_error", nil, "id="+job.Id+", "+err.Error(), http.StatusInternalServerError) 60 } 61 62 rows, err := sqlResult.RowsAffected() 63 64 if err != nil { 65 return false, model.NewAppError("SqlJobStore.UpdateStatus", "store.sql_job.update.app_error", nil, "id="+job.Id+", "+err.Error(), http.StatusInternalServerError) 66 } 67 68 if rows != 1 { 69 return false, nil 70 } 71 72 return true, nil 73 } 74 75 func (jss SqlJobStore) UpdateStatus(id string, status string) (*model.Job, *model.AppError) { 76 job := &model.Job{ 77 Id: id, 78 Status: status, 79 LastActivityAt: model.GetMillis(), 80 } 81 82 if _, err := jss.GetMaster().UpdateColumns(func(col *gorp.ColumnMap) bool { 83 return col.ColumnName == "Status" || col.ColumnName == "LastActivityAt" 84 }, job); err != nil { 85 return nil, model.NewAppError("SqlJobStore.UpdateStatus", "store.sql_job.update.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 86 } 87 88 return job, nil 89 } 90 91 func (jss SqlJobStore) UpdateStatusOptimistically(id string, currentStatus string, newStatus string) (bool, *model.AppError) { 92 sql := jss.getQueryBuilder(). 93 Update("Jobs"). 94 Set("LastActivityAt", model.GetMillis()). 95 Set("Status", newStatus). 96 Where(sq.Eq{"Id": id, "Status": currentStatus}) 97 98 if newStatus == model.JOB_STATUS_IN_PROGRESS { 99 sql = sql.Set("StartAt", model.GetMillis()) 100 } 101 query, args, err := sql.ToSql() 102 if err != nil { 103 return false, model.NewAppError("SqlJobStore.UpdateStatusOptimistically", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 104 } 105 106 sqlResult, err := jss.GetMaster().Exec(query, args...) 107 if err != nil { 108 return false, model.NewAppError("SqlJobStore.UpdateStatusOptimistically", "store.sql_job.update.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 109 } 110 rows, err := sqlResult.RowsAffected() 111 if err != nil { 112 return false, model.NewAppError("SqlJobStore.UpdateStatus", "store.sql_job.update.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 113 } 114 if rows != 1 { 115 return false, nil 116 } 117 118 return true, nil 119 } 120 121 func (jss SqlJobStore) Get(id string) (*model.Job, *model.AppError) { 122 query, args, err := jss.getQueryBuilder(). 123 Select("*"). 124 From("Jobs"). 125 Where(sq.Eq{"Id": id}).ToSql() 126 if err != nil { 127 return nil, model.NewAppError("SqlJobStore.Get", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 128 } 129 var status *model.Job 130 if err = jss.GetReplica().SelectOne(&status, query, args...); err != nil { 131 if err == sql.ErrNoRows { 132 return nil, model.NewAppError("SqlJobStore.Get", "store.sql_job.get.app_error", nil, "Id="+id+", "+err.Error(), http.StatusNotFound) 133 } 134 return nil, model.NewAppError("SqlJobStore.Get", "store.sql_job.get.app_error", nil, "Id="+id+", "+err.Error(), http.StatusInternalServerError) 135 } 136 return status, nil 137 } 138 139 func (jss SqlJobStore) GetAllPage(offset int, limit int) ([]*model.Job, *model.AppError) { 140 query, args, err := jss.getQueryBuilder(). 141 Select("*"). 142 From("Jobs"). 143 OrderBy("CreateAt DESC"). 144 Limit(uint64(limit)). 145 Offset(uint64(offset)).ToSql() 146 if err != nil { 147 return nil, model.NewAppError("SqlJobStore.GetAllPage", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 148 } 149 150 var statuses []*model.Job 151 if _, err = jss.GetReplica().Select(&statuses, query, args...); err != nil { 152 return nil, model.NewAppError("SqlJobStore.GetAllPage", "store.sql_job.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 153 } 154 return statuses, nil 155 } 156 157 func (jss SqlJobStore) GetAllByType(jobType string) ([]*model.Job, *model.AppError) { 158 query, args, err := jss.getQueryBuilder(). 159 Select("*"). 160 From("Jobs"). 161 Where(sq.Eq{"Type": jobType}). 162 OrderBy("CreateAt DESC").ToSql() 163 if err != nil { 164 return nil, model.NewAppError("SqlJobStore.GetAllByType", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 165 } 166 var statuses []*model.Job 167 if _, err = jss.GetReplica().Select(&statuses, query, args...); err != nil { 168 return nil, model.NewAppError("SqlJobStore.GetAllByType", "store.sql_job.get_all.app_error", nil, "Type="+jobType+", "+err.Error(), http.StatusInternalServerError) 169 } 170 return statuses, nil 171 } 172 173 func (jss SqlJobStore) GetAllByTypePage(jobType string, offset int, limit int) ([]*model.Job, *model.AppError) { 174 query, args, err := jss.getQueryBuilder(). 175 Select("*"). 176 From("Jobs"). 177 Where(sq.Eq{"Type": jobType}). 178 OrderBy("CreateAt DESC"). 179 Limit(uint64(limit)). 180 Offset(uint64(offset)).ToSql() 181 if err != nil { 182 return nil, model.NewAppError("SqlJobStore.GetAllByTypePage", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 183 } 184 185 var statuses []*model.Job 186 if _, err = jss.GetReplica().Select(&statuses, query, args...); err != nil { 187 return nil, model.NewAppError("SqlJobStore.GetAllByTypePage", "store.sql_job.get_all.app_error", nil, "Type="+jobType+", "+err.Error(), http.StatusInternalServerError) 188 } 189 return statuses, nil 190 } 191 192 func (jss SqlJobStore) GetAllByStatus(status string) ([]*model.Job, *model.AppError) { 193 var statuses []*model.Job 194 query, args, err := jss.getQueryBuilder(). 195 Select("*"). 196 From("Jobs"). 197 Where(sq.Eq{"Status": status}). 198 OrderBy("CreateAt ASC").ToSql() 199 if err != nil { 200 return nil, model.NewAppError("SqlJobStore.GetAllByStatus", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 201 } 202 203 if _, err = jss.GetReplica().Select(&statuses, query, args...); err != nil { 204 return nil, model.NewAppError("SqlJobStore.GetAllByStatus", "store.sql_job.get_all.app_error", nil, "Status="+status+", "+err.Error(), http.StatusInternalServerError) 205 } 206 return statuses, nil 207 } 208 209 func (jss SqlJobStore) GetNewestJobByStatusAndType(status string, jobType string) (*model.Job, *model.AppError) { 210 query, args, err := jss.getQueryBuilder(). 211 Select("*"). 212 From("Jobs"). 213 Where(sq.Eq{"Status": status, "Type": jobType}). 214 OrderBy("CreateAt DESC"). 215 Limit(1).ToSql() 216 if err != nil { 217 return nil, model.NewAppError("SqlJobStore.GetNewestJobByStatusAndType", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 218 } 219 220 var job *model.Job 221 if err = jss.GetReplica().SelectOne(&job, query, args...); err != nil && err != sql.ErrNoRows { 222 return nil, model.NewAppError("SqlJobStore.GetNewestJobByStatusAndType", "store.sql_job.get_newest_job_by_status_and_type.app_error", nil, "Status="+status+", "+err.Error(), http.StatusInternalServerError) 223 } 224 return job, nil 225 } 226 227 func (jss SqlJobStore) GetCountByStatusAndType(status string, jobType string) (int64, *model.AppError) { 228 query, args, err := jss.getQueryBuilder(). 229 Select("COUNT(*)"). 230 From("Jobs"). 231 Where(sq.Eq{"Status": status, "Type": jobType}).ToSql() 232 if err != nil { 233 return 0, model.NewAppError("SqlJobStore.GetCountByStatusAndType", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 234 } 235 count, err := jss.GetReplica().SelectInt(query, args...) 236 if err != nil { 237 return int64(0), model.NewAppError("SqlJobStore.GetCountByStatusAndType", "store.sql_job.get_count_by_status_and_type.app_error", nil, "Status="+status+", "+err.Error(), http.StatusInternalServerError) 238 } 239 return count, nil 240 } 241 242 func (jss SqlJobStore) Delete(id string) (string, *model.AppError) { 243 sql, args, err := jss.getQueryBuilder(). 244 Delete("Jobs"). 245 Where(sq.Eq{"Id": id}).ToSql() 246 if err != nil { 247 return "", model.NewAppError("SqlJobStore.DeleteByType", "store.sql.build_query.app_error", nil, err.Error(), http.StatusInternalServerError) 248 } 249 250 if _, err = jss.GetMaster().Exec(sql, args...); err != nil { 251 return "", model.NewAppError("SqlJobStore.DeleteByType", "store.sql_job.delete.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 252 } 253 return id, nil 254 }