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,61 @@
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",
"mysql_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/interface/main/playlist/model:go_default_library",
"//app/job/main/playlist/conf:go_default_library",
"//app/job/main/playlist/model:go_default_library",
"//library/time:go_default_library",
"//vendor/github.com/smartystreets/goconvey/convey:go_default_library",
],
)
go_library(
name = "go_default_library",
srcs = [
"dao.go",
"mysql.go",
"redis.go",
],
importpath = "go-common/app/job/main/playlist/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/interface/main/playlist/model:go_default_library",
"//app/job/main/playlist/conf:go_default_library",
"//app/job/main/playlist/model:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//library/net/http/blademaster:go_default_library",
"//library/stat/prom: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,61 @@
package dao
import (
"context"
"time"
"go-common/app/job/main/playlist/conf"
"go-common/library/cache/redis"
xsql "go-common/library/database/sql"
"go-common/library/log"
bm "go-common/library/net/http/blademaster"
"go-common/library/stat/prom"
)
// Dao .
type Dao struct {
c *conf.Config
db *xsql.DB
redis *redis.Pool
httpClient *bm.Client
viewCacheTTL int64
}
// New creates a dao instance.
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: xsql.NewMySQL(c.Mysql),
redis: redis.NewPool(c.Redis),
httpClient: bm.NewClient(c.HTTPClient),
viewCacheTTL: int64(time.Duration(c.Job.ViewCacheTTL) / time.Second),
}
return
}
// PromError stat and log.
func PromError(name string, format string, args ...interface{}) {
prom.BusinessErrCount.Incr(name)
log.Error(format, args...)
}
// PromInfo prometheus info count.
func PromInfo(name string) {
prom.BusinessInfoCount.Incr(name)
}
// Ping reports the health of the db/cache etc.
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
}

View File

@@ -0,0 +1,22 @@
package dao
import (
"flag"
"path/filepath"
"go-common/app/job/main/playlist/conf"
)
var d *Dao
func WithDao(f func(d *Dao)) func() {
return func() {
dir, _ := filepath.Abs("../cmd/playlist-job-test.toml")
flag.Set("conf", dir)
conf.Init()
if d == nil {
d = New(conf.Conf)
}
f(d)
}
}

View File

@@ -0,0 +1,48 @@
package dao
import (
"context"
plmdl "go-common/app/interface/main/playlist/model"
"go-common/app/job/main/playlist/model"
)
const (
_statSQL = "SELECT id,mid,fid,view,reply,fav,share,mtime FROM `playlist_stat` WHERE id = ?"
_upViewSQL = "UPDATE playlist_stat SET view= ?, mtime=mtime WHERE id = ?"
_upFavSQL = "UPDATE playlist_stat SET fav= ?, mtime=mtime WHERE id = ?"
_upReplySQL = "UPDATE playlist_stat SET reply= ?, mtime=mtime WHERE id = ?"
_upShareSQL = "UPDATE playlist_stat SET share= ?, mtime=mtime WHERE id = ?"
)
// Update updates stat in db.
func (d *Dao) Update(c context.Context, stat *model.StatM, tp string) (rows int64, err error) {
var tmpSQL string
switch tp {
case model.ViewCountType:
tmpSQL = _upViewSQL
case model.FavCountType:
tmpSQL = _upFavSQL
case model.ReplyCountType:
tmpSQL = _upReplySQL
case model.ShareCountType:
tmpSQL = _upShareSQL
}
res, err := d.db.Exec(c, tmpSQL, *stat.Count, stat.ID)
if err != nil {
PromError("db:更新计数", tp+" Update(%d,%+v) error(%v)", stat.ID, stat, err)
return
}
rows, err = res.RowsAffected()
return
}
// Stat returns stat info.
func (d *Dao) Stat(c context.Context, pid int64) (stat *plmdl.PlStat, err error) {
row := d.db.QueryRow(c, _statSQL, pid)
stat = &plmdl.PlStat{}
if err = row.Scan(&stat.ID, &stat.Mid, &stat.Fid, &stat.View, &stat.Reply, &stat.Fav, &stat.Share, &stat.MTime); err != nil {
PromError("db:读取计数", "Stat(%v) error(%v)", pid, err)
}
return
}

View File

@@ -0,0 +1,36 @@
package dao
import (
"context"
"testing"
"time"
plmdl "go-common/app/interface/main/playlist/model"
"go-common/app/job/main/playlist/model"
xtime "go-common/library/time"
. "github.com/smartystreets/goconvey/convey"
)
func TestDao_Stat(t *testing.T) {
Convey("test stat", t, WithDao(func(d *Dao) {
pid := int64(41)
res, err := d.Stat(context.TODO(), pid)
So(err, ShouldBeNil)
Printf("%+v", res)
}))
}
func TestDao_Update(t *testing.T) {
Convey("test update", t, WithDao(func(d *Dao) {
var (
pid int64 = 1
aid int64 = 1
view int64 = 2
)
arg := &model.StatM{Type: plmdl.PlDBusType, ID: pid, Aid: aid, Count: &view, Timestamp: xtime.Time(time.Now().Unix()), IP: ""}
res, err := d.Update(context.TODO(), arg, model.ViewCountType)
So(err, ShouldBeNil)
So(res, ShouldNotBeEmpty)
}))
}

View File

@@ -0,0 +1,62 @@
package dao
import (
"context"
"fmt"
"go-common/library/cache/redis"
)
const (
// view
_viewPrefix = "v_%d_%d_%s"
)
func viewKey(pid, aid int64, ip string) (key string) {
if ip == "" {
// let it pass if ip is empty.
return
}
return fmt.Sprintf(_viewPrefix, pid, aid, ip)
}
// Intercept intercepts illegal views.
func (d *Dao) Intercept(c context.Context, pid, aid int64, ip string) (ban bool) {
var (
err error
exist bool
key = viewKey(pid, aid, ip)
conn = d.redis.Get(c)
)
defer conn.Close()
if key == "" {
return
}
if exist, err = redis.Bool(conn.Do("EXISTS", key)); err != nil {
PromError("redis:EXISTS播放数", "conn.Do(EXISTS, %s) error(%v)", key, err)
return
}
if exist {
ban = true
return
}
if err = conn.Send("SET", key, ""); err != nil {
PromError("redis:SET播放数", "conn.Send(EXPIRE, %s) error(%v)", key, err)
return
}
if err = conn.Send("EXPIRE", key, d.viewCacheTTL); err != nil {
PromError("redis:EXPIRE播放数", "conn.Send(EXPIRE, %s) error(%v)", key, err)
return
}
if err = conn.Flush(); err != nil {
PromError("redis:播放数缓存Flush", "conn.Flush error(%v)", err)
return
}
for i := 0; i < 2; i++ {
if _, err = conn.Receive(); err != nil {
PromError("redis:播放数缓存Receive", "conn.Receive() error(%v)", err)
return
}
}
return
}