github.com/vnforks/kid/v5@v5.22.1-0.20200408055009-b89d99c65676/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 "github.com/mattermost/gorp" 11 "github.com/vnforks/kid/v5/model" 12 "github.com/vnforks/kid/v5/store" 13 ) 14 15 type SqlJobStore struct { 16 SqlStore 17 } 18 19 func newSqlJobStore(sqlStore SqlStore) store.JobStore { 20 s := &SqlJobStore{sqlStore} 21 22 for _, db := range sqlStore.GetAllConns() { 23 table := db.AddTableWithName(model.Job{}, "Jobs").SetKeys(false, "Id") 24 table.ColMap("Id").SetMaxSize(26) 25 table.ColMap("Type").SetMaxSize(32) 26 table.ColMap("Status").SetMaxSize(32) 27 table.ColMap("Data").SetMaxSize(1024) 28 } 29 30 return s 31 } 32 33 func (jss SqlJobStore) createIndexesIfNotExists() { 34 jss.CreateIndexIfNotExists("idx_jobs_type", "Jobs", "Type") 35 } 36 37 func (jss SqlJobStore) Save(job *model.Job) (*model.Job, *model.AppError) { 38 if err := jss.GetMaster().Insert(job); err != nil { 39 return nil, model.NewAppError("SqlJobStore.Save", "store.sql_job.save.app_error", nil, "id="+job.Id+", "+err.Error(), http.StatusInternalServerError) 40 } 41 return job, nil 42 } 43 44 func (jss SqlJobStore) UpdateOptimistically(job *model.Job, currentStatus string) (bool, *model.AppError) { 45 query := "UPDATE Jobs SET LastActivityAt = :LastActivityAt, Status = :Status, Progress = :Progress, Data = :Data WHERE Id = :Id AND Status = :OldStatus" 46 params := map[string]interface{}{ 47 "Id": job.Id, 48 "OldStatus": currentStatus, 49 "LastActivityAt": model.GetMillis(), 50 "Status": job.Status, 51 "Data": job.DataToJson(), 52 "Progress": job.Progress, 53 } 54 sqlResult, err := jss.GetMaster().Exec(query, params) 55 if err != nil { 56 return false, model.NewAppError("SqlJobStore.UpdateOptimistically", "store.sql_job.update.app_error", nil, "id="+job.Id+", "+err.Error(), http.StatusInternalServerError) 57 } 58 59 rows, err := sqlResult.RowsAffected() 60 61 if err != nil { 62 return false, model.NewAppError("SqlJobStore.UpdateStatus", "store.sql_job.update.app_error", nil, "id="+job.Id+", "+err.Error(), http.StatusInternalServerError) 63 } 64 65 if rows != 1 { 66 return false, nil 67 } 68 69 return true, nil 70 } 71 72 func (jss SqlJobStore) UpdateStatus(id string, status string) (*model.Job, *model.AppError) { 73 job := &model.Job{ 74 Id: id, 75 Status: status, 76 LastActivityAt: model.GetMillis(), 77 } 78 79 if _, err := jss.GetMaster().UpdateColumns(func(col *gorp.ColumnMap) bool { 80 return col.ColumnName == "Status" || col.ColumnName == "LastActivityAt" 81 }, job); err != nil { 82 return nil, model.NewAppError("SqlJobStore.UpdateStatus", "store.sql_job.update.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 83 } 84 85 return job, nil 86 } 87 88 func (jss SqlJobStore) UpdateStatusOptimistically(id string, currentStatus string, newStatus string) (bool, *model.AppError) { 89 var startAtClause string 90 if newStatus == model.JOB_STATUS_IN_PROGRESS { 91 startAtClause = "StartAt = :StartAt," 92 } 93 query := "UPDATE Jobs SET " + startAtClause + " Status = :NewStatus, LastActivityAt = :LastActivityAt WHERE Id = :Id AND Status = :OldStatus" 94 params := map[string]interface{}{ 95 "Id": id, 96 "OldStatus": currentStatus, 97 "NewStatus": newStatus, 98 "StartAt": model.GetMillis(), 99 "LastActivityAt": model.GetMillis(), 100 } 101 102 sqlResult, err := jss.GetMaster().Exec(query, params) 103 if err != nil { 104 return false, model.NewAppError("SqlJobStore.UpdateStatus", "store.sql_job.update.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 105 } 106 rows, err := sqlResult.RowsAffected() 107 if err != nil { 108 return false, model.NewAppError("SqlJobStore.UpdateStatus", "store.sql_job.update.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 109 } 110 if rows != 1 { 111 return false, nil 112 } 113 114 return true, nil 115 } 116 117 func (jss SqlJobStore) Get(id string) (*model.Job, *model.AppError) { 118 query := "SELECT * FROM Jobs WHERE Id = :Id" 119 120 var status *model.Job 121 if err := jss.GetReplica().SelectOne(&status, query, map[string]interface{}{"Id": id}); err != nil { 122 if err == sql.ErrNoRows { 123 return nil, model.NewAppError("SqlJobStore.Get", "store.sql_job.get.app_error", nil, "Id="+id+", "+err.Error(), http.StatusNotFound) 124 } 125 return nil, model.NewAppError("SqlJobStore.Get", "store.sql_job.get.app_error", nil, "Id="+id+", "+err.Error(), http.StatusInternalServerError) 126 } 127 return status, nil 128 } 129 130 func (jss SqlJobStore) GetAllPage(offset int, limit int) ([]*model.Job, *model.AppError) { 131 query := "SELECT * FROM Jobs ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset" 132 133 var statuses []*model.Job 134 if _, err := jss.GetReplica().Select(&statuses, query, map[string]interface{}{"Limit": limit, "Offset": offset}); err != nil { 135 return nil, model.NewAppError("SqlJobStore.GetAllPage", "store.sql_job.get_all.app_error", nil, err.Error(), http.StatusInternalServerError) 136 } 137 return statuses, nil 138 } 139 140 func (jss SqlJobStore) GetAllByType(jobType string) ([]*model.Job, *model.AppError) { 141 query := "SELECT * FROM Jobs WHERE Type = :Type ORDER BY CreateAt DESC" 142 var statuses []*model.Job 143 if _, err := jss.GetReplica().Select(&statuses, query, map[string]interface{}{"Type": jobType}); err != nil { 144 return nil, model.NewAppError("SqlJobStore.GetAllByType", "store.sql_job.get_all.app_error", nil, "Type="+jobType+", "+err.Error(), http.StatusInternalServerError) 145 } 146 return statuses, nil 147 } 148 149 func (jss SqlJobStore) GetAllByTypePage(jobType string, offset int, limit int) ([]*model.Job, *model.AppError) { 150 query := "SELECT * FROM Jobs WHERE Type = :Type ORDER BY CreateAt DESC LIMIT :Limit OFFSET :Offset" 151 152 var statuses []*model.Job 153 if _, err := jss.GetReplica().Select(&statuses, query, map[string]interface{}{"Type": jobType, "Limit": limit, "Offset": offset}); err != nil { 154 return nil, model.NewAppError("SqlJobStore.GetAllByTypePage", "store.sql_job.get_all.app_error", nil, "Type="+jobType+", "+err.Error(), http.StatusInternalServerError) 155 } 156 return statuses, nil 157 } 158 159 func (jss SqlJobStore) GetAllByStatus(status string) ([]*model.Job, *model.AppError) { 160 var statuses []*model.Job 161 query := "SELECT * FROM Jobs WHERE Status = :Status ORDER BY CreateAt ASC" 162 163 if _, err := jss.GetReplica().Select(&statuses, query, map[string]interface{}{"Status": status}); err != nil { 164 return nil, model.NewAppError("SqlJobStore.GetAllByStatus", "store.sql_job.get_all.app_error", nil, "Status="+status+", "+err.Error(), http.StatusInternalServerError) 165 } 166 return statuses, nil 167 } 168 169 func (jss SqlJobStore) GetNewestJobByStatusAndType(status string, jobType string) (*model.Job, *model.AppError) { 170 query := "SELECT * FROM Jobs WHERE Status = :Status AND Type = :Type ORDER BY CreateAt DESC LIMIT 1" 171 172 var job *model.Job 173 if err := jss.GetReplica().SelectOne(&job, query, map[string]interface{}{"Status": status, "Type": jobType}); err != nil && err != sql.ErrNoRows { 174 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) 175 } 176 return job, nil 177 } 178 179 func (jss SqlJobStore) GetCountByStatusAndType(status string, jobType string) (int64, *model.AppError) { 180 query := "SELECT COUNT(*) FROM Jobs WHERE Status = :Status AND Type = :Type" 181 count, err := jss.GetReplica().SelectInt(query, map[string]interface{}{"Status": status, "Type": jobType}) 182 if err != nil { 183 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) 184 } 185 return count, nil 186 } 187 188 func (jss SqlJobStore) Delete(id string) (string, *model.AppError) { 189 query := "DELETE FROM Jobs WHERE Id = :Id" 190 if _, err := jss.GetMaster().Exec(query, map[string]interface{}{"Id": id}); err != nil { 191 return "", model.NewAppError("SqlJobStore.DeleteByType", "store.sql_job.delete.app_error", nil, "id="+id+", "+err.Error(), http.StatusInternalServerError) 192 } 193 return id, nil 194 }