mysql.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package exp
  2. import (
  3. "context"
  4. "database/sql"
  5. "fmt"
  6. expm "go-common/app/service/live/xuser/model/exp"
  7. "go-common/library/log"
  8. "go-common/library/xstr"
  9. )
  10. const (
  11. _shard = 10
  12. _insExp = "INSERT IGNORE INTO user_exp_%d (uid,uexp,rexp) VALUES(?,?,?)"
  13. _selExp = "SELECT uid,uexp,rexp,ctime,mtime FROM user_exp_%d where uid=?"
  14. _inSelExp = "SELECT uid,uexp,rexp,ctime,mtime FROM user_exp_%d where uid IN (%s)"
  15. _addUexp = "INSERT INTO user_exp_%d(uid,uexp,rexp) VALUES(?,?,0) ON DUPLICATE KEY UPDATE uexp=uexp+%d"
  16. _addRexp = "INSERT INTO user_exp_%d(uid,uexp,rexp) VALUES(?,0,?) ON DUPLICATE KEY UPDATE rexp=rexp+%d"
  17. _errorDBLogPrefix = "xuser.exp.dao.mysql"
  18. )
  19. // InitExp 初始化用户经验,用于首次查询
  20. func (d *Dao) InitExp(c context.Context, uid int64, uexp int64, rexp int64) (row int64, err error) {
  21. res, err := d.db.Exec(c, fmt.Sprintf(_insExp, uid%_shard), uid, uexp, rexp)
  22. if err != nil {
  23. log.Error(_errorDBLogPrefix+"|InitExp d.exp.Exec err: %v", err)
  24. return
  25. }
  26. return res.RowsAffected()
  27. }
  28. // Exp 查询一条记录
  29. func (d *Dao) Exp(c context.Context, uid int64) (exp *expm.Exp, err error) {
  30. row := d.db.QueryRow(c, fmt.Sprintf(_selExp, uid%_shard), uid)
  31. exp = &expm.Exp{}
  32. if err = row.Scan(&exp.UID, &exp.Uexp, &exp.Rexp, &exp.CTime, &exp.MTime); err == sql.ErrNoRows {
  33. // 查询结果为空时,初始化数据
  34. _, err = d.InitExp(c, uid, 0, 0)
  35. }
  36. if err != nil {
  37. log.Error(_errorDBLogPrefix+"|Exp row.Scan err: %v", err)
  38. return
  39. }
  40. return
  41. }
  42. // MultiExp 批量查询
  43. func (d *Dao) MultiExp(c context.Context, uids []int64) (exps []*expm.Exp, err error) {
  44. exps = make([]*expm.Exp, 0)
  45. var (
  46. suffix int64
  47. uidGroup [_shard][]int64
  48. um = make(map[int64]struct{}, len(uids))
  49. )
  50. for _, uid := range uids {
  51. suffix = uid % _shard
  52. uidGroup[suffix] = append(uidGroup[suffix], uid)
  53. um[uid] = struct{}{}
  54. }
  55. for index, uids := range uidGroup {
  56. if 0 == len(uids) {
  57. continue
  58. }
  59. rows, err1 := d.db.Query(c, fmt.Sprintf(_inSelExp, index, xstr.JoinInts(uids)))
  60. if err1 != nil {
  61. err = err1
  62. log.Error(_errorDBLogPrefix+"|MultiExp d.exp.Query err: %v", err)
  63. return
  64. }
  65. for rows.Next() {
  66. ele := &expm.Exp{}
  67. if err = rows.Scan(&ele.UID, &ele.Uexp, &ele.Rexp, &ele.CTime, &ele.MTime); err != nil {
  68. log.Error(_errorDBLogPrefix+"|MultiExp rows.Scan err: %v", err)
  69. return
  70. }
  71. exps = append(exps, ele)
  72. delete(um, ele.UID)
  73. }
  74. }
  75. // 初始化不存在的数据,补齐数据
  76. for uid := range um {
  77. d.InitExp(c, uid, 0, 0)
  78. ele := &expm.Exp{UID: uid, Uexp: 0, Rexp: 0}
  79. exps = append(exps, ele)
  80. }
  81. return
  82. }
  83. // AddUexp 添加用户经验
  84. func (d *Dao) AddUexp(c context.Context, uid int64, uexp int64) (affect int64, err error) {
  85. upSQL := fmt.Sprintf(_addUexp, uid%_shard, uexp)
  86. res, err := d.db.Exec(c, upSQL, uid, uexp)
  87. if err != nil {
  88. log.Error(_errorDBLogPrefix+"|Exec(%s) error(%v)", upSQL, err)
  89. return
  90. }
  91. return res.RowsAffected()
  92. }
  93. // AddRexp 添加主播经验
  94. func (d *Dao) AddRexp(c context.Context, uid int64, rexp int64) (affect int64, err error) {
  95. upSQL := fmt.Sprintf(_addRexp, uid%_shard, rexp)
  96. res, err := d.db.Exec(c, upSQL, uid, rexp)
  97. if err != nil {
  98. log.Error(_errorDBLogPrefix+"|AddRexp|Exec(%s) error(%v)", upSQL, err)
  99. return
  100. }
  101. return res.RowsAffected()
  102. }