gitee.com/h79/goutils@v1.22.10/dao/dao.go (about) 1 package dao 2 3 import ( 4 "context" 5 "errors" 6 "fmt" 7 commonoption "gitee.com/h79/goutils/common/option" 8 "gitee.com/h79/goutils/common/result" 9 "gitee.com/h79/goutils/common/stringutil" 10 "gitee.com/h79/goutils/dao/db" 11 "gitee.com/h79/goutils/dao/option" 12 "gitee.com/h79/goutils/dao/redis" 13 "gitee.com/h79/goutils/dao/util" 14 "gitee.com/h79/goutils/dao/wrapper" 15 "gitee.com/h79/goutils/perf" 16 goredis "github.com/go-redis/redis/v8" 17 "github.com/olivere/elastic/v7" 18 "gorm.io/gorm" 19 "time" 20 ) 21 22 // Dao https://gorm.io/docs/query.html 23 type Dao struct { 24 Sql db.SqlDatabase 25 Redis redis.Client 26 Elastic db.EsDatabase 27 } 28 29 var errZero = fmt.Errorf("length is zero") 30 31 func (d *Dao) DBClient(opts ...commonoption.Option) (*gorm.DB, error) { 32 r, _, err := d.DBClientV2(opts...) 33 return r, err 34 } 35 36 func (d *Dao) DBClientV2(opts ...commonoption.Option) (*gorm.DB, string, error) { 37 if d.Sql == nil { 38 return nil, "", result.RErrNotSupport 39 } 40 var name, _ = option.NameKeyExist(opts...) 41 sql, err := d.Sql.Get(name) 42 if err != nil { 43 return nil, name, result.RErrNil 44 } 45 return sql.Db(), sql.Name(), nil 46 } 47 48 func (d *Dao) RedisClient(opts ...commonoption.Option) (*goredis.Client, error) { 49 r, _, err := d.RedisClientV2(opts...) 50 return r, err 51 } 52 53 func (d *Dao) RedisClientV2(opts ...commonoption.Option) (*goredis.Client, string, error) { 54 if d.Redis == nil { 55 return nil, "", result.RErrNotSupport 56 } 57 var name, _ = option.NameKeyExist(opts...) 58 rds, err := d.Redis.Get(name) 59 if err != nil { 60 return nil, name, err 61 } 62 return rds.Rds(), rds.Name(), nil 63 } 64 65 func (d *Dao) ClusterRedisClient(opts ...commonoption.Option) (*goredis.ClusterClient, error) { 66 r, _, err := d.ClusterRedisClientV2(opts...) 67 return r, err 68 } 69 70 func (d *Dao) ClusterRedisClientV2(opts ...commonoption.Option) (*goredis.ClusterClient, string, error) { 71 if d.Redis == nil { 72 return nil, "", result.RErrNotSupport 73 } 74 var name, _ = option.NameKeyExist(opts...) 75 rds, err := d.Redis.Get(name) 76 if err != nil { 77 return nil, name, err 78 } 79 return rds.Cluster(), rds.Name(), nil 80 } 81 82 func (d *Dao) SentinelRedisClient(opts ...commonoption.Option) (*goredis.SentinelClient, error) { 83 r, _, err := d.SentinelRedisClientV2(opts...) 84 return r, err 85 } 86 87 func (d *Dao) SentinelRedisClientV2(opts ...commonoption.Option) (*goredis.SentinelClient, string, error) { 88 if d.Redis == nil { 89 return nil, "", result.RErrNotSupport 90 } 91 var name, _ = option.NameKeyExist(opts...) 92 rds, err := d.Redis.Get(name) 93 if err != nil { 94 return nil, name, err 95 } 96 return rds.Sentinel(), rds.Name(), nil 97 } 98 99 func (d *Dao) ElasticClient(opts ...commonoption.Option) (*elastic.Client, error) { 100 r, _, err := d.ElasticClientV2(opts...) 101 return r, err 102 } 103 104 func (d *Dao) ElasticClientV2(opts ...commonoption.Option) (*elastic.Client, string, error) { 105 if d.Elastic == nil { 106 return nil, "", result.RErrNotSupport 107 } 108 var name, _ = option.NameKeyExist(opts...) 109 es, na, err := d.Elastic.Get(name) 110 return es, na, err 111 } 112 113 func (d *Dao) UseRedis(opts ...commonoption.Option) CurrentRedis { 114 client, name, _ := d.RedisClientV2(opts...) 115 t, _ := option.TimeOutExist(opts...) 116 w := option.AlarmExist(opts...) 117 return CurrentRedis{Client: client, Name: name, timeout: t, warn: w} 118 } 119 120 func (d *Dao) UseDB(opts ...commonoption.Option) CurrentDb { 121 client, name, _ := d.DBClientV2(opts...) 122 return CurrentDb{DB: client, Name: name} 123 } 124 125 func (d *Dao) UseElastic(opts ...commonoption.Option) CurrentElastic { 126 client, name, _ := d.ElasticClientV2(opts...) 127 return CurrentElastic{Client: client, Name: name} 128 } 129 130 func (d *Dao) Condition(ctx context.Context, data interface{}, call db.ConditionCallback, opts ...commonoption.Option) result.Result { 131 132 sql, err := d.DBClient(opts...) 133 if err != nil { 134 return result.Error(result.ErrDbInternal, fmt.Sprintf("the db non existed")) 135 } 136 137 tx := call(ctx, data, sql) 138 139 if errors.Is(tx.Error, gorm.ErrRecordNotFound) { 140 return result.Error(result.ErrNotFound, tx.Error.Error()) 141 } 142 if tx.Error != nil { 143 return result.Error(result.ErrDbInternal, tx.Error.Error()) 144 } 145 return result.Succeed() 146 } 147 148 func (d *Dao) IsNotFound(db *gorm.DB) int { 149 return wrapper.IsNotFound(db) 150 } 151 152 type CurrentElastic struct { 153 *elastic.Client 154 Name string 155 } 156 157 func (d *CurrentElastic) OK() bool { 158 return d.Client != nil 159 } 160 161 type CurrentDb struct { 162 *gorm.DB 163 Name string 164 } 165 166 func (d *CurrentDb) OK() bool { 167 return d.DB != nil 168 } 169 170 type CurrentRedis struct { 171 *goredis.Client 172 Name string 173 timeout int64 174 warn bool 175 } 176 177 func (d *CurrentRedis) Warning(r *perf.RunTime, err error) { 178 dif := r.End() 179 if dif == 0 || !d.warn { 180 return 181 } 182 util.Alarm(result.ErrDbInternal, "Redis", fmt.Sprintf("run too time long=> %d,start=> %d", dif, r.Start()), err) 183 } 184 185 func (d *CurrentRedis) OK() bool { 186 return d.Client != nil 187 } 188 189 func (d *CurrentRedis) HSet(ctx context.Context, key, field string, value interface{}) (int64, error) { 190 if d.Client == nil { 191 return 0, result.RErrNil 192 } 193 if len(field) <= 0 { 194 return 0, errZero 195 } 196 var err error 197 var rt = perf.Begin(d.timeout) 198 defer d.Warning(rt, nil) 199 ret, err := d.Client.HSet(ctx, key, field, value).Result() 200 return ret, err 201 } 202 203 func (d *CurrentRedis) HSetNX(ctx context.Context, key, field string, value interface{}) (bool, error) { 204 if d.Client == nil { 205 return false, result.RErrNil 206 } 207 if len(field) <= 0 { 208 return false, errZero 209 } 210 var err error 211 var rt = perf.Begin(d.timeout) 212 defer d.Warning(rt, err) 213 ret, err := d.Client.HSetNX(ctx, key, field, value).Result() 214 return ret, err 215 } 216 217 func (d *CurrentRedis) HGet(ctx context.Context, key, field string) (string, error) { 218 if d.Client == nil { 219 return "", result.RErrNil 220 } 221 var err error 222 var rt = perf.Begin(d.timeout) 223 defer d.Warning(rt, err) 224 ret, err := d.Client.HGet(ctx, key, field).Result() 225 return ret, err 226 } 227 228 func (d *CurrentRedis) HGetAll(ctx context.Context, key string) (map[string]string, error) { 229 if d.Client == nil { 230 return nil, result.RErrNil 231 } 232 var err error 233 var rt = perf.Begin(d.timeout) 234 defer d.Warning(rt, err) 235 ret, err := d.Client.HGetAll(ctx, key).Result() 236 return ret, err 237 } 238 239 func (d *CurrentRedis) HGetInt(ctx context.Context, key, field string) (int, error) { 240 if d.Client == nil { 241 return 0, result.RErrNil 242 } 243 var err error 244 var rt = perf.Begin(d.timeout) 245 defer d.Warning(rt, err) 246 ret, err := d.Client.HGet(ctx, key, field).Result() 247 if err != nil { 248 return 0, err 249 } 250 return stringutil.StringToInt(ret), nil 251 } 252 253 func (d *CurrentRedis) HDel(ctx context.Context, key, field string) (int64, error) { 254 if d.Client == nil { 255 return 0, result.RErrNil 256 } 257 var err error 258 var rt = perf.Begin(d.timeout) 259 defer d.Warning(rt, err) 260 ret, err := d.Client.HDel(ctx, key, field).Result() 261 return ret, err 262 } 263 264 func (d *CurrentRedis) HInc(ctx context.Context, key, field string, value int64) (int64, error) { 265 if d.Client == nil { 266 return 0, result.RErrNil 267 } 268 if len(field) <= 0 { 269 return 0, errZero 270 } 271 var err error 272 var rt = perf.Begin(d.timeout) 273 defer d.Warning(rt, err) 274 ret, err := d.Client.HIncrBy(ctx, key, field, value).Result() 275 return ret, err 276 } 277 278 func (d *CurrentRedis) Set(ctx context.Context, key string, value interface{}, expiration time.Duration) (string, error) { 279 if d.Client == nil { 280 return "", result.RErrNil 281 } 282 if len(key) <= 0 { 283 return "", errZero 284 } 285 var err error 286 var rt = perf.Begin(d.timeout) 287 defer d.Warning(rt, err) 288 ret, err := d.Client.Set(ctx, key, value, expiration).Result() 289 return ret, err 290 } 291 292 func (d *CurrentRedis) SetNX(ctx context.Context, key string, value interface{}, expiration time.Duration) (bool, error) { 293 if d.Client == nil { 294 return false, result.RErrNil 295 } 296 if len(key) <= 0 { 297 return false, errZero 298 } 299 var err error 300 var rt = perf.Begin(d.timeout) 301 defer d.Warning(rt, err) 302 ret, err := d.Client.SetNX(ctx, key, value, expiration).Result() 303 return ret, err 304 } 305 306 func (d *CurrentRedis) SetEX(ctx context.Context, key string, value interface{}, expiration time.Duration) (string, error) { 307 if d.Client == nil { 308 return "", result.RErrNil 309 } 310 if len(key) <= 0 { 311 return "", errZero 312 } 313 var err error 314 var rt = perf.Begin(d.timeout) 315 defer d.Warning(rt, err) 316 ret, err := d.Client.SetEX(ctx, key, value, expiration).Result() 317 return ret, err 318 } 319 320 func (d *CurrentRedis) Get(ctx context.Context, key string) (string, error) { 321 if d.Client == nil { 322 return "", result.RErrNil 323 } 324 var err error 325 var rt = perf.Begin(d.timeout) 326 defer d.Warning(rt, err) 327 ret, err := d.Client.Get(ctx, key).Result() 328 return ret, err 329 } 330 331 func (d *CurrentRedis) Inc(ctx context.Context, key string, value int64) (int64, error) { 332 if d.Client == nil { 333 return 0, result.RErrNil 334 } 335 if len(key) <= 0 { 336 return 0, errZero 337 } 338 var err error 339 var rt = perf.Begin(d.timeout) 340 defer d.Warning(rt, err) 341 ret, err := d.Client.IncrBy(ctx, key, value).Result() 342 return ret, err 343 } 344 345 func (d *CurrentRedis) GetInt(ctx context.Context, key string) (int, error) { 346 if d.Client == nil { 347 return 0, result.RErrNil 348 } 349 var err error 350 var rt = perf.Begin(d.timeout) 351 defer d.Warning(rt, err) 352 ret, err := d.Client.Get(ctx, key).Result() 353 if err != nil { 354 return 0, err 355 } 356 return stringutil.StringToInt(ret), nil 357 } 358 359 // ExpireAt 在某个时间点过期 360 func (d *CurrentRedis) ExpireAt(ctx context.Context, key string, time time.Time) { 361 if d.Client == nil { 362 return 363 } 364 var err error 365 var rt = perf.Begin(d.timeout) 366 defer d.Warning(rt, err) 367 _, err = d.Client.ExpireAt(ctx, key, time).Result() 368 } 369 370 // Expire 过多久失效 371 func (d *CurrentRedis) Expire(ctx context.Context, key string, time time.Duration) { 372 if d.Client == nil { 373 return 374 } 375 var err error 376 var rt = perf.Begin(d.timeout) 377 defer d.Warning(rt, err) 378 _, err = d.Client.Expire(ctx, key, time).Result() 379 }