mysql.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. package dao
  2. import (
  3. "context"
  4. xsql "database/sql"
  5. "fmt"
  6. "math/rand"
  7. "time"
  8. "go-common/app/interface/main/answer/model"
  9. "go-common/library/database/sql"
  10. "go-common/library/log"
  11. "go-common/library/xstr"
  12. "github.com/pkg/errors"
  13. )
  14. const (
  15. _shard = 10
  16. _getAnswerHistorySQL = "SELECT id,hid,mid,start_time,step_one_err_num,step_one_complete_time,step_two_start_time,complete_time,complete_result,score,is_pass_captcha,is_first_pass,passed_level,rank_id,step_extra_start_time,step_extra_complete_time,extra_score FROM answer_history_%d WHERE mid=? ORDER BY id DESC LIMIT 1"
  17. _getHistoryByHidSQL = "SELECT id,hid,mid,start_time,step_one_err_num,step_one_complete_time,step_two_start_time,complete_time,complete_result,score,is_pass_captcha,is_first_pass,passed_level,rank_id,step_extra_start_time,step_extra_complete_time,extra_score FROM answer_history_%d WHERE hid=? ORDER BY id DESC LIMIT 1"
  18. _sharingIndexSQL = "SELECT table_index FROM answer_history_mapping WHERE hid = ?"
  19. _addAnswerHistorySQL = "INSERT INTO answer_history_%d (hid,mid,start_time,step_one_err_num,step_one_complete_time) VALUES (?,?,?,?,?)"
  20. _setAnswerHistorySQL = "UPDATE answer_history_%d SET complete_result=?,complete_time=?,score=?,is_first_pass=?,passed_level=?,rank_id=? WHERE id=?"
  21. _updateAnswerLevelSQL = "UPDATE answer_history_%d SET is_first_pass = ?,passed_level = ? WHERE id = ? "
  22. _updateCaptchaSQL = "UPDATE answer_history_%d SET is_pass_captcha = ? WHERE id = ? "
  23. _updateStepTwoTimeSQL = "UPDATE answer_history_%d SET step_two_start_time = ? WHERE id = ? "
  24. _updateExtraStartTimeSQL = "UPDATE answer_history_%d SET step_extra_start_time = ? WHERE id = ? "
  25. _updateExtraRetSQL = "UPDATE answer_history_%d SET step_extra_complete_time = ?,extra_score = ? WHERE id = ? "
  26. _pendanHistorySQL = "SELECT hid,status FROM answer_pendant_history WHERE mid = ?"
  27. _inPendantHistorySQL = "INSERT INTO answer_pendant_history (hid,mid) VALUES (?,?)"
  28. _upPendantHistorySQL = "UPDATE answer_pendant_history SET status = 1 WHERE mid = ? AND hid = ? AND status = 0"
  29. _allTypesSQL = "SELECT id,typename,parentid,lablename FROM ans_v3_question_type ORDER BY parentid;"
  30. _questionByIdsSQL = "SELECT id,type_id,question,ans1,ans2,ans3,ans4,mid FROM ans_v3_question WHERE id IN (%s)"
  31. _questionTypeSQL = "SELECT id,type_id FROM ans_v3_question WHERE state = ?"
  32. _questionExtraByIdsSQL = "SELECT id,question,ans,status,origin_id,av_id,source,ctime,mtime FROM answer_extra_question WHERE state = 1 AND id IN (%s)"
  33. _questionExtraTypeSQL = "SELECT id,ans FROM answer_extra_question WHERE isdel = 1 and state = 1 limit ?"
  34. )
  35. func hit(id int64) int64 {
  36. return id % _shard
  37. }
  38. // PendantHistory .
  39. func (d *Dao) PendantHistory(c context.Context, mid int64) (hid int64, status int8, err error) {
  40. row := d.db.QueryRow(c, _pendanHistorySQL, mid)
  41. if err = row.Scan(&hid, &status); err != nil {
  42. if err == sql.ErrNoRows {
  43. return 0, 0, nil
  44. }
  45. log.Error("PendantHistory(%d),error:%+v", mid, err)
  46. return 0, 0, errors.WithStack(err)
  47. }
  48. return hid, status, nil
  49. }
  50. // History get user's answer history by mid.
  51. func (d *Dao) History(c context.Context, mid int64) (res *model.AnswerHistory, err error) {
  52. res = &model.AnswerHistory{}
  53. row := d.db.QueryRow(c, fmt.Sprintf(_getAnswerHistorySQL, hit(mid)), mid)
  54. if err = row.Scan(&res.ID, &res.Hid, &res.Mid, &res.StartTime, &res.StepOneErrTimes, &res.StepOneCompleteTime, &res.StepTwoStartTime, &res.CompleteTime,
  55. &res.CompleteResult, &res.Score, &res.IsPassCaptcha, &res.IsFirstPass, &res.PassedLevel, &res.RankID, &res.StepExtraStartTime, &res.StepExtraCompleteTime, &res.StepExtraScore); err != nil {
  56. if err == sql.ErrNoRows {
  57. err = nil
  58. } else {
  59. log.Error("History(%d),error:%+v", mid, err)
  60. }
  61. }
  62. return
  63. }
  64. // HistoryByHid get user's answer history by mid.
  65. func (d *Dao) HistoryByHid(c context.Context, hid int64) (res *model.AnswerHistory, err error) {
  66. res = &model.AnswerHistory{}
  67. row := d.db.QueryRow(c, fmt.Sprintf(_getHistoryByHidSQL, hit(hid)), hid)
  68. if err = row.Scan(&res.ID, &res.Hid, &res.Mid, &res.StartTime, &res.StepOneErrTimes, &res.StepOneCompleteTime, &res.StepTwoStartTime, &res.CompleteTime,
  69. &res.CompleteResult, &res.Score, &res.IsPassCaptcha, &res.IsFirstPass, &res.PassedLevel, &res.RankID, &res.StepExtraStartTime, &res.StepExtraCompleteTime, &res.StepExtraScore); err != nil {
  70. if err == sql.ErrNoRows {
  71. err = nil
  72. } else {
  73. log.Error("HistoryByHid(%d),error:%+v", hid, err)
  74. }
  75. }
  76. return
  77. }
  78. // OldHistory get user's answer history by hid and sharing index.
  79. func (d *Dao) OldHistory(c context.Context, hid, idx int64) (res *model.AnswerHistory, err error) {
  80. res = &model.AnswerHistory{}
  81. row := d.db.QueryRow(c, fmt.Sprintf(_getHistoryByHidSQL, idx), hid)
  82. if err = row.Scan(&res.ID, &res.Hid, &res.Mid, &res.StartTime, &res.StepOneErrTimes, &res.StepOneCompleteTime, &res.StepTwoStartTime, &res.CompleteTime,
  83. &res.CompleteResult, &res.Score, &res.IsPassCaptcha, &res.IsFirstPass, &res.PassedLevel, &res.RankID, &res.StepExtraStartTime, &res.StepExtraCompleteTime, &res.StepExtraScore); err != nil {
  84. if err == sql.ErrNoRows {
  85. err = nil
  86. } else {
  87. log.Error("OldHistory(%d,%d),error:%+v", hid, idx, err)
  88. }
  89. }
  90. return
  91. }
  92. // SharingIndexByHid get old history sharingIndex by hid
  93. func (d *Dao) SharingIndexByHid(c context.Context, hid int64) (res int64, err error) {
  94. row := d.db.QueryRow(c, _sharingIndexSQL, hid)
  95. if err = row.Scan(&res); err != nil {
  96. if err == sql.ErrNoRows {
  97. err = nil
  98. } else {
  99. log.Error("OldHistory(%d),error:%+v", hid, err)
  100. }
  101. }
  102. return
  103. }
  104. // AddPendantHistory .
  105. func (d *Dao) AddPendantHistory(c context.Context, mid, hid int64) (affected int64, err error) {
  106. var res xsql.Result
  107. if res, err = d.db.Exec(c, _inPendantHistorySQL, hid, mid); err != nil {
  108. log.Error("AddPendantHistory(%d,%d),error:%+v", mid, hid, err)
  109. return
  110. }
  111. return res.RowsAffected()
  112. }
  113. // SetHistory set user's answer history by id.
  114. func (d *Dao) SetHistory(c context.Context, mid int64, his *model.AnswerHistory) (affected int64, err error) {
  115. var res xsql.Result
  116. if res, err = d.db.Exec(c, fmt.Sprintf(_setAnswerHistorySQL, hit(mid)), his.CompleteResult, his.CompleteTime, his.Score, his.IsFirstPass, his.PassedLevel, his.RankID, his.ID); err != nil {
  117. log.Error("setAnswerHistory: db.Exec(%d, %v) error(%v)", mid, his, err)
  118. return
  119. }
  120. return res.RowsAffected()
  121. }
  122. // AddHistory add user's answer history by id.
  123. func (d *Dao) AddHistory(c context.Context, mid int64, his *model.AnswerHistory) (affected int64, hid string, err error) {
  124. var res xsql.Result
  125. hid = fmt.Sprintf("%d%04d%02d", time.Now().Unix(), rand.Intn(9999), hit(mid))
  126. if res, err = d.db.Exec(c, fmt.Sprintf(_addAnswerHistorySQL, hit(mid)), hid, his.Mid, his.StartTime, his.StepOneErrTimes, his.StepOneCompleteTime); err != nil {
  127. log.Error("addAnswerHistory: db.Exec(%d, %v) error(%v)", mid, his, err)
  128. return
  129. }
  130. affected, err = res.RowsAffected()
  131. return
  132. }
  133. // UpdateLevel update answer history passedLevel and isFirstPass.
  134. func (d *Dao) UpdateLevel(c context.Context, id int64, mid int64, isFirstPass, passedLevel int8) (ret int64, err error) {
  135. var res xsql.Result
  136. if res, err = d.db.Exec(c, fmt.Sprintf(_updateAnswerLevelSQL, hit(mid)), isFirstPass, passedLevel, id); err != nil {
  137. log.Error("UpdateLevel: db.Exec(%d,%d,%d,%d) error(%v)", id, mid, isFirstPass, passedLevel, err)
  138. return
  139. }
  140. return res.RowsAffected()
  141. }
  142. // UpdateCaptcha update answer history captcha.
  143. func (d *Dao) UpdateCaptcha(c context.Context, id int64, mid int64, isPassCaptcha int8) (ret int64, err error) {
  144. var res xsql.Result
  145. if res, err = d.db.Exec(c, fmt.Sprintf(_updateCaptchaSQL, hit(mid)), isPassCaptcha, id); err != nil {
  146. log.Error("UpdateCaptcha: db.Exec(%d, %d, %d) error(%v)", id, mid, isPassCaptcha, err)
  147. return
  148. }
  149. return res.RowsAffected()
  150. }
  151. // UpdateStepTwoTime .
  152. func (d *Dao) UpdateStepTwoTime(c context.Context, id int64, mid int64, t time.Time) (ret int64, err error) {
  153. var res xsql.Result
  154. if res, err = d.db.Exec(c, fmt.Sprintf(_updateStepTwoTimeSQL, hit(mid)), t, id); err != nil {
  155. log.Error("UpdateCaptcha: db.Exec(%d,%d,%s) error(%v)", id, mid, t, err)
  156. return
  157. }
  158. return res.RowsAffected()
  159. }
  160. // UpdateExtraStartTime update extra start time.
  161. func (d *Dao) UpdateExtraStartTime(c context.Context, id int64, mid int64, t time.Time) (ret int64, err error) {
  162. var res xsql.Result
  163. if res, err = d.db.Exec(c, fmt.Sprintf(_updateExtraStartTimeSQL, hit(mid)), t, id); err != nil {
  164. log.Error("updateExtraStartTime: db.Exec(%d, %d, %s) error(%v)", id, mid, t, err)
  165. return
  166. }
  167. return res.RowsAffected()
  168. }
  169. // UpdateExtraRet update extra start time.
  170. func (d *Dao) UpdateExtraRet(c context.Context, id int64, mid int64, t int64, extraScore int64) (ret int64, err error) {
  171. var res xsql.Result
  172. if res, err = d.db.Exec(c, fmt.Sprintf(_updateExtraRetSQL, hit(mid)), t, extraScore, id); err != nil {
  173. log.Error("updateExtraRetSQL: db.Exec(%d, %d, %d, %d) error(%v)", id, mid, t, extraScore, err)
  174. return
  175. }
  176. return res.RowsAffected()
  177. }
  178. // UpPendantHistory update pendant history.
  179. func (d *Dao) UpPendantHistory(c context.Context, mid, hid int64) (ret int64, err error) {
  180. var res xsql.Result
  181. if res, err = d.db.Exec(c, _upPendantHistorySQL, mid, hid); err != nil {
  182. log.Error("UpPendantHistory(%d,%d),error:%+v", mid, hid, err)
  183. return
  184. }
  185. return res.RowsAffected()
  186. }
  187. // QidsExtraByState get extra question ids by check
  188. func (d *Dao) QidsExtraByState(c context.Context, size int) (res []*model.ExtraQst, err error) {
  189. var rows *sql.Rows
  190. if rows, err = d.db.Query(c, _questionExtraTypeSQL, size); err != nil {
  191. return
  192. }
  193. defer rows.Close()
  194. for rows.Next() {
  195. r := new(model.ExtraQst)
  196. if err = rows.Scan(&r.ID, &r.Ans); err != nil {
  197. log.Error("QidsExtraByState(%d),error:%+v", size, err)
  198. res = nil
  199. return
  200. }
  201. res = append(res, r)
  202. }
  203. err = rows.Err()
  204. return
  205. }
  206. // ExtraByIds get extra question in idstr
  207. func (d *Dao) ExtraByIds(c context.Context, ids []int64) (res map[int64]*model.ExtraQst, err error) {
  208. var rows *sql.Rows
  209. res = make(map[int64]*model.ExtraQst, len(ids))
  210. idStr := xstr.JoinInts(ids)
  211. if rows, err = d.db.Query(c, fmt.Sprintf(_questionExtraByIdsSQL, idStr)); err != nil {
  212. log.Error("d.questionExtraByIds.Query error(%v)", err)
  213. return
  214. }
  215. defer rows.Close()
  216. for rows.Next() {
  217. r := new(model.ExtraQst)
  218. if err = rows.Scan(&r.ID, &r.Question, &r.Ans, &r.Status, &r.OriginID, &r.AvID, &r.Source, &r.Ctime, &r.Mtime); err != nil {
  219. log.Error("row.Scan() error(%v)", err)
  220. res = nil
  221. return
  222. }
  223. res[r.ID] = r
  224. }
  225. err = rows.Err()
  226. return
  227. }
  228. // Types get all types
  229. func (d *Dao) Types(c context.Context) (res []*model.TypeInfo, err error) {
  230. var rows *sql.Rows
  231. if rows, err = d.db.Query(c, _allTypesSQL); err != nil {
  232. log.Error("d.allTypesStmt.Query error(%v)", err)
  233. return
  234. }
  235. defer rows.Close()
  236. for rows.Next() {
  237. r := new(model.TypeInfo)
  238. if err = rows.Scan(&r.ID, &r.Name, &r.Parentid, &r.LabelName); err != nil {
  239. log.Error("row.Scan() error(%v)", err)
  240. res = nil
  241. return
  242. }
  243. res = append(res, r)
  244. }
  245. err = rows.Err()
  246. return
  247. }
  248. // ByIds get question in idStr
  249. func (d *Dao) ByIds(c context.Context, ids []int64) (res map[int64]*model.Question, err error) {
  250. var rows *sql.Rows
  251. res = make(map[int64]*model.Question, len(ids))
  252. idStr := xstr.JoinInts(ids)
  253. if rows, err = d.db.Query(c, fmt.Sprintf(_questionByIdsSQL, idStr)); err != nil {
  254. log.Error("d.queryQuestionByIdsStmt.Query error(%v)", err)
  255. return
  256. }
  257. defer rows.Close()
  258. for rows.Next() {
  259. r := new(model.Question)
  260. ans := make([]string, 4)
  261. if err = rows.Scan(&r.ID, &r.TypeID, &r.Question, &ans[0], &ans[1], &ans[2], &ans[3], &r.Mid); err != nil {
  262. log.Error("row.Scan() error(%v)", err)
  263. res = nil
  264. return
  265. }
  266. r.Ans = ans
  267. res[r.ID] = r
  268. }
  269. err = rows.Err()
  270. return
  271. }
  272. // QidsByState get question ids by check
  273. func (d *Dao) QidsByState(c context.Context, state int8) (res []*model.Question, err error) {
  274. var rows *sql.Rows
  275. if rows, err = d.db.Query(c, _questionTypeSQL, state); err != nil {
  276. log.Error("d.questionTypeStmt.Query error(%v)", err)
  277. return
  278. }
  279. defer rows.Close()
  280. for rows.Next() {
  281. r := new(model.Question)
  282. if err = rows.Scan(&r.ID, &r.TypeID); err != nil {
  283. log.Error("row.Scan() error(%v)", err)
  284. res = nil
  285. return
  286. }
  287. res = append(res, r)
  288. }
  289. err = rows.Err()
  290. return
  291. }