Create & Init Project...

This commit is contained in:
2019-04-22 18:49:16 +08:00
commit fc4fa37393
25440 changed files with 4054998 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dangbei_test.go",
"dao_test.go",
"mango_recom_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/tv/conf:go_default_library",
"//app/interface/main/tv/model/thirdp:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dangbei.go",
"dao.go",
"mango_db.go",
"mango_mc.go",
"mango_recom.go",
],
importpath = "go-common/app/interface/main/tv/dao/thirdp",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/tv/conf:go_default_library",
"//app/interface/main/tv/model/thirdp:go_default_library",
"//library/cache/memcache:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/ecode:go_default_library",
"//library/log:go_default_library",
"//library/stat/prom:go_default_library",
"//library/xstr:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)

View File

@@ -0,0 +1,264 @@
package thirdp
import (
"context"
"fmt"
"go-common/app/interface/main/tv/model/thirdp"
"go-common/library/cache/redis"
"go-common/library/database/sql"
"go-common/library/ecode"
"go-common/library/log"
)
const (
_dangbeiPGCPage = "SELECT id FROM tv_ep_season WHERE `check`= 1 AND valid = 1 AND is_deleted=0 %s ORDER BY id"
_dangbeiUGCPage = "SELECT aid FROM ugc_archive WHERE result = 1 AND valid = 1 AND deleted = 0 %s ORDER BY aid"
_dangbeiPGCCount = "SELECT count(1) FROM tv_ep_season WHERE `check`= 1 AND valid= 1 AND is_deleted=0"
_dangbeiUGCCount = "SELECT count(1) FROM ugc_archive WHERE result = 1 AND valid= 1 AND deleted =0"
_dangbeiPGCKey = "TV_Dangbei_PGC_Page"
_dangbeiUGCKey = "TV_Dangbei_UGC_Page"
_countField = "Dangbei_Count"
// DBeiPGC is dangbei pgc typeC
DBeiPGC = "pgc"
// DBeiUGC is dangbei ugc typeC
DBeiUGC = "ugc"
)
// KeyThirdp returns the key in Redis according to the type input
func KeyThirdp(typeC string) (key string, err error) {
switch typeC {
case DBeiPGC:
key = _dangbeiPGCKey
case DBeiUGC:
key = _dangbeiUGCKey
case MangoPGC:
key = _mangoPGCKey
case MangoUGC:
key = _mangoUGCKey
default:
err = ecode.TvDangbeiWrongType
}
return
}
// ThirdpCnt counts the number of pgc/ugc data to display for dangbei
func (d *Dao) ThirdpCnt(ctx context.Context, typeC string) (count int, err error) {
var query string
switch typeC {
case DBeiPGC:
query = _dangbeiPGCCount
case DBeiUGC:
query = _dangbeiUGCCount
case MangoPGC:
query = _mangoPGCCount
case MangoUGC:
query = _mangoUGCCount
default:
err = ecode.TvDangbeiWrongType
return
}
if err = d.db.QueryRow(ctx, query).Scan(&count); err != nil {
log.Error("PickDBeiPage ThirdpCnt Error %v", err)
}
return
}
// DBeiPages picks a page for dangbei api, lastID is the last page's biggest ID
func (d *Dao) DBeiPages(ctx context.Context, req *thirdp.ReqDBeiPages) (sids []int64, myLast int64, err error) {
var (
rows *sql.Rows
query string
lastID = req.LastID
ps = req.Ps
)
switch req.TypeC {
case DBeiPGC:
query = fmt.Sprintf(_dangbeiPGCPage+" LIMIT %d", "AND id> ?", ps)
case DBeiUGC:
query = fmt.Sprintf(_dangbeiUGCPage+" LIMIT %d", "AND aid> ?", ps)
default:
err = ecode.TvDangbeiWrongType
return
}
if rows, err = d.db.Query(ctx, query, lastID); err != nil {
log.Error("DangbeiPage, lastID %d, Err %v", lastID, err)
return
}
defer rows.Close()
if sids, myLast, err = dbeiRowsTreat(rows); err != nil {
log.Error("dbeiOffset lastID %d, Err %v", lastID, err)
}
return
}
func dbeiRowsTreat(rows *sql.Rows) (sids []int64, myLast int64, err error) {
for rows.Next() {
var r int64
if err = rows.Scan(&r); err != nil {
return
}
sids = append(sids, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
return
}
// record my biggest id
if len(sids) > 0 {
myLast = sids[len(sids)-1]
}
return
}
// thirdpOffset is used in case of missing pageID record in Redis
func (d *Dao) thirdpOffset(ctx context.Context, page int64, ps int64, typeC string) (lastPageMax int64, err error) {
if page <= 0 {
return 0, nil
}
var query string
switch typeC {
case DBeiPGC:
query = _dangbeiPGCPage
case DBeiUGC:
query = _dangbeiUGCPage
case MangoPGC:
query = _mangoPGCOffset
case MangoUGC:
query = _mangoUGCOffset
default:
err = ecode.TvDangbeiWrongType
return
}
querySQL := fmt.Sprintf(query+" LIMIT %d,%d", "", page*ps-1, 1)
if err = d.db.QueryRow(ctx, querySQL).Scan(&lastPageMax); err != nil {
log.Error("DangbeiPage, page %d, Err %v", page, err)
}
return
}
// SetPageID is used to record each dangbei page's biggest ID, it's to ease the next page's pickup
func (d *Dao) SetPageID(c context.Context, req *thirdp.ReqPageID) (err error) {
var key string
if key, err = KeyThirdp(req.TypeC); err != nil {
log.Error("PickDBeiPage Dangbei Key TypeC = %v, Error %v", req.TypeC, err)
return
}
conn := d.redis.Get(c)
defer conn.Close()
if err = conn.Send("HSET", key, req.Page, req.ID); err != nil {
log.Error("PickDBeiPage conn.Send(HSET Key %v, field %d, value %d) error(%v)", key, req.Page, req.ID, err)
return
}
if err = conn.Send("EXPIRE", key, d.dbeiExpire); err != nil {
log.Error("PickDBeiPage conn.Send error(%v)", err)
return
}
if err = conn.Flush(); err != nil {
log.Error("PickDBeiPage conn.Flush error(%v)", err)
return
}
for i := 0; i < 2; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("PickDBeiPage conn.Receive error(%v)", err)
return
}
}
return
}
// SetThirdpCnt is used to record dangbei pgc data count
func (d *Dao) SetThirdpCnt(c context.Context, count int, typeC string) (err error) {
var key string
if key, err = KeyThirdp(typeC); err != nil {
log.Error("PickDBeiPage Dangbei Key TypeC = %v, Error %v", typeC, err)
return
}
conn := d.redis.Get(c)
defer conn.Close()
if err = conn.Send("HSET", key, _countField, count); err != nil {
log.Error("PickDBeiPage conn.Send(HSET Key %v, field %d, value %d) error(%v)", key, _countField, count, err)
return
}
if err = conn.Send("EXPIRE", key, d.dbeiExpire); err != nil {
log.Error("PickDBeiPage conn.Send error(%v)", err)
return
}
if err = conn.Flush(); err != nil {
log.Error("PickDBeiPage conn.Flush error(%v)", err)
return
}
for i := 0; i < 2; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("PickDBeiPage conn.Receive error(%v)", err)
return
}
}
return
}
// GetThirdpCnt get dangbei pgc data count
func (d *Dao) GetThirdpCnt(c context.Context, typeC string) (count int, err error) {
var key string
if key, err = KeyThirdp(typeC); err != nil {
log.Error("PickDBeiPage Dangbei Key TypeC = %v, Error %v", typeC, err)
return
}
conn := d.redis.Get(c)
defer conn.Close()
if count, err = redis.Int(conn.Do("HGET", key, _countField)); err != nil {
if err == redis.ErrNil {
log.Info("PickDBeiPage conn.HGET(field:%s) not found", _countField)
} else {
log.Error("PickDBeiPage conn.HGET(field:%s) error(%v)", _countField, err)
}
}
return
}
// getPageID get pageNumber's biggestID from redis hashmap
func (d *Dao) getPageID(c context.Context, pageNumber int64, typeC string) (biggestID int64, err error) {
var key string
if key, err = KeyThirdp(typeC); err != nil {
log.Error("Dangbei Key TypeC = %v, Error %v", typeC, err)
return
}
conn := d.redis.Get(c)
defer conn.Close()
if biggestID, err = redis.Int64(conn.Do("HGET", key, pageNumber)); err != nil {
if err == redis.ErrNil {
log.Info("conn.HGET(page:%d) not found", pageNumber)
} else {
log.Error("conn.HGET(page:%d) error(%v)", pageNumber, err)
}
}
return
}
// LoadPageID picks the last page's biggest ID
func (d *Dao) LoadPageID(c context.Context, req *thirdp.ReqDBeiPages) (biggestID int64, err error) {
var (
pageNum = req.Page - 1
typeC = req.TypeC
)
if pageNum <= 0 {
return 0, nil
}
if biggestID, err = d.getPageID(c, pageNum, typeC); err == nil { // get directly from cache
cachedCount.Add("thirdp-page", 1)
return
}
missedCount.Add("thirdp-page", 1)
if biggestID, err = d.thirdpOffset(c, pageNum, req.Ps, typeC); err != nil {
log.Error("ThirdpOffSet TypeC %s, PageNum %d, Pagesize %d", typeC, pageNum, req.Ps)
return
}
if err = d.SetPageID(c, &thirdp.ReqPageID{
Page: pageNum,
ID: biggestID,
TypeC: typeC,
}); err != nil {
log.Error("ThirdpOffset TypeC %s, PageNum %d, SetPageID Err %v", typeC, pageNum, err)
}
return
}

View File

@@ -0,0 +1,145 @@
package thirdp
import (
"context"
"encoding/json"
"fmt"
"testing"
"go-common/app/interface/main/tv/model/thirdp"
. "github.com/smartystreets/goconvey/convey"
)
func TestDao_GetDBeiCount(t *testing.T) {
Convey("TestDao_GetDBeiCount", t, WithDao(func(d *Dao) {
count, err := d.GetThirdpCnt(ctx, DBeiUGC)
So(err, ShouldBeNil)
So(count, ShouldBeGreaterThan, 0)
fmt.Println(count)
}))
}
func TestDao_SetDBeiCount(t *testing.T) {
Convey("TestDao_SetDBeiCount", t, WithDao(func(d *Dao) {
err := d.SetThirdpCnt(ctx, 6667, DBeiUGC)
So(err, ShouldBeNil)
}))
}
func TestDao_ThirdpCnt(t *testing.T) {
Convey("TestDao_ThirdpCnt", t, WithDao(func(d *Dao) {
cntDBeiPGC, err2 := d.ThirdpCnt(ctx, DBeiPGC)
So(err2, ShouldBeNil)
So(cntDBeiPGC, ShouldBeGreaterThan, 0)
fmt.Println(cntDBeiPGC)
cntDBeiUGC, err := d.ThirdpCnt(ctx, DBeiUGC)
So(err, ShouldBeNil)
So(cntDBeiUGC, ShouldBeGreaterThan, 0)
fmt.Println(cntDBeiUGC)
cntMangoPGC, err3 := d.ThirdpCnt(ctx, MangoPGC)
So(err3, ShouldBeNil)
So(cntMangoPGC, ShouldBeGreaterThan, 0)
fmt.Println(cntMangoPGC)
cntMangoUGC, err4 := d.ThirdpCnt(ctx, MangoUGC)
So(err4, ShouldBeNil)
So(cntMangoUGC, ShouldBeGreaterThan, 0)
fmt.Println(cntMangoUGC)
So(cntDBeiPGC, ShouldBeLessThanOrEqualTo, cntMangoPGC)
So(cntDBeiUGC, ShouldBeLessThanOrEqualTo, cntMangoUGC)
}))
}
func TestDao_ThirdpPages(t *testing.T) {
Convey("TestDao_ThirdpPages", t, WithDao(func(d *Dao) {
typesDBei := []string{
DBeiPGC, DBeiUGC,
}
for _, v := range typesDBei {
fmt.Println("--- ", v, " ---")
req := &thirdp.ReqDBeiPages{
LastID: 255,
Ps: 10,
TypeC: v,
}
sids, myID, err := d.DBeiPages(ctx, req)
So(err, ShouldBeNil)
fmt.Println(sids)
So(myID, ShouldBeGreaterThan, 0)
fmt.Println(myID)
}
typesMango := []string{
MangoPGC, MangoUGC,
}
for _, v := range typesMango {
fmt.Println("--- ", v, " ---")
req := &thirdp.ReqDBeiPages{
LastID: 255,
Ps: 10,
TypeC: v,
}
sids, myID, err := d.MangoPages(ctx, req)
So(err, ShouldBeNil)
str, _ := json.Marshal(sids)
fmt.Println(string(str))
So(myID, ShouldBeGreaterThan, 0)
fmt.Println(myID)
}
}))
}
func TestDao_thirdpOffset(t *testing.T) {
Convey("TestDao_thirdpOffset", t, WithDao(func(d *Dao) {
lastMax, err := d.thirdpOffset(context.Background(), 1, 50, MangoPGC)
So(lastMax, ShouldEqual, 0)
So(err, ShouldBeNil)
types := []string{
DBeiPGC, DBeiUGC, MangoPGC, MangoUGC,
}
for _, v := range types {
lastMaxType, errP := d.thirdpOffset(context.Background(), 2, 50, v)
So(lastMaxType, ShouldBeGreaterThan, 0)
So(errP, ShouldBeNil)
fmt.Println(fmt.Sprintf("[Type - %s] [Max - %d]", v, lastMaxType))
}
}))
}
func TestDao_SetPageID(t *testing.T) {
Convey("TestDao_SetPageID", t, WithDao(func(d *Dao) {
err := d.SetPageID(ctx, &thirdp.ReqPageID{
TypeC: DBeiUGC,
ID: 8088,
Page: 3,
})
So(err, ShouldBeNil)
}))
}
func TestDao_GetPageID(t *testing.T) {
Convey("TestDao_GetPageID", t, WithDao(func(d *Dao) {
biggestID, err := d.getPageID(ctx, 7, DBeiUGC)
So(err, ShouldBeNil)
So(biggestID, ShouldBeGreaterThan, 0)
fmt.Println(biggestID)
}))
}
func TestDao_LoadPageID(t *testing.T) {
Convey("TestDao_LoadPageID", t, WithDao(func(d *Dao) {
types := []string{
DBeiPGC, DBeiUGC, MangoPGC, MangoUGC,
}
for _, v := range types {
req := &thirdp.ReqDBeiPages{
Page: 7,
Ps: 50,
TypeC: v,
}
biggestID, err := d.LoadPageID(ctx, req)
So(err, ShouldBeNil)
So(biggestID, ShouldBeGreaterThan, 0)
fmt.Println("Type: ", v, " Max: ", biggestID)
}
}))
}

View File

@@ -0,0 +1,63 @@
package thirdp
import (
"runtime"
"time"
"go-common/app/interface/main/tv/conf"
"go-common/library/cache/memcache"
"go-common/library/cache/redis"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/stat/prom"
)
// Dao .
type Dao struct {
db *sql.DB
conf *conf.Config
redis *redis.Pool
mc *memcache.Pool
dbeiExpire int64
cntExpire int32
mCh chan func()
}
// New .
func New(c *conf.Config) (d *Dao) {
d = &Dao{
db: sql.NewMySQL(c.Mysql),
conf: c,
redis: redis.NewPool(c.Redis.Config),
dbeiExpire: int64(time.Duration(c.Cfg.Dangbei.Expire) / time.Second),
mc: memcache.NewPool(c.Memcache.Config),
cntExpire: int32(time.Duration(c.Memcache.MangoExpire) / time.Second),
mCh: make(chan func(), 10240),
}
for i := 0; i < runtime.NumCPU()*2; i++ {
go d.cacheproc()
}
return
}
var (
cachedCount = prom.CacheHit
missedCount = prom.CacheMiss
)
// addCache add archive to mc or redis
func (d *Dao) addCache(f func()) {
select {
case d.mCh <- f:
default:
log.Warn("cacheproc chan full")
}
}
// cacheproc write memcache and stat redis use goroutine
func (d *Dao) cacheproc() {
for {
f := <-d.mCh
f()
}
}

View File

@@ -0,0 +1,30 @@
package thirdp
import (
"context"
"flag"
"path/filepath"
"go-common/app/interface/main/tv/conf"
. "github.com/smartystreets/goconvey/convey"
)
var (
d *Dao
ctx = context.Background()
)
func init() {
dir, _ := filepath.Abs("../../cmd/tv-interface.toml")
flag.Set("conf", dir)
conf.Init()
d = New(conf.Conf)
}
func WithDao(f func(d *Dao)) func() {
return func() {
Reset(func() {})
f(d)
}
}

View File

@@ -0,0 +1,104 @@
package thirdp
import (
"context"
"fmt"
"go-common/app/interface/main/tv/model/thirdp"
"go-common/library/database/sql"
"go-common/library/log"
)
const (
_mangoPGCPage = "SELECT id,mtime FROM tv_ep_season %s ORDER BY id"
_mangoUGCPage = "SELECT aid,mtime FROM ugc_archive %s ORDER BY aid"
_mangoPGCOffset = "SELECT id FROM tv_ep_season %s ORDER BY id"
_mangoUGCOffset = "SELECT aid FROM ugc_archive %s ORDER BY aid"
_mangoPGCCount = "SELECT count(1) FROM tv_ep_season"
_mangoUGCCount = "SELECT count(1) FROM ugc_archive"
_mangoPGCSnCount = "SELECT count(1) FROM tv_content WHERE season_id = ?"
_mangoUGCArcCount = "SELECT count(1) FROM ugc_video WHERE aid = ?"
_mangoPGCSnOffset = "SELECT epid,mtime FROM tv_content WHERE season_id = ?"
_mangoUGCArcOffset = "SELECT cid,mtime FROM ugc_video WHERE aid = ?"
_mangoPGCKey = "TV_Mango_PGC_Page"
_mangoUGCKey = "TV_Mango_UGC_Page"
// MangoPGC is mango pgc typeC
MangoPGC = "mango_pgc"
// MangoUGC is mango ugc typeC
MangoUGC = "mango_ugc"
)
// MangoPages picks a page for dangbei api, lastID is the last page's biggest ID
func (d *Dao) MangoPages(ctx context.Context, req *thirdp.ReqDBeiPages) (sids []*thirdp.RespSid, myLast int64, err error) {
var (
rows *sql.Rows
query string
)
switch req.TypeC {
case MangoPGC:
query = fmt.Sprintf(_mangoPGCPage+" LIMIT %d", " WHERE id> ?", req.Ps)
case MangoUGC:
query = fmt.Sprintf(_mangoUGCPage+" LIMIT %d", " WHERE aid> ?", req.Ps)
default:
err = fmt.Errorf("MangoPages Wrong Type %s", req.TypeC)
return
}
if rows, err = d.db.Query(ctx, query, req.LastID); err != nil {
log.Error("MangoPages, lastID %d, Err %v", req.LastID, err)
return
}
defer rows.Close()
if sids, myLast, err = mangoRowsTreat(rows); err != nil {
log.Error("MangoPages lastID %d, Err %v", req.LastID, err)
}
return
}
func mangoRowsTreat(rows *sql.Rows) (sids []*thirdp.RespSid, myLast int64, err error) {
for rows.Next() {
var r = thirdp.RespSid{}
if err = rows.Scan(&r.Sid, &r.Mtime); err != nil {
return
}
sids = append(sids, &r)
}
if len(sids) > 0 {
myLast = sids[len(sids)-1].Sid
}
return
}
// MangoSnCnt counts ep/video number from DB
func (d *Dao) MangoSnCnt(ctx context.Context, isPGC bool, sid int64) (cnt int, err error) {
var querySQL string
if isPGC {
querySQL = _mangoPGCSnCount
} else {
querySQL = _mangoUGCArcCount
}
if err = d.db.QueryRow(ctx, querySQL, sid).Scan(&cnt); err != nil {
log.Error("MangoSnCnt isPGC %v, Sid %d, Err %v", isPGC, sid, err)
}
return
}
// MangoSnOffset picks season or arc's detail info by page ( limit + offset )
func (d *Dao) MangoSnOffset(ctx context.Context, isPGC bool, sid int64, pageN, pagesize int) (epids []*thirdp.RespSid, err error) {
var (
querySQL = fmt.Sprintf(" LIMIT %d, %d", (pageN-1)*pagesize, pagesize)
rows *sql.Rows
)
if isPGC {
querySQL = _mangoPGCSnOffset + querySQL
} else {
querySQL = _mangoUGCArcOffset + querySQL
}
if rows, err = d.db.Query(ctx, querySQL, sid); err != nil {
log.Error("MangoSnOffset, Sid %d, IsPGC %v, Err %v", sid, isPGC, err)
return
}
defer rows.Close()
if epids, _, err = mangoRowsTreat(rows); err != nil {
log.Error("MangoSnOffset, Sid %d, IsPGC %v, Err %v", sid, isPGC, err)
}
return
}

View File

@@ -0,0 +1,65 @@
package thirdp
import (
"context"
"fmt"
"go-common/library/cache/memcache"
"go-common/library/log"
)
func mangoMCKey(isPGC bool, sid int64) string {
if isPGC {
return fmt.Sprintf("%s_%d", "mango_pgc", sid)
}
return fmt.Sprintf("%s_%d", "mango_ugc", sid)
}
// SetSnCnt save season/archive count
func (d *Dao) SetSnCnt(c context.Context, isPGC bool, sid int64, cnt int) (err error) {
var (
key = mangoMCKey(isPGC, sid)
conn = d.mc.Get(c)
)
defer conn.Close()
if err = conn.Set(&memcache.Item{Key: key, Object: cnt, Flags: memcache.FlagJSON, Expiration: d.cntExpire}); err != nil {
log.Error("conn.Set error(%v)", err)
return
}
return
}
// GetSnCnt get season/archive count cache.
func (d *Dao) GetSnCnt(c context.Context, isPGC bool, sid int64) (cnt int, err error) {
var (
key = mangoMCKey(isPGC, sid)
conn = d.mc.Get(c)
item *memcache.Item
)
defer conn.Close()
if item, err = conn.Get(key); err != nil {
if err != memcache.ErrNotFound {
log.Error("conn.Get(%s) error(%v)", key, err)
}
return
}
if err = conn.Scan(item, &cnt); err != nil {
log.Error("conn.Get(%s) error(%v)", key, err)
}
return
}
// LoadSnCnt loads season's ep cnt, or archive's video cnt
func (d *Dao) LoadSnCnt(ctx context.Context, isPGC bool, sid int64) (cnt int, err error) {
if cnt, err = d.GetSnCnt(ctx, isPGC, sid); err == nil { // not found or MC error
return
}
log.Warn("LoadSnCnt IsPGC %v, Get Sid [%d] from MC Err (%v)", isPGC, sid, err) // cache set/get error
if cnt, err = d.MangoSnCnt(ctx, isPGC, sid); err != nil {
return
}
d.addCache(func() {
d.SetSnCnt(ctx, isPGC, sid, cnt)
})
return
}

View File

@@ -0,0 +1,73 @@
package thirdp
import (
"context"
"fmt"
model "go-common/app/interface/main/tv/model/thirdp"
"go-common/library/cache/memcache"
"go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_mangoRecomKey = "mango_cms_recom"
_mangoRecom = "SELECT id, rid, rtype, title, cover , category, playcount, jid, content, staff , rorder FROM mango_recom WHERE deleted = 0 AND id IN (%s)"
)
// MangoOrder gets mango recom data.
func (d *Dao) MangoOrder(c context.Context) (s []int64, err error) {
var (
conn = d.mc.Get(c)
item *memcache.Item
res = model.MangoOrder{}
)
defer conn.Close()
if item, err = conn.Get(_mangoRecomKey); err != nil {
if err == memcache.ErrNotFound {
err = nil
return
}
log.Error("conn.Get(%s) error (%v)", _mangoRecomKey, err)
return
}
if err = conn.Scan(item, &res); err != nil {
log.Error("conn.Scan(%s) error(%v)", _mangoRecomKey, err)
}
s = res.RIDs
return
}
// MangoRecom picks the mango recom data from DB
func (d *Dao) MangoRecom(c context.Context, ids []int64) (data []*model.MangoRecom, err error) {
var (
rows *sql.Rows
query = fmt.Sprintf(_mangoRecom, xstr.JoinInts(ids))
dataSet = make(map[int64]*model.MangoRecom, len(ids))
)
if rows, err = d.db.Query(c, query); err != nil {
log.Error("mangoRecom, Err %v", err)
return
}
// SELECT id, rid, rtype, title, cover , category, playcount, jid, content, staff , rorder
for rows.Next() {
var r = &model.MangoRecom{}
if err = rows.Scan(&r.ID, &r.RID, &r.Rtype, &r.Title, &r.Cover, &r.Category, &r.Playcount, &r.JID, &r.Content, &r.Staff, &r.Rorder); err != nil {
return
}
dataSet[r.ID] = r
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
return
}
for _, v := range ids {
if value, ok := dataSet[v]; ok {
data = append(data, value)
continue
}
log.Warn("MangoRecom RID %d Missing", v)
}
return
}

View File

@@ -0,0 +1,35 @@
package thirdp
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestThirdpMangoOrder(t *testing.T) {
var (
c = context.Background()
)
convey.Convey("MangoOrder", t, func(ctx convey.C) {
s, err := d.MangoOrder(c)
ctx.Convey("Then err should be nil.s should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(s, convey.ShouldNotBeNil)
})
})
}
func TestThirdpMangoRecom(t *testing.T) {
var (
c = context.Background()
ids = []int64{}
)
convey.Convey("MangoRecom", t, func(ctx convey.C) {
data, err := d.MangoRecom(c, ids)
ctx.Convey("Then err should be nil.data should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(data, convey.ShouldNotBeNil)
})
})
}