github.com/leg100/ots@v0.0.7-0.20210919080622-034055ced4bd/sqlite/apply_model.go (about)

     1  package sqlite
     2  
     3  import (
     4  	"database/sql"
     5  
     6  	"github.com/leg100/go-tfe"
     7  	"github.com/leg100/ots"
     8  	"gorm.io/gorm"
     9  )
    10  
    11  // Apply models a row in an applies table.
    12  type Apply struct {
    13  	gorm.Model
    14  
    15  	ExternalID string `gorm:"uniqueIndex"`
    16  
    17  	ResourceAdditions    int
    18  	ResourceChanges      int
    19  	ResourceDestructions int
    20  	Status               tfe.ApplyStatus
    21  	StatusTimestamps     *ApplyStatusTimestamps `gorm:"embedded;embeddedPrefix:timestamp_"`
    22  
    23  	LogsBlobID string
    24  
    25  	// Apply belongs to a run
    26  	RunID uint
    27  }
    28  
    29  // ApplyList is a list of run models
    30  type ApplyList []Apply
    31  
    32  // ApplyStatusTimestamps holds the timestamps for individual apply statuses.
    33  type ApplyStatusTimestamps struct {
    34  	CanceledAt      sql.NullTime
    35  	ErroredAt       sql.NullTime
    36  	FinishedAt      sql.NullTime
    37  	ForceCanceledAt sql.NullTime
    38  	QueuedAt        sql.NullTime
    39  	StartedAt       sql.NullTime
    40  }
    41  
    42  // Update updates the model with the supplied fn. The fn operates on the domain
    43  // obj, so Update handles converting to and from a domain obj.
    44  func (model *Apply) Update(fn func(*ots.Apply) error) error {
    45  	// model -> domain
    46  	domain := model.ToDomain()
    47  
    48  	// invoke user fn
    49  	if err := fn(domain); err != nil {
    50  		return err
    51  	}
    52  
    53  	// domain -> model
    54  	model.FromDomain(domain)
    55  
    56  	return nil
    57  }
    58  
    59  func (model *Apply) ToDomain() *ots.Apply {
    60  	domain := ots.Apply{
    61  		ID:                   model.ExternalID,
    62  		Model:                model.Model,
    63  		ResourceAdditions:    model.ResourceAdditions,
    64  		ResourceChanges:      model.ResourceChanges,
    65  		ResourceDestructions: model.ResourceDestructions,
    66  		Status:               model.Status,
    67  		StatusTimestamps:     &tfe.ApplyStatusTimestamps{},
    68  		LogsBlobID:           model.LogsBlobID,
    69  	}
    70  
    71  	if model.StatusTimestamps.CanceledAt.Valid {
    72  		domain.StatusTimestamps.CanceledAt = &model.StatusTimestamps.CanceledAt.Time
    73  	}
    74  
    75  	if model.StatusTimestamps.ErroredAt.Valid {
    76  		domain.StatusTimestamps.ErroredAt = &model.StatusTimestamps.ErroredAt.Time
    77  	}
    78  
    79  	if model.StatusTimestamps.FinishedAt.Valid {
    80  		domain.StatusTimestamps.FinishedAt = &model.StatusTimestamps.FinishedAt.Time
    81  	}
    82  
    83  	if model.StatusTimestamps.ForceCanceledAt.Valid {
    84  		domain.StatusTimestamps.ForceCanceledAt = &model.StatusTimestamps.ForceCanceledAt.Time
    85  	}
    86  
    87  	if model.StatusTimestamps.QueuedAt.Valid {
    88  		domain.StatusTimestamps.QueuedAt = &model.StatusTimestamps.QueuedAt.Time
    89  	}
    90  
    91  	if model.StatusTimestamps.StartedAt.Valid {
    92  		domain.StatusTimestamps.StartedAt = &model.StatusTimestamps.StartedAt.Time
    93  	}
    94  
    95  	return &domain
    96  }
    97  
    98  // FromDomain updates run model fields with a run domain object's fields
    99  func (model *Apply) FromDomain(domain *ots.Apply) {
   100  	model.ExternalID = domain.ID
   101  	model.Model = domain.Model
   102  	model.ResourceAdditions = domain.ResourceAdditions
   103  	model.ResourceChanges = domain.ResourceChanges
   104  	model.ResourceDestructions = domain.ResourceDestructions
   105  	model.Status = domain.Status
   106  	model.LogsBlobID = domain.LogsBlobID
   107  
   108  	if domain.StatusTimestamps.CanceledAt != nil {
   109  		model.StatusTimestamps.CanceledAt.Time = *domain.StatusTimestamps.CanceledAt
   110  		model.StatusTimestamps.CanceledAt.Valid = true
   111  	}
   112  
   113  	if domain.StatusTimestamps.ErroredAt != nil {
   114  		model.StatusTimestamps.ErroredAt.Time = *domain.StatusTimestamps.ErroredAt
   115  		model.StatusTimestamps.ErroredAt.Valid = true
   116  	}
   117  
   118  	if domain.StatusTimestamps.FinishedAt != nil {
   119  		model.StatusTimestamps.FinishedAt.Time = *domain.StatusTimestamps.FinishedAt
   120  		model.StatusTimestamps.FinishedAt.Valid = true
   121  	}
   122  
   123  	if domain.StatusTimestamps.ForceCanceledAt != nil {
   124  		model.StatusTimestamps.ForceCanceledAt.Time = *domain.StatusTimestamps.ForceCanceledAt
   125  		model.StatusTimestamps.ForceCanceledAt.Valid = true
   126  	}
   127  
   128  	if domain.StatusTimestamps.QueuedAt != nil {
   129  		model.StatusTimestamps.QueuedAt.Time = *domain.StatusTimestamps.QueuedAt
   130  		model.StatusTimestamps.QueuedAt.Valid = true
   131  	}
   132  
   133  	if domain.StatusTimestamps.StartedAt != nil {
   134  		model.StatusTimestamps.StartedAt.Time = *domain.StatusTimestamps.StartedAt
   135  		model.StatusTimestamps.StartedAt.Valid = true
   136  	}
   137  }
   138  
   139  func (l ApplyList) ToDomain() (dl []*ots.Apply) {
   140  	for _, i := range l {
   141  		dl = append(dl, i.ToDomain())
   142  	}
   143  	return
   144  }