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  }