up.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. package manager
  2. import (
  3. "context"
  4. "database/sql"
  5. "errors"
  6. "fmt"
  7. "strings"
  8. "time"
  9. upgrpc "go-common/app/service/main/up/api/v1"
  10. "go-common/app/service/main/up/dao"
  11. "go-common/app/service/main/up/model"
  12. xsql "go-common/library/database/sql"
  13. "go-common/library/log"
  14. "go-common/library/xstr"
  15. )
  16. const (
  17. _upsWithGroupBase = "SELECT ups.id,mid,up_group.id as group_id ,up_group.short_tag as group_tag,up_group.name as group_name,ups.note,ups.ctime, ups.mtime, ups.uid FROM ups INNER JOIN up_group on ups.type=up_group.id "
  18. _upsWithGroupBaseWithColor = "SELECT ups.id,mid,up_group.id as group_id ,up_group.short_tag as group_tag,up_group.name as group_name,ups.note,ups.ctime, ups.mtime, ups.uid, up_group.colors FROM ups INNER JOIN up_group on ups.type=up_group.id "
  19. _upsWithGroup = _upsWithGroupBaseWithColor + "limit ? offset ? "
  20. _upsWithGroupByMtime = _upsWithGroupBaseWithColor + "where ups.mtime >= ?"
  21. _delByMid = "DELETE FROM ups where id = ?"
  22. _insertMidType = "INSERT INTO ups (mid, type, note, ctime, mtime, uid) values "
  23. _selectByMidTypeWithGroup = _upsWithGroupBase + "where mid = ? and type = ?"
  24. _updateByID = "update ups set type=?, note=?, uid=?, mtime=? where id = ?"
  25. //MysqlTimeFormat mysql time format
  26. MysqlTimeFormat = "2006-01-02 15:04:05"
  27. _selectByID = _upsWithGroupBase + "where ups.id = ?"
  28. _selectCount = "SELECT COUNT(0) FROM ups INNER JOIN up_group on ups.type=up_group.id "
  29. _upSpecialSQL = "SELECT type FROM ups WHERE mid = ?"
  30. _upsSpecialSQL = "SELECT mid, type FROM ups WHERE mid IN (%s)"
  31. _upGroupsMidsSQL = "SELECT id, mid, type FROM ups WHERE id > ? AND type IN (%s) LIMIT ?"
  32. )
  33. // UpSpecials load all ups with group info
  34. func (d *Dao) UpSpecials(c context.Context) (ups []*model.UpSpecial, err error) {
  35. log.Info("start refresh ups table")
  36. stmt, err := d.managerDB.Prepare(_upsWithGroup)
  37. if err != nil {
  38. log.Error("d.managerDB.Prepare error(%v)", err)
  39. return
  40. }
  41. defer stmt.Close()
  42. var offset = 0
  43. var limit = 1000
  44. var cnt = 0
  45. var isFirst = true
  46. for isFirst || cnt == limit {
  47. isFirst = false
  48. rows, err1 := stmt.Query(c, limit, offset)
  49. if err1 != nil {
  50. err = err1
  51. log.Error("stmt.Query error(%v)", err1)
  52. return
  53. }
  54. cnt = 0
  55. for rows.Next() {
  56. cnt++
  57. var up *model.UpSpecial
  58. up, err = parseUpGroupWithColor(rows)
  59. ups = append(ups, up)
  60. }
  61. rows.Close()
  62. if err != nil {
  63. return
  64. }
  65. log.Info("reading data from table, read count=%d", cnt)
  66. offset += cnt
  67. }
  68. log.Info("end refresh ups table, read count=%d", offset)
  69. return
  70. }
  71. //RefreshUpSpecialIncremental refresh cache incrementally
  72. func (d *Dao) RefreshUpSpecialIncremental(c context.Context, lastMTime time.Time) (ups []*model.UpSpecial, err error) {
  73. var timeStr = lastMTime.Format(MysqlTimeFormat)
  74. log.Info("start refresh ups table mtime>%s", timeStr)
  75. stmt, err := d.managerDB.Prepare(_upsWithGroupByMtime)
  76. if err != nil {
  77. log.Error("d.managerDB.Prepare error(%v)", err)
  78. return
  79. }
  80. defer stmt.Close()
  81. var cnt = 0
  82. rows, err1 := stmt.Query(c, timeStr)
  83. if err1 != nil {
  84. err = err1
  85. log.Error("stmt.Query error(%v)", err1)
  86. return
  87. }
  88. cnt = 0
  89. for rows.Next() {
  90. cnt++
  91. var up *model.UpSpecial
  92. up, err = parseUpGroupWithColor(rows)
  93. if err != nil {
  94. log.Error("scan row err, %v", err)
  95. break
  96. }
  97. ups = append(ups, up)
  98. }
  99. rows.Close()
  100. if err != nil {
  101. return
  102. }
  103. log.Info("reading data from table, read count=%d", cnt)
  104. return
  105. }
  106. //DelSpecialByID delete special by id
  107. func (d *Dao) DelSpecialByID(c context.Context, id int64) (res sql.Result, err error) {
  108. var stmt *xsql.Stmt
  109. stmt, err = d.managerDB.Prepare(_delByMid)
  110. if err != nil {
  111. log.Error("stmt prepare fail, error(%v), sql=%s", err, _delByMid)
  112. return
  113. }
  114. defer stmt.Close()
  115. res, err = stmt.Exec(c, id)
  116. if err != nil {
  117. log.Error("delete mid from ups fail, id=%d, err=%v", id, err)
  118. }
  119. return
  120. }
  121. //InsertSpecial insert special
  122. func (d *Dao) InsertSpecial(c context.Context, special *model.UpSpecial, mids ...int64) (res sql.Result, err error) {
  123. var count = len(mids)
  124. if count == 0 {
  125. err = errors.New("no data need update")
  126. return
  127. }
  128. var insertSchema []string
  129. var vals []interface{}
  130. var nowStr = time.Now().Format(MysqlTimeFormat)
  131. for _, mid := range mids {
  132. insertSchema = append(insertSchema, "(?,?,?,?,?,?)")
  133. vals = append(vals, mid, special.GroupID, special.Note, nowStr, nowStr, special.UID)
  134. }
  135. var insertSQL = _insertMidType + strings.Join(insertSchema, ",")
  136. var stmt *xsql.Stmt
  137. stmt, err = d.managerDB.Prepare(insertSQL)
  138. if err != nil {
  139. log.Error("stmt prepare fail, error(%v), sql=%s", err, insertSQL)
  140. return
  141. }
  142. defer stmt.Close()
  143. res, err = stmt.Exec(c, vals...)
  144. if err != nil {
  145. log.Error("insert ups fail, err=%v, groupid=%d, note=%s, mid=%v", err, special.GroupID, special.Note, mids)
  146. }
  147. return
  148. }
  149. //UpdateSpecialByID update special by id
  150. func (d *Dao) UpdateSpecialByID(c context.Context, id int64, special *model.UpSpecial) (res sql.Result, err error) {
  151. var stmt *xsql.Stmt
  152. stmt, err = d.managerDB.Prepare(_updateByID)
  153. if err != nil {
  154. log.Error("stmt prepare fail, error(%v), sql=%s", err, _updateByID)
  155. return
  156. }
  157. defer stmt.Close()
  158. var timeStr = time.Now().Format(MysqlTimeFormat)
  159. res, err = stmt.Exec(c, special.GroupID, special.Note, special.UID, timeStr, id)
  160. if err != nil {
  161. log.Error("update ups fail, err=%v, groupid=%d, note=%s, id=%d", err, special.GroupID, special.Note, id)
  162. }
  163. return
  164. }
  165. //GetSpecialByMidGroup get special by mid and group
  166. func (d *Dao) GetSpecialByMidGroup(c context.Context, mid int64, groupID int64) (res *model.UpSpecial, err error) {
  167. var stmt *xsql.Stmt
  168. stmt, err = d.managerDB.Prepare(_selectByMidTypeWithGroup)
  169. if err != nil {
  170. log.Error("stmt prepare fail, error(%v), sql=%s", err, _selectByMidTypeWithGroup)
  171. return
  172. }
  173. defer stmt.Close()
  174. row := stmt.QueryRow(c, mid, groupID)
  175. var note sql.NullString
  176. var up = model.UpSpecial{}
  177. switch err = row.Scan(&up.ID, &up.Mid, &up.GroupID, &up.GroupTag, &up.GroupName, &note, &up.CTime, &up.MTime, &up.UID); err {
  178. case sql.ErrNoRows:
  179. err = nil
  180. return
  181. case nil:
  182. up.Note = note.String
  183. res = &up
  184. default:
  185. log.Error("rows.Scan error(%v)", err)
  186. return
  187. }
  188. return
  189. }
  190. //GetSpecialByID get special by id
  191. func (d *Dao) GetSpecialByID(c context.Context, id int64) (res *model.UpSpecial, err error) {
  192. rows, err := prepareAndQuery(c, d.managerDB, _selectByID, id)
  193. if err != nil {
  194. return
  195. }
  196. defer rows.Close()
  197. var note sql.NullString
  198. for rows.Next() {
  199. var up = &model.UpSpecial{}
  200. err = rows.Scan(&up.ID, &up.Mid, &up.GroupID, &up.GroupTag, &up.GroupName, &note, &up.CTime, &up.MTime, &up.UID)
  201. up.Note = note.String
  202. res = up
  203. break
  204. }
  205. return
  206. }
  207. //GetSepcialCount get special count
  208. func (d *Dao) GetSepcialCount(c context.Context, conditions ...dao.Condition) (count int, err error) {
  209. var conditionStr, args, hasOperator = dao.ConcatCondition(conditions...)
  210. var where = " WHERE "
  211. if !hasOperator {
  212. where = ""
  213. }
  214. rows, err := prepareAndQuery(c, d.managerDB, _selectCount+where+conditionStr, args...)
  215. if err != nil {
  216. log.Error("get special db fail, err=%+v", err)
  217. return
  218. }
  219. defer rows.Close()
  220. for rows.Next() {
  221. rows.Scan(&count)
  222. }
  223. return
  224. }
  225. func parseUpGroupWithColor(rows *xsql.Rows) (up *model.UpSpecial, err error) {
  226. var note sql.NullString
  227. var colors sql.NullString
  228. up = &model.UpSpecial{}
  229. err = rows.Scan(&up.ID, &up.Mid, &up.GroupID, &up.GroupTag, &up.GroupName, &note, &up.CTime, &up.MTime, &up.UID, &colors)
  230. if err != nil {
  231. log.Error("scan row err, %v", err)
  232. return
  233. }
  234. up.Note = note.String
  235. if colors.Valid {
  236. var colors = strings.Split(colors.String, "|")
  237. if len(colors) >= 2 {
  238. up.FontColor = colors[0]
  239. up.BgColor = colors[1]
  240. }
  241. }
  242. return
  243. }
  244. //GetSpecial get special from db
  245. func (d *Dao) GetSpecial(c context.Context, conditions ...dao.Condition) (res []*model.UpSpecial, err error) {
  246. var conditionStr, args, hasOperator = dao.ConcatCondition(conditions...)
  247. var where = " WHERE "
  248. if !hasOperator {
  249. where = ""
  250. }
  251. rows, err := prepareAndQuery(c, d.managerDB, _upsWithGroupBaseWithColor+where+conditionStr, args...)
  252. if err != nil {
  253. log.Error("get special db fail, err=%+v", err)
  254. return
  255. }
  256. defer rows.Close()
  257. for rows.Next() {
  258. var up *model.UpSpecial
  259. up, err = parseUpGroupWithColor(rows)
  260. if err != nil {
  261. log.Error("scan row err, %v", err)
  262. break
  263. }
  264. res = append(res, up)
  265. }
  266. return
  267. }
  268. //GetSpecialByMid get speical by mid
  269. func (d *Dao) GetSpecialByMid(c context.Context, mid int64) (res []*model.UpSpecial, err error) {
  270. var condition = dao.Condition{
  271. Key: "ups.mid",
  272. Operator: "=",
  273. Value: mid,
  274. }
  275. return d.GetSpecial(c, condition)
  276. }
  277. // RawUpSpecial get up special propertys
  278. func (d *Dao) RawUpSpecial(c context.Context, mid int64) (us *upgrpc.UpSpecial, err error) {
  279. rows, err := d.managerDB.Query(c, _upSpecialSQL, mid)
  280. if err != nil {
  281. return
  282. }
  283. defer rows.Close()
  284. us = new(upgrpc.UpSpecial)
  285. for rows.Next() {
  286. var groupID int64
  287. if err = rows.Scan(&groupID); err != nil {
  288. if err == xsql.ErrNoRows {
  289. err = nil
  290. }
  291. return
  292. }
  293. us.GroupIDs = append(us.GroupIDs, groupID)
  294. }
  295. return
  296. }
  297. // RawUpsSpecial get mult up special propertys
  298. func (d *Dao) RawUpsSpecial(c context.Context, mids []int64) (mu map[int64]*upgrpc.UpSpecial, err error) {
  299. rows, err := d.managerDB.Query(c, fmt.Sprintf(_upsSpecialSQL, xstr.JoinInts(mids)))
  300. if err != nil {
  301. return
  302. }
  303. defer rows.Close()
  304. mu = make(map[int64]*upgrpc.UpSpecial, len(mids))
  305. for rows.Next() {
  306. var mid, groupID int64
  307. if err = rows.Scan(&mid, &groupID); err != nil {
  308. if err == xsql.ErrNoRows {
  309. err = nil
  310. }
  311. return
  312. }
  313. if mu[mid] == nil {
  314. mu[mid] = new(upgrpc.UpSpecial)
  315. }
  316. mu[mid].GroupIDs = append(mu[mid].GroupIDs, groupID)
  317. }
  318. return
  319. }
  320. // UpGroupsMids get mids in one group.
  321. func (d *Dao) UpGroupsMids(c context.Context, groupIDs []int64, lastID int64, ps int) (lid int64, gmids map[int64][]int64, err error) {
  322. rows, err := d.managerDB.Query(c, fmt.Sprintf(_upGroupsMidsSQL, xstr.JoinInts(groupIDs)), lastID, ps)
  323. if err != nil {
  324. return
  325. }
  326. defer rows.Close()
  327. gmids = make(map[int64][]int64)
  328. for rows.Next() {
  329. var id, gid, mid int64
  330. if err = rows.Scan(&id, &mid, &gid); err != nil {
  331. if err == xsql.ErrNoRows {
  332. err = nil
  333. }
  334. return
  335. }
  336. if id > lid {
  337. lid = id
  338. }
  339. gmids[gid] = append(gmids[gid], mid)
  340. }
  341. return
  342. }