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