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