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,58 @@
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",
"redis_test.go",
],
embed = [":go_default_library"],
rundir = ".",
tags = ["automanaged"],
deps = [
"//app/service/main/figure/conf:go_default_library",
"//app/service/main/figure/model: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/service/main/figure/dao",
tags = ["automanaged"],
visibility = ["//visibility:public"],
deps = [
"//app/service/main/figure/conf:go_default_library",
"//app/service/main/figure/model:go_default_library",
"//library/cache/redis:go_default_library",
"//library/database/sql:go_default_library",
"//library/log:go_default_library",
"//vendor/github.com/pkg/errors: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,44 @@
package dao
import (
"context"
"time"
"go-common/app/service/main/figure/conf"
"go-common/library/cache/redis"
"go-common/library/database/sql"
)
// Dao figure DAO
type Dao struct {
c *conf.Config
db *sql.DB
redis *redis.Pool
redisExpire int32
}
// New new a figure DAO
func New(c *conf.Config) (d *Dao) {
d = &Dao{
c: c,
db: sql.NewMySQL(c.Mysql),
redis: redis.NewPool(c.Redis.Config),
redisExpire: int32(time.Duration(c.Redis.Expire) / time.Second),
}
return
}
// Ping check service health
func (d *Dao) Ping(c context.Context) (err error) {
if err = d.PingRedis(c); err != nil {
return
}
return d.db.Ping(c)
}
// Close close all dao.
func (d *Dao) Close() {
if d.db != nil {
d.db.Close()
}
}

View File

@@ -0,0 +1,36 @@
package dao
import (
"flag"
"os"
"testing"
"go-common/app/service/main/figure/conf"
)
var (
d *Dao
)
func TestMain(m *testing.M) {
if os.Getenv("DEPLOY_ENV") != "" {
flag.Set("app_id", "main.account-law.figure-service")
flag.Set("conf_token", "9b960afb4badef680ae468698b4efd1a")
flag.Set("tree_id", "5632")
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/figure-service-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,57 @@
package dao
import (
"context"
"fmt"
"go-common/app/service/main/figure/model"
xsql "go-common/library/database/sql"
"github.com/pkg/errors"
)
const (
_shard = 100
_figureInfo = "SELECT id, mid, score, lawful_score, wide_score, friendly_score, bounty_score, creativity_score, ver, ctime, mtime FROM figure_user_%02d WHERE mid=? ORDER BY id DESC LIMIT 1"
_rank = `SELECT score_from,score_to,percentage FROM figure_rank ORDER BY percentage ASC`
)
func hit(mid int64) int64 {
return mid % _shard
}
// FigureInfo get user figure info
func (d *Dao) FigureInfo(c context.Context, mid int64) (res *model.Figure, err error) {
row := d.db.QueryRow(c, fmt.Sprintf(_figureInfo, hit(mid)), mid)
res = &model.Figure{}
if err = row.Scan(&res.ID, &res.Mid, &res.Score, &res.LawfulScore, &res.WideScore, &res.FriendlyScore, &res.BountyScore, &res.CreativityScore, &res.Ver, &res.Ctime, &res.Mtime); err != nil {
if err == xsql.ErrNoRows {
err = nil
res = nil
return
}
err = errors.WithStack(err)
}
return
}
// Ranks get figure score rank by ver
func (d *Dao) Ranks(c context.Context) (ranks []*model.Rank, err error) {
var (
rows *xsql.Rows
)
if rows, err = d.db.Query(c, _rank); err != nil {
return
}
defer rows.Close()
for rows.Next() {
var rank = &model.Rank{}
if err = rows.Scan(&rank.ScoreFrom, &rank.ScoreTo, &rank.Percentage); err != nil {
ranks = nil
return
}
ranks = append(ranks, rank)
}
err = rows.Err()
return
}

View File

@@ -0,0 +1,53 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
)
func TestDaohit(t *testing.T) {
convey.Convey("hit", t, func(ctx convey.C) {
var (
mid = int64(46333)
)
ctx.Convey("When everything right.", func(ctx convey.C) {
shard := hit(mid)
ctx.Convey("Then shard should not be mid % 100.", func(ctx convey.C) {
ctx.So(shard, convey.ShouldEqual, 33)
})
})
})
}
func TestDaoFigureInfo(t *testing.T) {
convey.Convey("FigureInfo", t, func(ctx convey.C) {
var (
c = context.Background()
mid = int64(20606508)
)
ctx.Convey("When everything right.", func(ctx convey.C) {
res, err := d.FigureInfo(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 TestDaoRanks(t *testing.T) {
convey.Convey("Ranks", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything right.", func(ctx convey.C) {
ranks, err := d.Ranks(c)
ctx.Convey("Then err should be nil.ranks should have length 100.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(ranks, convey.ShouldHaveLength, 100)
})
})
})
}

View File

@@ -0,0 +1,112 @@
package dao
import (
"context"
"encoding/json"
"fmt"
"go-common/app/service/main/figure/model"
"go-common/library/cache/redis"
"go-common/library/log"
"github.com/pkg/errors"
)
const (
_figureKey = "f:%d"
)
func figureKey(mid int64) string {
return fmt.Sprintf(_figureKey, mid)
}
// PingRedis check redis connection
func (d *Dao) PingRedis(c context.Context) (err error) {
conn := d.redis.Get(c)
defer conn.Close()
if _, err = conn.Do("SET", "PING", "PONG"); err != nil {
err = errors.WithStack(err)
}
return
}
// AddFigureInfoCache put figure to redis
func (d *Dao) AddFigureInfoCache(c context.Context, f *model.Figure) (err error) {
var (
key = figureKey(f.Mid)
conn = d.redis.Get(c)
values []byte
)
defer conn.Close()
if values, err = json.Marshal(f); err != nil {
err = errors.Wrapf(err, "%+v", f)
return
}
if err = conn.Send("SET", key, values); err != nil {
err = errors.Wrapf(err, "conn.Send(SET, %s, %d)", key, values)
return
}
if err = conn.Send("EXPIRE", key, d.redisExpire); err != nil {
err = errors.Wrapf(err, "conn.Send(Expire, %s, %d)", key, d.redisExpire)
return
}
return
}
// FigureInfoCache get user figure info from redis
func (d *Dao) FigureInfoCache(c context.Context, mid int64) (f *model.Figure, err error) {
key := figureKey(mid)
conn := d.redis.Get(c)
defer conn.Close()
item, err := redis.Bytes(conn.Do("GET", key))
if err != nil {
if err == redis.ErrNil {
err = nil
}
return
}
if err = json.Unmarshal(item, &f); err != nil {
log.Error("json.Unmarshal(%v) err(%v)", item, err)
}
return
}
// FigureBatchInfoCache ...
func (d *Dao) FigureBatchInfoCache(c context.Context, mids []int64) (fs []*model.Figure, missIndex []int, err error) {
if len(mids) == 0 {
return
}
fs = make([]*model.Figure, len(mids))
var (
conn = d.redis.Get(c)
valueBytes [][]byte
keys []interface{}
)
defer conn.Close()
for _, mid := range mids {
keys = append(keys, figureKey(mid))
}
if valueBytes, err = redis.ByteSlices(conn.Do("MGET", keys...)); err != nil {
if err == redis.ErrNil {
err = nil
return
}
err = errors.WithStack(err)
return
}
for i, value := range valueBytes {
if value == nil {
missIndex = append(missIndex, i)
continue
}
f := &model.Figure{}
if err = json.Unmarshal(value, &f); err != nil {
log.Error("%+v", errors.Wrapf(err, "json.Unmarshal(%s)", value))
err = nil
missIndex = append(missIndex, i)
continue
}
fs[i] = f
}
return
}

View File

@@ -0,0 +1,77 @@
package dao
import (
"context"
"testing"
"github.com/smartystreets/goconvey/convey"
"go-common/app/service/main/figure/model"
)
func TestDaofigureKey(t *testing.T) {
convey.Convey("figureKey", t, func(ctx convey.C) {
var (
mid = int64(46333)
)
ctx.Convey("When everything right.", func(ctx convey.C) {
key := figureKey(mid)
ctx.Convey("Then key should equal f:key.", func(ctx convey.C) {
ctx.So(key, convey.ShouldEqual, "f:46333")
})
})
})
}
func TestDaoPingRedis(t *testing.T) {
convey.Convey("PingRedis", t, func(ctx convey.C) {
var (
c = context.Background()
)
ctx.Convey("When everything right.", func(ctx convey.C) {
err := d.PingRedis(c)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
})
})
})
}
func TestDaoAddFigureInfoCache(t *testing.T) {
convey.Convey("AddFigureInfoCache", t, func(ctx convey.C) {
var (
c = context.Background()
figure = &model.Figure{
Mid: 46333,
Score: 2333,
LawfulScore: 123,
WideScore: 321,
FriendlyScore: 19999,
BountyScore: 1,
CreativityScore: 0,
Ver: 2333,
}
)
ctx.Convey("When add FigureInfoCache.", func(ctx convey.C) {
err := d.AddFigureInfoCache(c, figure)
ctx.Convey("Then err should be nil.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.Convey("When get FigureInfoCache.", func(ctx convey.C) {
figure2, err := d.FigureInfoCache(c, figure.Mid)
ctx.Convey("Then err should be nil.figure2 should resemble figure.", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(figure2, convey.ShouldResemble, figure)
})
})
ctx.Convey("When get FigureBatchInfoCache.", func(ctx convey.C) {
figures, missIndex, err := d.FigureBatchInfoCache(c, []int64{figure.Mid})
ctx.Convey("Then err should be nil.missIndex should be empty.figures should have length 1.figuers[0] should resemble figure", func(ctx convey.C) {
ctx.So(err, convey.ShouldBeNil)
ctx.So(missIndex, convey.ShouldBeEmpty)
ctx.So(figures, convey.ShouldHaveLength, 1)
ctx.So(figures[0], convey.ShouldResemble, figure)
})
})
})
})
})
}