func CreateBank(rc *impl.RCM_Cmd) (interface{}, error) { log.D("rc CreateBank") var uid int64 var uname string var bName string err := rc.ValidF(` uid,R|I,R:0; uname,R|S,L:0; bName,R|S,L:0; `, &uid, &uname, &bName) if err != nil { log.E("CreateBank arg err:%v", err) return 0, err } b := &bank.BANK{} b.UId = &uid b.Name = &bName b.UName = &uname b.Status = bank.GetString("N") b.Public = bank.GetInt(1) if n, err := b.C(nil); err != nil { log.E("CreateBank err:%v", err) return 0, err } else { return n, nil } }
func migrateAddColumn(db *sql.DB, table, column, typ, defaul, comment string) error { log.I("begin to add column[%s] to the table[%s]...", column, table) exists, err := tableColumnExist(db, table, column) if err != nil { log.E("get table column exists fail %v", err.Error()) return err } if exists == false { _, err := db.Exec(fmt.Sprintf(`ALTER TABLE %s ADD %s %s default %s comment '%s';`, table, column, typ, defaul, comment)) if err != nil { log.E("add column[%s] fail %v", column, err.Error()) return err } log.I("have added column[%s] to the table[%s]", column, table) //set the old data of this field to default value _, err = db.Exec(fmt.Sprintf(`update %s set %s = ?`, table, column), "") return err } else { log.I("column[%s] already exists no need to add", column) } return nil }
func LogErr(err error, reason string) error { _, file, line, _ := runtime.Caller(1) if err != nil { log.E("%v:%v %v:%v", file, line, reason, err.Error()) } else { log.E(reason) } return errors.New(reason) }
func UpdateBankPaper(rc *impl.RCM_Cmd) (interface{}, error) { var uid, bankId int64 var paperIds, p2bIds, ext string err := rc.ValidF(` uid,R|I,R:0; bankId,R|I,R:0; paperIds,R|S,L:0; p2bIds,O|S,L:0; ext,O|S,L:0; `, &uid, &bankId, &paperIds, &p2bIds, &ext) if err != nil { log.E("UpdateBankPaper arg err:%v", err) return 0, err } extParse := []P2b_Paper{} json.Unmarshal([]byte(ext), &extParse) rs := []P2b_Paper{} paperIdsArr := []int64{} err = json.Unmarshal([]byte(paperIds), &paperIdsArr) if err != nil { return nil, err } if p2bIds == "" { p2bIds = "0" } sql_ := "delete from ebs_p2b where bank_id=? and tid not in (" + p2bIds + ")" var conn *sql.DB = dbMgr.DbConn() tx, err := conn.Begin() if err != nil { return nil, err } //同步练习 for _, v := range extParse { fmt.Println(tx.Exec("insert into ebs_p2b (tid,bank_id,paper_id,status,add1) values (?,?,?,'N','P')", v.P2bId, bankId, v.PId)) } //同步练习 if ext != "" { sql_ += " and add1='P'" } else { sql_ += " and (add1!='P' or add1 is null)" } log.D("%s", sql_) if _, err := tx.Exec(sql_, bankId); err != nil { tx.Rollback() return nil, err } for _, v := range paperIdsArr { if res, err := tx.Exec("insert into ebs_p2b (bank_id,paper_id,status) values (?,?,'N')", bankId, v); err != nil { tx.Rollback() return nil, err } else { p2bId, _ := res.LastInsertId() rs = append(rs, P2b_Paper{p2bId, v}) } } return rs, tx.Commit() }
func LogNErr(err error) error { _, file, line, _ := runtime.Caller(1) if err != nil { log.E("%v:%v %v", file, line, err.Error()) } return err }
func SimpleHandle(fn func(*routing.HTTPSession) (interface{}, error)) routing.HandleFunc { return func(hs *routing.HTTPSession) routing.HResult { rst, err := fn(hs) if err != nil { log.E("err:%v", err.Error()) return hs.MsgResE(1, err.Error()) } return _common.MsgRes(hs, rst) } }
func ChkIdx(C func(string) *tmgo.Collection, indexes map[string]map[string]tmgo.Index) error { for cname, index := range indexes { tc := C(cname) if _, err := tc.Count(); err != nil { return err } log.D("ChkIdx checking index on collection(%v)...", cname) idx_l, err := tc.Indexes() if err != nil { if qerr, ok := err.(*tmgo.QueryError); !ok || qerr.Code != 26 { err = util.Err("ChkIdx list indexes fail with error(%v) on collection(%v)", err, cname) log.E("%v", err) return err } log.D("ChkIdx the collection(%v) is not found, it will create empty one...", cname) err = tc.Create(&tmgo.CollectionInfo{}) if err != nil { err = util.Err("ChkIdx create collection(%v) fail with error(%v)", cname, err) log.E("%v", err) return err } } exists := map[string]tmgo.Index{} for _, idx := range idx_l { exists[idx.Name] = idx } for iname, idx := range index { if _, ok := exists[iname]; ok { continue } idx.Name = iname err = C(cname).EnsureIndex(idx) if err != nil { err = util.Err("ChkIdx ensure index by keys(%v),name(%v) fail with error(%v) on collection(%v)", idx.Key, idx.Name, err, cname) log.E("%v", err) return err } log.D("ChkIdx ensure index(%v) on collection(%v) success", iname, cname) } } return nil }
func GetBankItemCnt(rc *impl.RCM_Cmd) (interface{}, error) { var bankIds string err := rc.ValidF(` bankIds,R|S,L:0; `, &bankIds) if err != nil { log.E("GetBankItemCnt arg err:%v", err) return 0, err } return bank.GetBankQcAndPc(bankIds) }
func AttendBankInfo(rc *impl.RCM_Cmd) (interface{}, error) { var bankIds string err := rc.ValidF(` bankIds,R|S,L:0; `, &bankIds) if err != nil { log.E("AttendBankInfo arg err:%v", err) return 0, err } return bank.AttendBankInfo(bankIds) }
func ListBankPaper(rc *impl.RCM_Cmd) (interface{}, error) { var uid, bankId int64 err := rc.ValidF(` uid,O|I,R:0; bankId,R|I,R:0; `, &uid, &bankId) if err != nil { log.E("ListBankPaper arg err:%v", err) return 0, err } return bank.FuncListBankPaper(uid, bankId) }
func GetBankPaperScore(rc *impl.RCM_Cmd) (interface{}, error) { var bankId, paperId int64 err := rc.ValidF(` bankId,R|I,R:0; paperId,R|I,R:0; `, &bankId, &paperId) if err != nil { log.E("GetBankPaperScore arg err:%v", err) return 0, err } return bank.GetBankPaperScore(bankId, paperId) }
func (m *MDb) TPing() { var showlog = ShowLog && (util.Now()-m.log_time > ShowLogTime) if showlog { m.log_time = util.Now() log.D("MDb start ping to %v ", m.String()) } err := m.H.Ping(m.DB) if err == nil || err.Error() != "Closed explicitly" { if err == nil { if showlog { log.D("MDb ping to %v success", m.String()) } } else { log.E("MDb ping to %v error->%v, will mark to not active", m.String(), err) } m.lck.Lock() m.Active = err == nil m.ping = 0 m.lck.Unlock() return } // m.H.Close(m.DB) //do reconnect log.E("MDb ping to %v error->%v, will try reconnect", m.String(), err) for { db, err := m.H.Create() if err == nil { log.D("MDb connect to %v success, will mark to active", m.String()) m.lck.Lock() m.DB = db m.ping = 0 m.Active = true m.lck.Unlock() break } else { log.E("MDb connect to %v error->%v, will retry after 5s", m.String(), err) time.Sleep(5 * time.Second) } } }
func GetUsrPaperRecord(rc *impl.RCM_Cmd) (interface{}, error) { var p2bIds string var uid int64 err := rc.ValidF(` p2bIds,R|S,L:0; userId,R|I,R:0; `, &p2bIds, &uid) if err != nil { log.E("GetUsrPaperRecord arg err:%v", err) return 0, err } return bank.GetUsrPaperRecord(uid, p2bIds) }
func SimpleListHandle(fn func(*routing.HTTPSession) (interface{}, int64, error)) routing.HandleFunc { return func(hs *routing.HTTPSession) routing.HResult { list, total, err := fn(hs) if err != nil { log.E("err:%v", err.Error()) return hs.MsgResE(1, err.Error()) } return _common.MsgRes(hs, map[string]interface{}{ "total": total, "list": list, }) } }
func MakeDataAccessFilter(f func(*routing.HTTPSession) (bool, error)) routing.HandleFunc { return func(hs *routing.HTTPSession) routing.HResult { pass, err := f(hs) if err != nil { log.E("检验当前用户数据权限失败-%v", err.Error()) return _common.MsgResE(hs, 1, "检验当前用户数据权限失败") } if !pass { return _common.MsgResE(hs, 1, "当前用户没权限访问该数据") } return routing.HRES_CONTINUE } }
func wrapRedirectHandle(fn func(*routing.HTTPSession) []reflect.Value) routing.HandleFunc { return func(hs *routing.HTTPSession) routing.HResult { outs := fn(hs) if len(outs) != 2 { panic("redirect handle api return count should be 2") } if err, ok := outs[1].Interface().(error); ok && err != nil { log.E("err:%v", err.Error()) return hs.MsgResE(1, err.Error()) } hs.Redirect(outs[0].Interface().(string)) return _common.MsgRes(hs, outs[0].Interface().(string)) } }
func JsonUnmarshalBody(hs *routing.HTTPSession, v interface{}) error { buf, _ := ioutil.ReadAll(hs.R.Body) rdr1 := myReader{bytes.NewBuffer(buf)} rdr2 := myReader{bytes.NewBuffer(buf)} decoder := json.NewDecoder(rdr1) err := decoder.Decode(v) if err != nil { log.E("parse request body fail:%v", err.Error()) return fmt.Errorf("请求参数格式错误:%v", err) } hs.R.Body = rdr2 return nil }
func SaveAnswer(hs *routing.HTTPSession) routing.HResult { var aId int64 var a string err := hs.ValidCheckVal(` aId,R|I,R:0; a,R|S,L:0; `, &aId, &a) if err != nil { log.E("SaveAnswer arg error:%v", err) return hs.MsgResE(1, fmt.Sprintf("%s:%s", common_.ARG_ERROR, err.Error())) } aParse := []ANSWER2{} if err := json.Unmarshal([]byte(a), &aParse); err != nil { log.E("%v", err) return hs.MsgResE(1, fmt.Sprintf("%s:作答内容格式错误,%s", common_.ARG_ERROR, err.Error())) } sql_ := `update ebs_answer set content=? where tid=?` conn := dbMgr.DbConn() if _, err := conn.Exec(sql_, a, aId); err != nil { log.E("SaveAnswer db error:%v,sql:%s,args:%v", err, sql_, a) return hs.MsgResE(2, fmt.Sprintf("%s:%s", common_.DB_ERROR, err.Error())) } return hs.MsgRes("success") }
func EditBank(rc *impl.RCM_Cmd) (interface{}, error) { var bName string var id int64 err := rc.ValidF(` bName,R|S,L:0; id,R|I,R:0; `, &bName, &id) if err != nil { log.E("EditBank arg err:%v", err) return 0, err } b := &bank.BANK{} b.Tid = &id b.Name = &bName return nil, b.U(nil) }
func GetAnswerRecord(hs *routing.HTTPSession) routing.HResult { var aId int64 err := hs.ValidCheckVal(` aId,R|I,R:0; `, &aId) if err != nil { log.E("GetAnswerRecord arg error:%v", err) return hs.MsgResE(1, fmt.Sprintf("%s:%s", common_.ARG_ERROR, err.Error())) } conn := dbMgr.DbConn() var content sql.NullString if err := conn.QueryRow("select content from ebs_answer where tid=?", aId).Scan(&content); err != nil { if err != sql.ErrNoRows { return hs.MsgResE(2, err.Error()) } } return hs.MsgRes(content.String) }
func FuncListBankQuestion(uid, bankId int64) ([]QUESTION, error) { rs := []QUESTION{} usrFilter := "" args := []interface{}{bankId, bankId} if uid != 0 { usrFilter = " and b.uid=?" args = append(args, uid) } conn := dbMgr.DbConn() sql_ := `select q.TID, q.NAME, q.BANK_ID, q.PID, q.TAG, q.DESCRIPTION, q.DURATION, q.SCORE, q.Q_ANALYZE, q.TYPE,q.Q_OPTION, q.ANSWER, q.UID, q.UNAME,q2b.score,q2b.ext,q2b.tid,q2b.seq from ebs_question q join ebs_q2b q2b on q2b.bank_id=? and q2b.q_id=q.tid join ebs_bank b on b.tid=?` + usrFilter + ` order by q2b.seq asc` log.D("sql:%s", sql_) if rows, err := conn.Query(sql_, args...); err != nil { return rs, err } else { columns := []string{"TID", "NAME", "BANK_ID", "PID", "TAG", "DESCRIPTION", "DURATION", "SCORE", "Q_ANALYZE", "TYPE", "Q_OPTION", "ANSWER", "UID", "UNAME", "SCORE"} for rows.Next() { vals := []interface{}{} b := QUESTION{} for _, v := range columns { (&b).GetFieldByColumn(v, &vals) } var ext sql.NullString var q2bId int64 var q2bSeq sql.NullInt64 vals = append(vals, &ext, &q2bId, &q2bSeq) if err := rows.Scan(vals...); err != nil { log.E("scan err:%v", err) } b.Q2bId = q2bId b.Q2bSeq = q2bSeq.Int64 if ext.String != "" { extParse := EXT{} json.Unmarshal([]byte(ext.String), &extParse) b.SCORE = &extParse.Score b.DURATION = &extParse.Duration b.Ext = extParse } rs = append(rs, b) } } return rs, nil }
func editQ2b(parse []EXT, tArr []int64, p2bIdArr []int64, tx *sql.Tx) error { for i, v := range parse { if v.Score < 0 { return fmt.Errorf("分数不能为负数") } // if v.End<v.Begin{ // return fmt.Errorf("开始时间不能大于结束时间") // } if v.Duration < 0 { return fmt.Errorf("作答时间不能小于0") } tableName := "ebs_p2b" if tArr[i] == 10 { tableName = "ebs_q2b" } if tArr[i] == 30 { tableName = "ebs_p2q" } b, _ := json.Marshal(v) ext := string(b) args := []interface{}{} args = append(args, ext) extraAttr := "" if tableName == "ebs_p2q" { args = append(args, v.Score, v.Seq) extraAttr = ",score=?,seq=?" } if tableName == "ebs_q2b" && v.Seq != "" { args = append(args, v.Seq) extraAttr = ",seq=?" } args = append(args, p2bIdArr[i]) if _, err := tx.Exec("update "+tableName+" set ext=? "+extraAttr+" where tid=?", args...); err != nil { log.E("EditP2B db error:%v", err) return err } } return nil }
//作答题库题目初始化所有题目answer func InitQuestionsAnswer(uid, bankId int64, uname string, pid int64, tx *sql.Tx) error { now := time.Now().Unix() sql_ := `insert into ebs_answer (qid,paper_id,begin,uid,uname,status,type,bank_id,q2b_id,answer_key,add1 ) select q_id,0,?,?,?,'N',10,bank_id,tid,?,-1 from ebs_q2b where bank_id=? order by seq asc` if _, err := tx.Exec(sql_, now, uid, uname, pid, bankId); err != nil { return err } qs := []QUESTION{} sql_ = `update ebs_answer set paper_snapshot=?,answer_snapshot=? where q2b_id=? and answer_key=?` if rows, err := tx.Query("select q.tid,q.Q_ANALYZE,q.ANSWER,q2b.tid,q.description,q.duration,q2b.ext,q.name,q.q_option,q.pid,q2b.seq,q.score,q.type,q.uid,q.uname,q2b.bank_id,q.desc2 from ebs_question q join ebs_q2b q2b on q2b.q_id=q.tid and q2b.bank_id=?", bankId); err != nil { return err } else { for rows.Next() { q := QUESTION{} var q2bId, q2bSeq sql.NullInt64 var q2bExt sql.NullString if err := rows.Scan(&q.Tid, &q.Q_ANALYZE, &q.ANSWER, &q2bId, &q.DESCRIPTION, &q.DURATION, &q2bExt, &q.Name, &q.Q_OPTION, &q.PID, &q2bSeq, &q.SCORE, &q.TYPE, &q.UID, &q.UNAME, &q.BANK_ID, &q.DESC2); err != nil { log.E("%v", err) } q.Q2bId = q2bId.Int64 json.Unmarshal([]byte(q2bExt.String), &q.Ext) q.Q2bSeq = q2bSeq.Int64 qs = append(qs, q) } } for _, v := range qs { as := fmt.Sprintf(`{"analyze":"%s","answer":"%s","id":%d},`, *v.Q_ANALYZE, *v.ANSWER, *v.Tid) // {"analyze":"略","answer":"[[{\"content\":\"B\",\"score\":2}]]","id":3782}, if _, err := tx.Exec(sql_, v.ToString(), as, v.Q2bId, pid); err != nil { return err } } return nil }
func AddDefault2(urls string) { for _, murl := range strings.Split(urls, ";") { url_m := strings.SplitAfterN(murl, "*", 2) var count = 1 if len(url_m) > 1 { tc, err := util.ParseInt(url_m[1]) if err != nil { panic(fmt.Sprintf("parsing uri(%v) fail with error %v", murl, err)) } count = tc } var url = strings.TrimSuffix(url_m[0], "*") url_n := strings.SplitAfterN(url, "/", 2) if len(url_n) != 2 { panic(fmt.Sprintf("invalid db uri(%v)", url)) } for i := 0; i < count; i++ { //connection multi time var tempDelay time.Duration for { mdb, err := dbm.NewMDb(NewMGO_H(url, url_n[1])) if err == nil { Default.Add(mdb) break } if tempDelay == 0 { tempDelay = 100 * time.Millisecond } else { tempDelay *= 2 } if max := 8 * time.Second; tempDelay > max { tempDelay = max } log.E("AddDefault2 connection to server(%v) fail with error(%v), retrying after %v", url, err, tempDelay) time.Sleep(tempDelay) } } } }
//获取一个题库中的试卷成绩,group by uid func GetBankPaperScore(bankId, paperId int64) (interface{}, error) { rs := make(map[string]float64) sql_ := "select uid,score from ebs_answer where banK_id=? and p2b_id=? and status=?" conn := dbMgr.DbConn() if rows, err := conn.Query(sql_, bankId, paperId, "REMARKED"); err != nil { log.E("%v", err) return rs, err } else { for rows.Next() { var v1 sql.NullString var v2 sql.NullFloat64 rows.Scan(&v1, &v2) rs[v1.String] = v2.Float64 } } var totalScore sql.NullFloat64 if err := conn.QueryRow(`select sum(score) from ebs_p2q where paper_id in (select p2b.paper_id from ebs_p2b p2b where p2b.tid=?)`, paperId).Scan(&totalScore); err != nil { return rs, err } else { rs["-1"] = totalScore.Float64 } return rs, nil }
func (a *AbsV) Build(dtcm *dtm.DTCM_S, id, info interface{}, args ...interface{}) (interface{}, interface{}, []interface{}, error) { var src = fmt.Sprintf("%v", args[0]) video, err := ParseVideo(filepath.Join(a.WDir, src)) if err != nil { err = util.Err("AbsV parse video by src(%v) error->%v", src, err) log.E("%v", err) return nil, nil, nil, err } video.Info = info video.Alias = a.Alias var mv, _ = util.Json2Map(util.S2Json(video)) var tw, th, dur = video.Width, video.Height, int64(video.Duration * 1000000) var dst interface{} if len(args) > 1 { dst = args[1] } else { dst = strings.TrimSuffix(src, filepath.Ext(src)) } log.D("AbsV adding task by src(%v),width(%v),height(%v),duration(%v)", src, tw, th, dur) return id, mv, []interface{}{ src, dst, tw, th, dur, }, nil }
func getPaper(id int64, f int64) (p PAPER, err_ error) { conn := dbMgr.DbConn() fmt.Println(conn.QueryRow("select tid,name,description,bank_id,tag,duration,score,q_grp,uid,uname from ebs_paper where tid=? and status='N'", id).Scan( &p.Tid, &p.Name, &p.DESCRIPTION, &p.BANK_ID, &p.TAG, &p.DURATION, &p.SCORE, &p.Q_GRP, &p.UID, &p.UNAME, )) qgParse := []Q_GRP{} if p.Q_GRP != nil { fmt.Println(json.Unmarshal([]byte(*p.Q_GRP), &qgParse)) } if len(qgParse) == 0 { return } questions := []map[string]interface{}{} child_questions := []map[string]interface{}{} sql_ := `select q.q_analyze,q.answer,q.tid,q.name,q.pid,q.tag,q.description,q.duration,q.score,q.type,q.q_option,p2q.seq,p2q.q_grp,p2q.tid,p2q.ext,q.desc2,q.uid from ebs_p2q p2q join ebs_question q on q.tid=p2q.qid where p2q.paper_id=? order by p2q.seq` //union select q.q_analyze,q.answer,q.tid,q.name,q.pid,q.tag,q.description,q.duration,q.score,q.type,q.q_option,0,0,0,0,q.desc2,q.uid from ebs_question q where q.pid<>0 and q.pid in ( //select q.tid from ebs_p2q p2q join ebs_question q on q.tid=p2q.qid where p2q.paper_id=?) if rows, err := conn.Query(sql_, id); err != nil { log.E("GetPaperDetail Query err:%v,sql:%s", err, sql_) err_ = err return } else { for rows.Next() { var v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17 sql.NullString rows.Scan(&v12, &v13, &v1, &v2, &v3, &v4, &v5, &v6, &v7, &v8, &v9, &v10, &v11, &v14, &v15, &v16, &v17) if v3.String != "0" { o := map[string]interface{}{ "id": v1.String, "name": v2.String, "pid": v3.String, "tag": v4.String, "description": v5.String, "desc": v5.String, "duration": v6.String, "score": v7.String, "type": v8.String, "option": v9.String, "seq": v10.String, "uid": v17.String, } if v8.String == "35" { o["description"], o["desc"] = v16.String, v16.String } if f == 1 { o["answer"] = v13.String o["analyze"] = v12.String o["desc"] = v5.String } child_questions = append(child_questions, o) } else { o := map[string]interface{}{ "id": v1.String, "name": v2.String, "pid": v3.String, "tag": v4.String, "description": v5.String, "desc": v5.String, "duration": v6.String, "score": func() float64 { ext_ := EXT{} json.Unmarshal([]byte(v15.String), &ext_) return ext_.Score }(), "type": v8.String, "option": v9.String, "seq": v10.String, "qGrp": v11.String, "p2qId": v14.String, "ext": func() EXT { ext_ := EXT{} json.Unmarshal([]byte(v15.String), &ext_) return ext_ }(), "uid": v17.String, } if v8.String == "35" { o["description"], o["desc"] = v16.String, v16.String } if f == 1 { o["answer"] = v13.String o["analyze"] = v12.String o["desc"] = v5.String } questions = append(questions, o) } } for i_, v_ := range questions { children := []map[string]interface{}{} for _, v := range child_questions { if v["pid"] == v_["id"] { children = append(children, v) } } questions[i_]["children"] = children } } var totalScore float64 for _, v_ := range questions { totalScore += v_["score"].(float64) } for i, v := range qgParse { children := []map[string]interface{}{} for _, v_ := range questions { if v_["qGrp"] == fmt.Sprintf("%d", v.Id) { children = append(children, v_) } } qgParse[i].Questions = children } p.SCORE = &totalScore p.Q_PARSE = qgParse return }
//查看题库题目,不显示题目答案 func FuncListBankQuestion2(bankId int64, parse common.ListParam, aid int64) ([]QUESTION, common.Pagiation, error) { rs := []QUESTION{} args := []interface{}{bankId} args = append(args, aid) // answerFilter := "" // if aid!=0{ // answerFilter = " and a.answer_key=?" // } statusFilter := "" //1答对,0答错,-1未答 if parse.Status != "" { statusFilter = " and a.add1=?" s := parse.Status if parse.Status == "-1" { statusFilter = " and a.status=?" s = "N" } args = append(args, s) } typeFilter := "" if parse.Type != 0 { typeFilter = " and q.type=?" args = append(args, parse.Type) } if parse.Pa.Pn < 1 || parse.Pa.Ps < 1 { parse.Pa.Pn = 1 parse.Pa.Ps = 10 } start := (parse.Pa.Pn - 1) * parse.Pa.Ps end := parse.Pa.Ps conn := dbMgr.DbConn() tx, err := conn.Begin() if err != nil { return rs, parse.Pa, err } sql_ := fmt.Sprintf(`select SQL_CALC_FOUND_ROWS q.TID, q.NAME, q.BANK_ID, q.PID, q.TAG, q.DESCRIPTION, q.DURATION, q.SCORE, q.Q_ANALYZE, q.TYPE,q.Q_OPTION, q.UID, q.UNAME,q2b.score,q2b.ext,q2b.tid,q2b.seq,q.desc2,a.tid,a.status,a.content,a.paper_snapshot,a.answer_snapshot from ebs_answer a left join ebs_question q on q.tid=a.qid left join ebs_q2b q2b on q2b.tid=a.q2b_id and q2b.bank_id=? where a.answer_key=? %s order by q2b.seq asc limit %d,%d`, statusFilter+typeFilter, start, end) if aid == 0 { sql_ = fmt.Sprintf(`select SQL_CALC_FOUND_ROWS q.TID, q.NAME, q.BANK_ID, q.PID, q.TAG, q.DESCRIPTION, q.DURATION, q.SCORE, q.Q_ANALYZE, q.TYPE,q.Q_OPTION, q.UID, q.UNAME,q2b.score,q2b.ext,q2b.tid,q2b.seq,q.desc2,a.tid,a.status,a.content,a.paper_snapshot,a.answer_snapshot from ebs_question q join ebs_q2b q2b on q2b.bank_id=? and q2b.q_id=q.tid left join ebs_answer a on a.answer_key=? and a.q2b_id=q2b.tid where 1=1 %s order by q2b.seq asc limit %d,%d`, statusFilter+typeFilter, start, end) } log.D("%v", sql_) if rows, err := tx.Query(sql_, args...); err != nil { tx.Commit() return rs, parse.Pa, err } else { columns := []string{"TID", "NAME", "BANK_ID", "PID", "TAG", "DESCRIPTION", "DURATION", "SCORE", "Q_ANALYZE", "TYPE", "Q_OPTION", "UID", "UNAME", "SCORE"} for rows.Next() { vals := []interface{}{} b := QUESTION{} for _, v := range columns { (&b).GetFieldByColumn(v, &vals) } var ext, desc2, aStatus, aContent, paperSnapshot, answerSnapshot sql.NullString var q2bId sql.NullInt64 var q2bSeq, aIdRes sql.NullInt64 vals = append(vals, &ext, &q2bId, &q2bSeq, &desc2, &aIdRes, &aStatus, &aContent, &paperSnapshot, &answerSnapshot) if err := rows.Scan(vals...); err != nil { log.E("scan err:%v", err) } qParse := QUESTION{} json.Unmarshal([]byte(paperSnapshot.String), &qParse) if qParse.Tid != nil { log.D("qParse:%v", qParse.ToString()) b = qParse bb, _ := json.Marshal(qParse.Ext) ext.String = string(bb) } b.Q2bId = q2bId.Int64 b.Q2bSeq = q2bSeq.Int64 if b.TYPE != nil { if *b.TYPE == 35 { b.DESCRIPTION = &desc2.String } } if aid != 0 { b.Extra = map[string]interface{}{"aid": aIdRes.Int64, "aStatus": aStatus.String, "aContent": aContent.String} } if ext.String != "" { extParse := EXT{} json.Unmarshal([]byte(ext.String), &extParse) b.SCORE = &extParse.Score b.DURATION = &extParse.Duration b.Ext = extParse } rs = append(rs, b) } } if err := tx.QueryRow(`select FOUND_ROWS()`).Scan(&parse.Pa.Total); err != nil { tx.Commit() return rs, parse.Pa, err } tx.Commit() return rs, parse.Pa, nil }