github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/modules/config/config.go (about) 1 package config 2 3 import ( 4 "context" 5 "encoding/json" 6 7 confid "github.com/machinefi/w3bstream/pkg/depends/conf/id" 8 "github.com/machinefi/w3bstream/pkg/depends/kit/sqlx" 9 "github.com/machinefi/w3bstream/pkg/depends/kit/sqlx/builder" 10 "github.com/machinefi/w3bstream/pkg/depends/kit/statusx" 11 "github.com/machinefi/w3bstream/pkg/enums" 12 "github.com/machinefi/w3bstream/pkg/errors/status" 13 "github.com/machinefi/w3bstream/pkg/models" 14 "github.com/machinefi/w3bstream/pkg/types" 15 "github.com/machinefi/w3bstream/pkg/types/wasm" 16 ) 17 18 func Marshal(c wasm.Configuration) (data []byte, err error) { 19 data, err = json.Marshal(c) 20 if err != nil { 21 err = status.ConfigParseFailed.StatusErr().WithDesc(err.Error()) 22 } 23 return 24 } 25 26 func Unmarshal(data []byte, typ enums.ConfigType) (c wasm.Configuration, err error) { 27 c, err = wasm.NewUserConfigurationByType(typ) 28 if err != nil { 29 return nil, status.InvalidConfigType.StatusErr().WithDesc(err.Error()) 30 } 31 if err = json.Unmarshal(data, c); err != nil { 32 return nil, status.ConfigParseFailed.StatusErr().WithDesc(err.Error()) 33 } 34 return c, nil 35 } 36 37 func GetBySFID(ctx context.Context, id types.SFID) (*models.Config, error) { 38 d := types.MustMgrDBExecutorFromContext(ctx) 39 m := &models.Config{RelConfig: models.RelConfig{ConfigID: id}} 40 41 if err := m.FetchByConfigID(d); err != nil { 42 if sqlx.DBErr(err).IsNotFound() { 43 return nil, status.ConfigNotFound 44 } 45 return nil, status.DatabaseError.StatusErr().WithDesc(err.Error()) 46 } 47 return m, nil 48 } 49 50 func GetValueBySFID(ctx context.Context, id types.SFID) (wasm.Configuration, error) { 51 m, err := GetBySFID(ctx, id) 52 if err != nil { 53 return nil, err 54 } 55 return Unmarshal(m.Value, m.Type) 56 } 57 58 func GetByRelAndType(ctx context.Context, id types.SFID, t enums.ConfigType) (*models.Config, error) { 59 d := types.MustMgrDBExecutorFromContext(ctx) 60 m := &models.Config{ConfigBase: models.ConfigBase{RelID: id, Type: t}} 61 v := &Detail{id, t} 62 63 if err := m.FetchByRelIDAndType(d); err != nil { 64 if sqlx.DBErr(err).IsNotFound() { 65 return nil, status.ConfigNotFound.StatusErr().WithDesc(v.Log(err)) 66 } 67 return nil, status.DatabaseError.StatusErr().WithDesc(v.Log(err)) 68 } 69 return m, nil 70 } 71 72 func GetValueByRelAndType(ctx context.Context, rel types.SFID, t enums.ConfigType) (wasm.Configuration, error) { 73 m, err := GetByRelAndType(ctx, rel, t) 74 if err != nil { 75 return nil, err 76 } 77 return Unmarshal(m.Value, t) 78 } 79 80 func Upsert(ctx context.Context, rel types.SFID, c wasm.Configuration) (*models.Config, error) { 81 var ( 82 d = types.MustMgrDBExecutorFromContext(ctx) 83 idg = confid.MustSFIDGeneratorFromContext(ctx) 84 v = &Detail{rel, c} 85 err error 86 m *models.Config 87 old wasm.Configuration 88 ) 89 90 err = sqlx.NewTasks(d).With( 91 func(d sqlx.DBExecutor) error { 92 m = &models.Config{ 93 ConfigBase: models.ConfigBase{RelID: rel, Type: c.ConfigType()}, 94 } 95 if err = m.FetchByRelIDAndType(d); err != nil { 96 if sqlx.DBErr(err).IsNotFound() { 97 return nil 98 } 99 return status.DatabaseError.StatusErr().WithDesc(v.Log(err)) 100 } 101 if old, err = Unmarshal(m.Value, c.ConfigType()); err != nil { 102 return err 103 } 104 if err = wasm.UninitConfiguration(ctx, old); err != nil { 105 return status.ConfigUninitFailed.StatusErr().WithDesc(v.Log(err)) 106 } 107 return nil 108 }, 109 func(d sqlx.DBExecutor) error { 110 var raw []byte 111 raw, err = Marshal(c) 112 if err != nil { 113 return err 114 } 115 if old == nil { 116 m = &models.Config{ 117 RelConfig: models.RelConfig{ConfigID: idg.MustGenSFID()}, 118 ConfigBase: models.ConfigBase{ 119 Type: c.ConfigType(), RelID: rel, Value: raw, 120 }, 121 } 122 err = m.Create(d) 123 } else { 124 m.Value = raw 125 err = m.UpdateByRelIDAndType(d) 126 } 127 if err != nil { 128 if sqlx.DBErr(err).IsConflict() { 129 return status.ConfigConflict.StatusErr().WithDesc(v.Log(err)) 130 } 131 return status.DatabaseError.StatusErr().WithDesc(err.Error()) 132 } 133 return nil 134 }, 135 func(d sqlx.DBExecutor) error { 136 if err = wasm.InitConfiguration(ctx, c); err != nil { 137 return status.ConfigInitFailed.StatusErr().WithDesc(v.Log(err)) 138 } 139 return nil 140 }, 141 ).Do() 142 143 if err != nil { 144 return nil, err 145 } 146 return m, nil 147 } 148 149 func List(ctx context.Context, r *CondArgs) ([]*Detail, error) { 150 var ( 151 d = types.MustMgrDBExecutorFromContext(ctx) 152 m = &models.Config{} 153 c wasm.Configuration 154 ) 155 156 lst, err := m.List(d, r.Condition()) 157 if err != nil { 158 return nil, status.DatabaseError.StatusErr().WithDesc(err.Error()) 159 } 160 161 configs := make([]*Detail, 0, len(lst)) 162 for _, cfg := range lst { 163 c, err = Unmarshal(cfg.Value, cfg.Type) 164 if err != nil { 165 return nil, err 166 } 167 configs = append(configs, &Detail{RelID: cfg.RelID, Configuration: c}) 168 } 169 return configs, nil 170 } 171 172 func Remove(ctx context.Context, r *CondArgs) error { 173 var ( 174 d = types.MustMgrDBExecutorFromContext(ctx) 175 m = &models.Config{} 176 lst []*Detail 177 err error 178 ) 179 180 return sqlx.NewTasks(d).With( 181 func(d sqlx.DBExecutor) error { 182 ctx := types.WithMgrDBExecutor(ctx, d) 183 lst, err = List(ctx, r) 184 return err 185 }, 186 func(d sqlx.DBExecutor) error { 187 if _, err = d.Exec( 188 builder.Delete().From(d.T(m), builder.Where(r.Condition())), 189 ); err != nil { 190 return status.DatabaseError.StatusErr().WithDesc(err.Error()) 191 } 192 return nil 193 }, 194 func(db sqlx.DBExecutor) error { 195 summary := make(statusx.ErrorFields, 0, len(lst)) 196 for _, c := range lst { 197 err2 := wasm.UninitConfiguration(ctx, c.Configuration) 198 if err2 != nil { 199 summary = append(summary, &statusx.ErrorField{ 200 Field: c.String(), Msg: err2.Error(), 201 }) 202 } 203 } 204 if len(summary) > 0 { 205 return status.ConfigUninitFailed.StatusErr(). 206 AppendErrorFields(summary...) 207 } 208 return nil 209 }, 210 ).Do() 211 } 212 213 func Create(ctx context.Context, id types.SFID, c wasm.Configuration) (*models.Config, error) { 214 var ( 215 d = types.MustMgrDBExecutorFromContext(ctx) 216 v = &Detail{id, c} 217 ) 218 219 raw, err := Marshal(c) 220 if err != nil { 221 return nil, err 222 } 223 224 m := &models.Config{ 225 RelConfig: models.RelConfig{ 226 ConfigID: confid.MustSFIDGeneratorFromContext(ctx).MustGenSFID(), 227 }, 228 ConfigBase: models.ConfigBase{ 229 RelID: id, Type: c.ConfigType(), Value: raw, 230 }, 231 } 232 233 err = sqlx.NewTasks(d).With( 234 func(db sqlx.DBExecutor) error { 235 if err = m.Create(d); err != nil { 236 if sqlx.DBErr(err).IsConflict() { 237 return status.ConfigConflict.StatusErr().WithDesc(v.Log(err)) 238 } 239 return status.DatabaseError.StatusErr().WithDesc(err.Error()) 240 } 241 return nil 242 }, 243 func(db sqlx.DBExecutor) error { 244 if err = wasm.InitConfiguration(ctx, c); err != nil { 245 return status.ConfigInitFailed.StatusErr(). 246 WithDesc(v.Log(err)) 247 } 248 return nil 249 }, 250 ).Do() 251 if err != nil { 252 return nil, err 253 } 254 return m, nil 255 }