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,73 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
"go_library",
)
go_test(
name = "go_default_test",
srcs = [
"dao_test.go",
"databus_test.go",
"mysql_test.go",
"redis_test.go",
"reply_test.go",
"search_test.go",
"stat_redis_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/playlist/conf:go_default_library",
"//app/interface/main/playlist/model:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"databus.go",
"mysql.go",
"redis.go",
"reply.go",
"search.go",
"stat_redis.go",
],
importpath = "go-common/app/interface/main/playlist/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/playlist/conf:go_default_library",
"//app/interface/main/playlist/model:go_default_library",
"//app/job/main/playlist/model: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/net/http/blademaster:go_default_library",
"//library/net/metadata:go_default_library",
"//library/queue/databus:go_default_library",
"//library/stat/prom:go_default_library",
"//library/time: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,80 @@
package dao
import (
"context"
"fmt"
"time"
"go-common/app/interface/main/playlist/conf"
"go-common/library/cache/redis"
"go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/queue/databus"
"go-common/library/stat/prom"
)
// Dao dao struct.
type Dao struct {
// config
c *conf.Config
// db
db *sql.DB
// redis
redis *redis.Pool
statExpire int32
plExpire int32
// http client
http *bm.Client
// stmt
videosStmt map[string]*sql.Stmt
// databus
viewDbus *databus.Databus
shareDbus *databus.Databus
// search video URL
searchURL string
}
// New new dao.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
// config
c: c,
db: sql.NewMySQL(c.Mysql),
redis: redis.NewPool(c.Redis.Config),
statExpire: int32(time.Duration(c.Redis.StatExpire) / time.Second),
plExpire: int32(time.Duration(c.Redis.PlExpire) / time.Second),
http: bm.NewClient(c.HTTPClient),
viewDbus: databus.New(c.ViewDatabus),
shareDbus: databus.New(c.ShareDatabus),
searchURL: c.Host.Search + _searchURL,
}
d.videosStmt = make(map[string]*sql.Stmt, _plArcSub)
for i := 0; i < _plArcSub; i++ {
key := fmt.Sprintf("%02d", i)
d.videosStmt[key] = d.db.Prepared(fmt.Sprintf(_plArcsSQL, key))
}
return
}
// Ping ping dao
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.db.Ping(c); err != nil {
return
}
err = d.pingRedis(c)
return
}
func (d *Dao) pingRedis(c context.Context) (err error) {
conn := d.redis.Get(c)
_, err = conn.Do("SET", "PING", "PONG")
conn.Close()
return
}
// PromError stat and log.
func PromError(name string, format string, args ...interface{}) {
prom.BusinessErrCount.Incr(name)
log.Error(format, args...)
}

View File

@@ -0,0 +1,36 @@
package dao
import (
"flag"
"os"
"testing"
"go-common/app/interface/main/playlist/conf"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", " main.web-svr.playlist")
flag.Set("conf_token", "050b58400f4204509146d9b0a63e0cec")
flag.Set("tree_id", "6215")
flag.Set("conf_version", "docker-1")
flag.Set("deploy_env", "uat")
flag.Set("conf_host", "config.bilibili.co")
flag.Set("conf_path", "/tmp")
flag.Set("region", "sh")
flag.Set("zone", "sh001")
} else {
flag.Set("conf", "../cmd/playlist-test.toml")
}
flag.Parse()
if err := conf.Init(); err != nil {
panic(err)
}
d = New(conf.Conf)
m.Run()
os.Exit(0)
}

View File

@@ -0,0 +1,55 @@
package dao
import (
"context"
"strconv"
"time"
"go-common/app/interface/main/playlist/model"
pjmdl "go-common/app/job/main/playlist/model"
"go-common/library/log"
"go-common/library/net/metadata"
xtime "go-common/library/time"
)
var _defaultAdd = int64(1)
// PubView adds a view count.
func (d *Dao) PubView(c context.Context, pid, aid, view int64) (err error) {
ip := metadata.String(c, metadata.RemoteIP)
view += _defaultAdd
msg := &pjmdl.StatM{
Type: model.PlDBusType,
ID: pid,
Aid: aid,
IP: ip,
Count: &view,
Timestamp: xtime.Time(time.Now().Unix()),
}
if err = d.viewDbus.Send(c, strconv.FormatInt(pid, 10), msg); err != nil {
PromError("databus:发送浏览量", "d.viewDbus.Send(%+v) error(%v)", msg, err)
return
}
log.Info("s.PubView( pid: %d, aid: %d, ip: %s, view: %d)", msg.ID, msg.Aid, msg.IP, *msg.Count)
return
}
// PubShare adds a share count.
func (d *Dao) PubShare(c context.Context, pid, aid, share int64) (err error) {
ip := metadata.String(c, metadata.RemoteIP)
share += _defaultAdd
msg := &pjmdl.StatM{
Type: model.PlDBusType,
ID: pid,
Aid: aid,
IP: ip,
Count: &share,
Timestamp: xtime.Time(time.Now().Unix()),
}
if err = d.shareDbus.Send(c, strconv.FormatInt(pid, 10), msg); err != nil {
PromError("databus:发送分享数", "d.shareDbus.Send(%+v) error(%v)", msg, err)
return
}
log.Info("s.PubShare( pid: %d, aid: %d, ip: %s, share: %d)", msg.ID, msg.Aid, msg.IP, *msg.Count)
return
}

View File

@@ -0,0 +1,38 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoPubView(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
aid = int64(13825646)
view = int64(1000)
)
convey.Convey("PubView", t, func(ctx convey.C) {
err := d.PubView(c, pid, aid, view)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoPubShare(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
aid = int64(13825646)
share = int64(50)
)
convey.Convey("PubShare", t, func(ctx convey.C) {
err := d.PubShare(c, pid, aid, share)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,267 @@
package dao
import (
"context"
"database/sql"
"fmt"
"strings"
"time"
"go-common/app/interface/main/playlist/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
"go-common/library/xstr"
)
const (
_plArcSub = 100
_plArcSQL = "SELECT aid,sort,`desc` FROM playlist_archive_%s WHERE pid = ? AND aid = ?"
_plArcsSQL = "SELECT aid,sort,`desc` FROM playlist_archive_%s WHERE pid = ? ORDER BY sort"
_plArcAddSQL = "INSERT INTO playlist_archive_%s (pid,aid,sort,`desc`) VALUES (?,?,?,?)"
_plArcBatchAddSQL = "INSERT INTO playlist_archive_%s (pid,aid,sort,`desc`) VALUES %s"
_plArcDelSQL = "DELETE FROM playlist_archive_%s WHERE pid = ? AND aid = ?"
_plArcDelByPidSQL = "DELETE FROM playlist_archive_%s WHERE pid = ?"
_plArcBatchDelSQL = "DELETE FROM playlist_archive_%s WHERE pid = ? AND aid in (%s)"
_plArcDescEditSQL = "UPDATE playlist_archive_%s SET `desc` = ? WHERE pid = ? AND aid = ?"
_plArcSortEditSQL = "UPDATE playlist_archive_%s SET sort = ? WHERE pid = ? AND aid = ?"
_plArcSortBatchEditSQL = "UPDATE playlist_archive_%s SET sort = CASE %s END WHERE pid = ? AND aid IN (%s)"
_plAddSQL = "INSERT INTO playlist_stat (mid,fid,is_deleted,view,reply,fav,share) VALUES (?,?,0,0,0,0,0) ON DUPLICATE KEY UPDATE mid=?,fid=?,is_deleted=0,view=0,reply=0,fav=0,share=0"
_plEditSQL = "UPDATE playlist_stat SET mtime = ? WHERE id = ?"
_plDelSQL = "UPDATE playlist_stat set is_deleted = 1 WHERE id = ?"
_plByMidSQL = "SELECT id,mid,fid,view,reply,fav,`share`,mtime FROM playlist_stat WHERE is_deleted = 0 AND mid = ?"
_plByPidsSQL = "SELECT id,mid,fid,view,reply,fav,`share`,mtime FROM playlist_stat WHERE id in (%s)"
_plByPidSQL = "SELECT id,mid,fid,view,reply,fav,`share`,mtime FROM playlist_stat WHERE id = ?"
)
func plArcHit(pid int64) string {
return fmt.Sprintf("%02d", pid%_plArcSub)
}
// Video get video by pid and aid
func (d *Dao) Video(c context.Context, pid, aid int64) (res *model.ArcSort, err error) {
res = &model.ArcSort{}
row := d.db.QueryRow(c, fmt.Sprintf(_plArcSQL, plArcHit(pid)), pid, aid)
if err = row.Scan(&res.Aid, &res.Sort, &res.Desc); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("Video:row.Scan error(%v)", err)
}
}
return
}
// Videos get playlist videos.
func (d *Dao) Videos(c context.Context, pid int64) (res []*model.ArcSort, err error) {
var rows *xsql.Rows
if rows, err = d.videosStmt[plArcHit(pid)].Query(c, pid); err != nil {
log.Error("d.videosStmt[%s].Query(%d) error(%v)", plArcHit(pid), pid, err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.ArcSort)
if err = rows.Scan(&r.Aid, &r.Sort, &r.Desc); err != nil {
log.Error("row.Scan() error(%v)", err)
return
}
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// AddArc add archive to playlist.
func (d *Dao) AddArc(c context.Context, pid, aid, sort int64, desc string) (lastID int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, fmt.Sprintf(_plArcAddSQL, plArcHit(pid)), pid, aid, desc, sort); err != nil {
log.Error("AddArc: db.Exec(%d,%d,%d,%s) error(%v)", pid, aid, sort, desc, err)
return
}
return res.LastInsertId()
}
// BatchAddArc add archives to playlist.
func (d *Dao) BatchAddArc(c context.Context, pid int64, arcSorts []*model.ArcSort) (lastID int64, err error) {
var (
res sql.Result
values []string
)
for _, v := range arcSorts {
values = append(values, fmt.Sprintf("(%d,%d,%d,'%s')", pid, v.Aid, v.Sort, v.Desc))
}
if res, err = d.db.Exec(c, fmt.Sprintf(_plArcBatchAddSQL, plArcHit(pid), strings.Join(values, ","))); err != nil {
log.Error("BatchAddArc: db.Exec(%d) error(%v)", pid, err)
return
}
return res.LastInsertId()
}
// DelArc delete playlist archive.
func (d *Dao) DelArc(c context.Context, pid, aid int64) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, fmt.Sprintf(_plArcDelSQL, plArcHit(pid)), pid, aid); err != nil {
log.Error("DelArc: db.Exec(%d,%d) error(%v)", pid, aid, err)
return
}
return res.RowsAffected()
}
// BatchDelArc delete archives from playlist.
func (d *Dao) BatchDelArc(c context.Context, pid int64, aids []int64) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, fmt.Sprintf(_plArcBatchDelSQL, plArcHit(pid), xstr.JoinInts(aids)), pid); err != nil {
log.Error("BatchDelArc: db.Exec(%d,%v) error(%v)", pid, aids, err)
return
}
return res.RowsAffected()
}
// UpdateArcDesc update playlist arc desc.
func (d *Dao) UpdateArcDesc(c context.Context, pid, aid int64, desc string) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, fmt.Sprintf(_plArcDescEditSQL, plArcHit(pid)), desc, pid, aid); err != nil {
log.Error("UpdateArcDesc: db.Exec(%d,%d,%s) error(%v)", pid, aid, desc, err)
return
}
return res.RowsAffected()
}
// UpdateArcSort update playlist arc sort.
func (d *Dao) UpdateArcSort(c context.Context, pid, aid, sort int64) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, fmt.Sprintf(_plArcSortEditSQL, plArcHit(pid)), sort, pid, aid); err != nil {
log.Error("UpdateArcSort: db.Exec(%d,%d,%d) error(%v)", pid, aid, sort, err)
return
}
return res.RowsAffected()
}
// BatchUpdateArcSort batch update playlist arc sort.
func (d *Dao) BatchUpdateArcSort(c context.Context, pid int64, arcSorts []*model.ArcSort) (affected int64, err error) {
var (
caseStr string
aids []int64
res sql.Result
)
for _, v := range arcSorts {
caseStr = fmt.Sprintf("%s WHEN aid = %d THEN %d", caseStr, v.Aid, v.Sort)
aids = append(aids, v.Aid)
}
if res, err = d.db.Exec(c, fmt.Sprintf(_plArcSortBatchEditSQL, plArcHit(pid), caseStr, xstr.JoinInts(aids)), pid); err != nil {
log.Error("BatchUpdateArcSort: db.Exec(%d,%s,%v) error(%v)", pid, caseStr, aids, err)
return
}
return res.RowsAffected()
}
//Add playlist stat.
func (d *Dao) Add(c context.Context, mid, fid int64) (lastID int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _plAddSQL, mid, fid, mid, fid); err != nil {
log.Error("Add:db.Exec(%d,%d) error(%v)", mid, fid, err)
return
}
return res.LastInsertId()
}
// Del playlist stat.
func (d *Dao) Del(c context.Context, pid int64) (affected int64, err error) {
var (
res sql.Result
tx *xsql.Tx
)
if tx, err = d.db.Begin(c); err != nil {
log.Error("d.db.Begin error(%v)", err)
return
}
if res, err = tx.Exec(_plDelSQL, pid); err != nil {
tx.Rollback()
log.Error("DelPlaylist: db.Exec(%d) error(%v)", pid, err)
return
}
if _, err = d.db.Exec(c, fmt.Sprintf(_plArcDelByPidSQL, plArcHit(pid)), pid); err != nil {
tx.Rollback()
log.Error("DelArc: db.Exec(%d) error(%v)", pid, err)
return
}
if err = tx.Commit(); err != nil {
log.Error("tx.Commit error(%v)", err)
return
}
return res.RowsAffected()
}
// Update playlist stat.
func (d *Dao) Update(c context.Context, pid int64) (affected int64, err error) {
var res sql.Result
if res, err = d.db.Exec(c, _plEditSQL, time.Now(), pid); err != nil {
log.Error("Update mtime: db.Exec(%d) error(%v)", pid, err)
return
}
return res.RowsAffected()
}
// PlsByMid get playlist by mid.
func (d *Dao) PlsByMid(c context.Context, mid int64) (res []*model.PlStat, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _plByMidSQL, mid); err != nil {
log.Error("PlsByMid:d.db.Query(%d) error(%v)", mid, err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.PlStat)
if err = rows.Scan(&r.ID, &r.Mid, &r.Fid, &r.View, &r.Reply, &r.Fav, &r.Share, &r.MTime); err != nil {
log.Error("PlsByMid:row.Scan() error(%v)", err)
return
}
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// PlsByPid get playlist stat by pids.
func (d *Dao) PlsByPid(c context.Context, pids []int64) (res []*model.PlStat, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, fmt.Sprintf(_plByPidsSQL, xstr.JoinInts(pids))); err != nil {
log.Error("PlsByPid: db.Exec(%s) error(%v)", xstr.JoinInts(pids), err)
return
}
defer rows.Close()
for rows.Next() {
r := new(model.PlStat)
if err = rows.Scan(&r.ID, &r.Mid, &r.Fid, &r.View, &r.Reply, &r.Fav, &r.Share, &r.MTime); err != nil {
log.Error("PlsByPid:row.Scan() error(%v)", err)
return
}
res = append(res, r)
}
if err = rows.Err(); err != nil {
log.Error("rows.Err() error(%v)", err)
}
return
}
// PlByPid get playlist by pid.
func (d *Dao) PlByPid(c context.Context, pid int64) (res *model.PlStat, err error) {
res = &model.PlStat{}
row := d.db.QueryRow(c, _plByPidSQL, pid)
if err = row.Scan(&res.ID, &res.Mid, &res.Fid, &res.View, &res.Reply, &res.Fav, &res.Share, &res.MTime); err != nil {
if err == sql.ErrNoRows {
err = nil
} else {
log.Error("PlByPid:row.Scan error(%v)", err)
}
}
return
}

View File

@@ -0,0 +1,245 @@
package dao
import (
"context"
"testing"
"go-common/app/interface/main/playlist/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoplArcHit(t *testing.T) {
var (
pid = int64(1)
)
convey.Convey("plArcHit", t, func(ctx convey.C) {
p1 := plArcHit(pid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoVideo(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
aid = int64(13825646)
)
convey.Convey("Video", t, func(ctx convey.C) {
res, err := d.Video(c, pid, aid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
}
func TestDaoVideos(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
)
convey.Convey("Videos", t, func(ctx convey.C) {
_, err := d.Videos(c, pid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoAddArc(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
aid = int64(3)
sort = int64(0)
desc = "abc"
)
convey.Convey("AddArc", t, func(ctx convey.C) {
lastID, err := d.AddArc(c, pid, aid, sort, desc)
ctx.Convey("Then err should be nil.lastID should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(lastID, convey.ShouldNotBeNil)
})
})
}
func TestDaoBatchAddArc(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
arcSorts = []*model.ArcSort{}
)
convey.Convey("BatchAddArc", t, func(ctx convey.C) {
arcSorts = append(arcSorts, &model.ArcSort{Aid: 13825646, Desc: "abc", Sort: 100})
lastID, err := d.BatchAddArc(c, pid, arcSorts)
ctx.Convey("Then err should be nil.lastID should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(lastID, convey.ShouldNotBeNil)
})
})
}
func TestDaoDelArc(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
aid = int64(13825646)
)
convey.Convey("DelArc", t, func(ctx convey.C) {
affected, err := d.DelArc(c, pid, aid)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
}
func TestDaoBatchDelArc(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
aids = []int64{13825646, 11, 22, 33}
)
convey.Convey("BatchDelArc", t, func(ctx convey.C) {
affected, err := d.BatchDelArc(c, pid, aids)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
}
func TestDaoUpdateArcDesc(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
aid = int64(13825646)
desc = "abc"
)
convey.Convey("UpdateArcDesc", t, func(ctx convey.C) {
affected, err := d.UpdateArcDesc(c, pid, aid, desc)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
}
func TestDaoUpdateArcSort(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
aid = int64(13825646)
sort = int64(0)
)
convey.Convey("UpdateArcSort", t, func(ctx convey.C) {
affected, err := d.UpdateArcSort(c, pid, aid, sort)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
}
func TestDaoBatchUpdateArcSort(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
arcSorts = []*model.ArcSort{}
)
convey.Convey("BatchUpdateArcSort", t, func(ctx convey.C) {
arcSorts = append(arcSorts, &model.ArcSort{Aid: 1, Desc: "abc"})
affected, err := d.BatchUpdateArcSort(c, pid, arcSorts)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
}
func TestDaoAdd(t *testing.T) {
var (
c = context.Background()
mid = int64(2)
fid = int64(1)
)
convey.Convey("Add", t, func(ctx convey.C) {
lastID, err := d.Add(c, mid, fid)
ctx.Convey("Then err should be nil.lastID should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(lastID, convey.ShouldNotBeNil)
})
})
}
func TestDaoDel(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
)
convey.Convey("Del", t, func(ctx convey.C) {
affected, err := d.Del(c, pid)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
}
func TestDaoUpdate(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
)
convey.Convey("Update", t, func(ctx convey.C) {
affected, err := d.Update(c, pid)
ctx.Convey("Then err should be nil.affected should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(affected, convey.ShouldNotBeNil)
})
})
}
func TestDaoPlsByMid(t *testing.T) {
var (
c = context.Background()
mid = int64(2)
)
convey.Convey("PlsByMid", t, func(ctx convey.C) {
res, err := d.PlsByMid(c, mid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
}
func TestDaoPlsByPid(t *testing.T) {
var (
c = context.Background()
pids = []int64{1, 2, 3}
)
convey.Convey("PlsByPid", t, func(ctx convey.C) {
_, err := d.PlsByPid(c, pids)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoPlByPid(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
)
convey.Convey("PlByPid", t, func(ctx convey.C) {
res, err := d.PlByPid(c, pid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,286 @@
package dao
import (
"context"
"fmt"
"go-common/app/interface/main/playlist/model"
"go-common/library/cache/redis"
"go-common/library/log"
)
const (
_plArcKey = "pla_%d"
_plArcDescKey = "plad_%d"
)
func keyPlArc(pid int64) string {
return fmt.Sprintf(_plArcKey, pid)
}
func keyPlArcDesc(pid int64) string {
return fmt.Sprintf(_plArcDescKey, pid)
}
// ArcsCache get playlist archives cache.
func (d *Dao) ArcsCache(c context.Context, pid int64, start, end int) (arcs []*model.ArcSort, err error) {
var (
plakey = keyPlArc(pid)
pladKey = keyPlArcDesc(pid)
conn = d.redis.Get(c)
aids []int64
descs []string
)
defer conn.Close()
values, err := redis.Values(conn.Do("ZRANGE", plakey, start, end, "WITHSCORES"))
if err != nil {
log.Error("conn.Do(ZREVRANGE, %s) error(%v)", plakey, err)
return
}
if len(values) == 0 {
return
}
arcMap := make(map[int64]*model.ArcSort)
args := redis.Args{}.Add(pladKey)
for len(values) > 0 {
arc := &model.ArcSort{}
if values, err = redis.Scan(values, &arc.Aid, &arc.Sort); err != nil {
log.Error("redis.Scan(%v) error(%v)", values, err)
return
}
arcMap[arc.Aid] = arc
aids = append(aids, arc.Aid)
args = args.Add(arc.Aid)
}
if len(aids) > 0 {
descs, err = redis.Strings(conn.Do("HMGET", args...))
if err != nil {
log.Error("conn.Do(HMGET %v) error(%v)", args, err)
err = nil
}
descLen := len(descs)
for k, aid := range aids {
if arc, ok := arcMap[aid]; ok {
if descLen >= k+1 {
if desc := descs[k]; desc != "" {
arc.Desc = desc
}
}
arcs = append(arcs, arc)
}
}
}
return
}
// AddArcCache add playlist archive cache.
func (d *Dao) AddArcCache(c context.Context, pid int64, arc *model.ArcSort) (err error) {
var (
plakey = keyPlArc(pid)
pladKey = keyPlArcDesc(pid)
conn = d.redis.Get(c)
count int
)
defer conn.Close()
if _, err = redis.Bool(conn.Do("EXPIRE", plakey, d.plExpire)); err != nil {
log.Error("conn.Do(EXPIRE %s) error(%v)", plakey, err)
return
}
if _, err = redis.Bool(conn.Do("EXPIRE", pladKey, d.plExpire)); err != nil {
log.Error("conn.Do(EXPIRE %s) error(%v)", pladKey, err)
return
}
args1 := redis.Args{}.Add(plakey)
args1 = args1.Add(arc.Sort).Add(arc.Aid)
if err = conn.Send("ZADD", args1...); err != nil {
log.Error("conn.Send(ZADD, %s, %v) error(%v)", plakey, args1, err)
return
}
count++
if arc.Desc != "" {
args2 := redis.Args{}.Add(pladKey).Add(arc.Aid).Add(arc.Desc)
if err = conn.Send("HSET", args2...); err != nil {
log.Error("conn.Send(ZADD, %s, %v) error(%v)", plakey, args2, err)
return
}
count++
if err = conn.Send("EXPIRE", pladKey, d.plExpire); err != nil {
log.Error("conn.Send(Expire, %s) error(%v)", pladKey, err)
return
}
count++
}
if err = conn.Send("EXPIRE", plakey, d.plExpire); err != nil {
log.Error("conn.Send(Expire, %s) error(%v)", pladKey, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
for i := 0; i < count; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}
// SetArcsCache set playlist archives cache.
func (d *Dao) SetArcsCache(c context.Context, pid int64, arcs []*model.ArcSort) (err error) {
var (
plaKey = keyPlArc(pid)
pladKey = keyPlArcDesc(pid)
conn = d.redis.Get(c)
addDesc bool
count int
)
defer conn.Close()
if _, err = redis.Bool(conn.Do("EXPIRE", plaKey, d.plExpire)); err != nil {
log.Error("conn.Do(EXPIRE %s) error(%v)", plaKey, err)
return
}
if _, err = redis.Bool(conn.Do("EXPIRE", pladKey, d.plExpire)); err != nil {
log.Error("conn.Do(EXPIRE %s) error(%v)", plaKey, err)
return
}
args1 := redis.Args{}.Add(plaKey)
args2 := redis.Args{}.Add(pladKey)
for _, arc := range arcs {
args1 = args1.Add(arc.Sort).Add(arc.Aid)
if arc.Desc != "" {
addDesc = true
args2 = args2.Add(arc.Aid).Add(arc.Desc)
}
}
if err = conn.Send("ZADD", args1...); err != nil {
log.Error("conn.Send(ZADD, %s, %v) error(%v)", plaKey, args1, err)
return
}
count++
if addDesc {
if err = conn.Send("HMSET", args2...); err != nil {
log.Error("conn.Send(ZADD, %s, %v) error(%v)", pladKey, args2, err)
return
}
count++
}
if err = conn.Send("EXPIRE", pladKey, d.plExpire); err != nil {
log.Error("conn.Send(Expire, %s) error(%v)", pladKey, err)
return
}
count++
if err = conn.Send("EXPIRE", plaKey, d.plExpire); err != nil {
log.Error("conn.Send(Expire, %s) error(%v)", plaKey, err)
return
}
count++
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
for i := 0; i < count; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}
// SetArcDescCache set playlist archive desc cache.
func (d *Dao) SetArcDescCache(c context.Context, pid, aid int64, desc string) (err error) {
var (
key = keyPlArcDesc(pid)
conn = d.redis.Get(c)
)
defer conn.Close()
if _, err = redis.Bool(conn.Do("EXPIRE", key, d.plExpire)); err != nil {
log.Error("conn.Do(EXPIRE %s) error(%v)", key, err)
return
}
if err = conn.Send("HSET", key, aid, desc); err != nil {
log.Error("conn.Send(HSET, %s, %d, %s) error(%v)", key, aid, desc, err)
return
}
if err = conn.Send("EXPIRE", key, d.plExpire); err != nil {
log.Error("conn.Send(Expire, %s) error(%v)", key, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
for i := 0; i < 2; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}
// DelArcsCache delete playlist archives cache.
func (d *Dao) DelArcsCache(c context.Context, pid int64, aids []int64) (err error) {
var (
plaKey = keyPlArc(pid)
pladKey = keyPlArcDesc(pid)
conn = d.redis.Get(c)
)
defer conn.Close()
arg1 := redis.Args{}.Add(plaKey)
arg2 := redis.Args{}.Add(pladKey)
for _, aid := range aids {
arg1 = arg1.Add(aid)
arg2 = arg2.Add(aid)
}
if err = conn.Send("ZREM", arg1...); err != nil {
log.Error("conn.Send(ZREM %s) error(%v)", plaKey, err)
return
}
if err = conn.Send("HDEL", arg2...); err != nil {
log.Error("conn.Send(HDEL %s) error(%v)", pladKey, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush() error(%v)", err)
return
}
for i := 0; i < 2; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}
// DelCache del all cache .
func (d *Dao) DelCache(c context.Context, pid int64) (err error) {
var (
plaKey = keyPlArc(pid)
pladKey = keyPlArcDesc(pid)
conn = d.redis.Get(c)
)
defer conn.Close()
if err = conn.Send("DEL", plaKey); err != nil {
log.Error("conn.Send(DEL plaKey(%s) error(%v))", plaKey, err)
return
}
if err = conn.Send("DEL", pladKey); err != nil {
log.Error("conn.Send(DEL pladKey(%s) error(%v))", pladKey, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush() error(%v)", err)
return
}
for i := 0; i < 2; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}

View File

@@ -0,0 +1,120 @@
package dao
import (
"context"
"testing"
"go-common/app/interface/main/playlist/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaokeyPlArc(t *testing.T) {
var (
pid = int64(1)
)
convey.Convey("keyPlArc", t, func(ctx convey.C) {
p1 := keyPlArc(pid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaokeyPlArcDesc(t *testing.T) {
var (
pid = int64(1)
)
convey.Convey("keyPlArcDesc", t, func(ctx convey.C) {
p1 := keyPlArcDesc(pid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoArcsCache(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
start = int(1)
end = int(20)
)
convey.Convey("ArcsCache", t, func(ctx convey.C) {
_, err := d.ArcsCache(c, pid, start, end)
ctx.Convey("Then err should be nil.arcs should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoAddArcCache(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
arc = &model.ArcSort{Aid: 13825646, Sort: 100, Desc: "abc"}
)
convey.Convey("AddArcCache", t, func(ctx convey.C) {
err := d.AddArcCache(c, pid, arc)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetArcsCache(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
arcs = []*model.ArcSort{}
)
convey.Convey("SetArcsCache", t, func(ctx convey.C) {
arcs = append(arcs, &model.ArcSort{Aid: 13825646, Sort: 100, Desc: "abc"})
err := d.SetArcsCache(c, pid, arcs)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetArcDescCache(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
aid = int64(13825646)
desc = "abc"
)
convey.Convey("SetArcDescCache", t, func(ctx convey.C) {
err := d.SetArcDescCache(c, pid, aid, desc)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoDelArcsCache(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
aids = []int64{13825646, 11, 100}
)
convey.Convey("DelArcsCache", t, func(ctx convey.C) {
err := d.DelArcsCache(c, pid, aids)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoDelCache(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
)
convey.Convey("DelCache", t, func(ctx convey.C) {
err := d.DelCache(c, pid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,36 @@
package dao
import (
"context"
"net/url"
"strconv"
"go-common/library/ecode"
)
const (
_replyType = "18"
_replyState = "0" // 0: open, 1: close
_replyURL = "http://api.bilibili.co/x/internal/v2/reply/subject/regist"
)
// RegReply opens playlist's reply.
func (d *Dao) RegReply(c context.Context, pid, mid int64) (err error) {
params := url.Values{}
params.Set("mid", strconv.FormatInt(mid, 10))
params.Set("oid", strconv.FormatInt(pid, 10))
params.Set("type", _replyType)
params.Set("state", _replyState)
var res struct {
Code int `json:"code"`
}
if err = d.http.Post(c, _replyURL, "", params, &res); err != nil {
PromError("reply:打开评论", "d.http.Post(%s) error(%v)", _replyURL+"?"+params.Encode(), err)
return
}
if res.Code != ecode.OK.Code() {
PromError("reply:打开评论状态码异常", "d.http.Post(%s) error(%v)", _replyURL+"?"+params.Encode(), err)
err = ecode.Int(res.Code)
}
return
}

View File

@@ -0,0 +1,22 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoRegReply(t *testing.T) {
var (
c = context.Background()
pid = int64(1)
mid = int64(2)
)
convey.Convey("RegReply", t, func(ctx convey.C) {
err := d.RegReply(c, pid, mid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}

View File

@@ -0,0 +1,52 @@
package dao
import (
"context"
"go-common/app/interface/main/playlist/model"
"go-common/library/ecode"
"go-common/library/log"
"go-common/library/net/metadata"
"net/url"
"strconv"
)
const (
_searchURL = "/main/search"
_searchVer = "v3"
_platform = "web"
_searchType = "video"
_searchFrom = "web_playlist"
)
// SearchVideo get search video.
func (d *Dao) SearchVideo(c context.Context, pn, ps int, query string) (res []*model.SearchArc, count int, err error) {
var (
params = url.Values{}
ip = metadata.String(c, metadata.RemoteIP)
)
params.Set("main_ver", _searchVer)
params.Set("platform", _platform)
params.Set("search_type", _searchType)
params.Set("from_source", _searchFrom)
params.Set("pagesize", strconv.Itoa(ps))
params.Set("page", strconv.Itoa(pn))
params.Set("keyword", query)
params.Set("clientip", ip)
var rs struct {
Code int `json:"code"`
Result []*model.SearchArc `json:"result"`
NumResults int `json:"numResults"`
}
if err = d.http.Get(c, d.searchURL, ip, params, &rs); err != nil {
log.Error("d.http.Get(%s,%v) error(%v)", d.searchURL, params, err)
return
}
if rs.Code != ecode.OK.Code() {
log.Error("d.http.Get(%s,%v) code error(%v)", d.searchURL, params, rs.Code)
return
}
res = rs.Result
count = rs.NumResults
return
}

View File

@@ -0,0 +1,25 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaoSearchVideo(t *testing.T) {
var (
c = context.Background()
pn = int(1)
ps = int(10)
query = "aaaaa"
)
convey.Convey("SearchVideo", t, func(ctx convey.C) {
res, count, err := d.SearchVideo(c, pn, ps, query)
ctx.Convey("Then err should be nil.res,count should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(count, convey.ShouldNotBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
}

View File

@@ -0,0 +1,304 @@
package dao
import (
"context"
"encoding/json"
"fmt"
"go-common/app/interface/main/playlist/model"
"go-common/library/cache/redis"
"go-common/library/log"
)
const (
_statKey = "st_%d"
_plKey = "pl_%d"
)
func keyStat(mid int64) string {
return fmt.Sprintf(_statKey, mid)
}
func keyPl(pid int64) string {
return fmt.Sprintf(_plKey, pid)
}
// PlStatCache get stat from cache.
func (d *Dao) PlStatCache(c context.Context, mid, pid int64) (stat *model.PlStat, err error) {
var (
bs []byte
key = keyStat(mid)
conn = d.redis.Get(c)
)
defer conn.Close()
if bs, err = redis.Bytes(conn.Do("HGET", key, pid)); err != nil {
if err == redis.ErrNil {
err = nil
stat = nil
} else {
log.Error("conn.Do(HGET,%s,%d) error(%v)", key, pid, err)
}
return
}
stat = new(model.PlStat)
if err = json.Unmarshal(bs, stat); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", string(bs), err)
}
return
}
// SetPlStatCache set playlist stat to cache.
func (d *Dao) SetPlStatCache(c context.Context, mid, pid int64, stat *model.PlStat) (err error) {
var (
bs []byte
ok bool
keyMid = keyStat(mid)
keyPid = keyPl(pid)
conn = d.redis.Get(c)
)
defer conn.Close()
if ok, err = redis.Bool(conn.Do("EXPIRE", keyMid, d.statExpire)); err != nil {
log.Error("conn.Do(EXPIRE %s) error(%v)", keyMid, err)
return
}
if ok {
if bs, err = json.Marshal(stat); err != nil {
log.Error("json.Marshal() error(%v)", err)
return
}
if err = conn.Send("HSET", keyMid, pid, bs); err != nil {
log.Error("conn.Send(HSET,%s,%d) error(%v)", keyMid, pid, err)
return
}
if err = conn.Send("EXPIRE", keyMid, d.statExpire); err != nil {
log.Error("conn.Send(EXPIRE,%s) error(%v)", keyMid, err)
return
}
if err = conn.Send("SET", keyPid, bs); err != nil {
log.Error("conn.Send(SET,%s,%s) error(%v)", keyPid, string(bs), err)
return
}
if err = conn.Send("EXPIRE", keyPid, d.plExpire); err != nil {
log.Error("conn.Send(EXPIRE,%s) error(%v)", keyPid, err)
return
}
if err = conn.Flush(); err != nil {
log.Error("add conn.Flush error(%v)", err)
return
}
for i := 0; i < 4; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("add conn.Receive()%d error(%v)", i+1, err)
return
}
}
}
return
}
// SetStatsCache set playlist stat list to cache.
func (d *Dao) SetStatsCache(c context.Context, mid int64, plStats []*model.PlStat) (err error) {
var (
bs []byte
keyPid string
keyPids []string
argsPid = redis.Args{}
)
keyMid := keyStat(mid)
conn := d.redis.Get(c)
defer conn.Close()
if _, err = redis.Bool(conn.Do("EXPIRE", keyMid, d.statExpire)); err != nil {
log.Error("conn.Do(EXPIRE %s) error(%v)", keyMid, err)
return
}
argsMid := redis.Args{}.Add(keyMid)
for _, v := range plStats {
if bs, err = json.Marshal(v); err != nil {
log.Error("json.Marshal err(%v)", err)
continue
}
argsMid = argsMid.Add(v.ID).Add(string(bs))
keyPid = keyPl(v.ID)
keyPids = append(keyPids, keyPid)
argsPid = argsPid.Add(keyPid).Add(string(bs))
}
if err = conn.Send("HMSET", argsMid...); err != nil {
log.Error("conn.Send(HMSET, %s) error(%v)", keyMid, err)
return
}
if err = conn.Send("EXPIRE", keyMid, d.statExpire); err != nil {
log.Error("conn.Send(Expire, %s, %d) error(%v)", keyMid, d.statExpire, err)
return
}
if err = conn.Send("MSET", argsPid...); err != nil {
log.Error("conn.Send(MSET) error(%v)", err)
return
}
count := 3
for _, v := range keyPids {
count++
if err = conn.Send("EXPIRE", v, d.plExpire); err != nil {
log.Error("conn.Send(Expire, %s, %d) error(%v)", v, d.plExpire, err)
return
}
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
for i := 0; i < count; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}
// PlsCache get playlist by pids from cache.
func (d *Dao) PlsCache(c context.Context, pids []int64) (res []*model.PlStat, err error) {
var (
key string
args = redis.Args{}
)
for _, pid := range pids {
key = keyPl(pid)
args = args.Add(key)
}
conn := d.redis.Get(c)
defer conn.Close()
var (
bss [][]byte
)
if bss, err = redis.ByteSlices(conn.Do("MGET", args...)); err != nil {
if err == redis.ErrNil {
err = nil
} else {
log.Error("PlsCache conn.Do(MGET,%s) error(%v)", key, err)
}
return
}
for _, bs := range bss {
stat := new(model.PlStat)
if bs == nil {
continue
}
if err = json.Unmarshal(bs, stat); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", string(bs), err)
err = nil
continue
}
res = append(res, stat)
}
return
}
// SetPlCache set playlist to cache.
func (d *Dao) SetPlCache(c context.Context, plStats []*model.PlStat) (err error) {
var (
bs []byte
keyPid string
keyPids []string
argsPid = redis.Args{}
)
conn := d.redis.Get(c)
defer conn.Close()
for _, v := range plStats {
if bs, err = json.Marshal(v); err != nil {
log.Error("json.Marshal err(%v)", err)
continue
}
keyPid = keyPl(v.ID)
keyPids = append(keyPids, keyPid)
argsPid = argsPid.Add(keyPid).Add(string(bs))
}
if err = conn.Send("MSET", argsPid...); err != nil {
log.Error("conn.Send(MSET) error(%v)", err)
return
}
count := 1
for _, v := range keyPids {
count++
if err = conn.Send("EXPIRE", v, d.plExpire); err != nil {
log.Error("conn.Send(Expire, %s, %d) error(%v)", v, d.plExpire, err)
return
}
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush error(%v)", err)
return
}
for i := 0; i < count; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}
// DelPlCache delete playlist from redis.
func (d *Dao) DelPlCache(c context.Context, mid, pid int64) (err error) {
var (
key = keyPl(pid)
plaKey = keyPlArc(pid)
pladKey = keyPlArcDesc(pid)
keyStat = keyStat(mid)
conn = d.redis.Get(c)
)
defer conn.Close()
if err = conn.Send("DEL", key); err != nil {
log.Error("conn.Send(DEL %s) error(%v)", key, err)
return
}
if err = conn.Send("DEL", plaKey); err != nil {
log.Error("conn.Send(DEL %s) error(%v)", plaKey, err)
return
}
if err = conn.Send("DEL", pladKey); err != nil {
log.Error("conn.Send(DEL %s) error(%v)", pladKey, err)
return
}
if err = conn.Send("HDEL", keyStat, pid); err != nil {
log.Error("conn.Send(HDEL,%s,%d) error(%v)", keyStat, pid, err)
}
if err = conn.Flush(); err != nil {
log.Error("conn.Flush() error(%v)", err)
return
}
for i := 0; i < 4; i++ {
if _, err = conn.Receive(); err != nil {
log.Error("conn.Receive() error(%v)", err)
return
}
}
return
}
// StatsCache get playlist stats from cache.
func (d *Dao) StatsCache(c context.Context, mid int64) (res []*model.PlStat, err error) {
key := keyStat(mid)
conn := d.redis.Get(c)
defer conn.Close()
var (
bss [][]byte
)
if bss, err = redis.ByteSlices(conn.Do("HGETALL", key)); err != nil {
if err == redis.ErrNil {
err = nil
} else {
log.Error("StatCache conn.Do(HGETALL,%s) error(%v)", key, err)
}
return
}
for i := 1; i <= len(bss); i += 2 {
stat := new(model.PlStat)
if err = json.Unmarshal(bss[i], stat); err != nil {
log.Error("json.Unmarshal(%s) error(%v)", string(bss[i]), err)
continue
}
res = append(res, stat)
}
return
}

View File

@@ -0,0 +1,133 @@
package dao
import (
"context"
"testing"
"go-common/app/interface/main/playlist/model"
"github.com/smartystreets/goconvey/convey"
)
func TestDaokeyStat(t *testing.T) {
var (
mid = int64(2)
)
convey.Convey("keyStat", t, func(ctx convey.C) {
p1 := keyStat(mid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaokeyPl(t *testing.T) {
var (
pid = int64(1)
)
convey.Convey("keyPl", t, func(ctx convey.C) {
p1 := keyPl(pid)
ctx.Convey("Then p1 should not be nil.", func(ctx convey.C) {
ctx.So(p1, convey.ShouldNotBeNil)
})
})
}
func TestDaoPlStatCache(t *testing.T) {
var (
c = context.Background()
mid = int64(2)
pid = int64(1)
)
convey.Convey("PlStatCache", t, func(ctx convey.C) {
_, err := d.PlStatCache(c, mid, pid)
ctx.Convey("Then err should be nil.stat should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetPlStatCache(t *testing.T) {
var (
c = context.Background()
mid = int64(2)
pid = int64(1)
stat = &model.PlStat{}
)
convey.Convey("SetPlStatCache", t, func(ctx convey.C) {
err := d.SetPlStatCache(c, mid, pid, stat)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoSetStatsCache(t *testing.T) {
var (
c = context.Background()
mid = int64(2)
plStats = []*model.PlStat{}
)
plStats = append(plStats, &model.PlStat{ID: 1, Share: 1})
convey.Convey("SetStatsCache", t, func(ctx convey.C) {
err := d.SetStatsCache(c, mid, plStats)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoPlsCache(t *testing.T) {
var (
c = context.Background()
pids = []int64{1, 2, 3}
)
convey.Convey("PlsCache", t, func(ctx convey.C) {
res, err := d.PlsCache(c, pids)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(res, convey.ShouldNotBeNil)
})
})
}
func TestDaoSetPlCache(t *testing.T) {
var (
c = context.Background()
plStats = []*model.PlStat{}
)
plStats = append(plStats, &model.PlStat{ID: 1, View: 100})
convey.Convey("SetPlCache", t, func(ctx convey.C) {
err := d.SetPlCache(c, plStats)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoDelPlCache(t *testing.T) {
var (
c = context.Background()
mid = int64(2)
pid = int64(1)
)
convey.Convey("DelPlCache", t, func(ctx convey.C) {
err := d.DelPlCache(c, mid, pid)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}
func TestDaoStatsCache(t *testing.T) {
var (
c = context.Background()
mid = int64(2)
)
convey.Convey("StatsCache", t, func(ctx convey.C) {
_, err := d.StatsCache(c, mid)
ctx.Convey("Then err should be nil.res should not be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
}