go-common/app/interface/openplatform/article/dao/mysql_article.go
2019-04-22 18:49:16 +08:00

305 lines
8.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package dao
import (
"context"
"database/sql"
"fmt"
"strconv"
"strings"
"sync"
"time"
artmdl "go-common/app/interface/openplatform/article/model"
xsql "go-common/library/database/sql"
"go-common/library/log"
xtime "go-common/library/time"
"go-common/library/xstr"
"go-common/library/sync/errgroup"
)
// Article gets article's meta and content.
func (d *Dao) Article(c context.Context, aid int64) (res *artmdl.Article, err error) {
res = &artmdl.Article{}
if res.Meta, err = d.ArticleMeta(c, aid); err != nil {
PromError("article:获取文章meta")
return
}
if res.Meta == nil {
res = nil
return
}
if res.Content, err = d.ArticleContent(c, aid); err != nil {
PromError("article:获取文章content")
}
if res.Keywords, err = d.ArticleKeywords(c, aid); err != nil {
PromError("article:获取文章keywords")
}
res.Strong()
return
}
// ArticleContent get article content
func (d *Dao) ArticleContent(c context.Context, id int64) (res string, err error) {
contentSQL := fmt.Sprintf(_articleContentSQL, d.hit(id))
if err = d.articleDB.QueryRow(c, contentSQL, id).Scan(&res); err != nil {
if err == sql.ErrNoRows {
err = nil
return
}
PromError("db:ArticleContent")
log.Error("dao.ArticleContent(%s) error(%+v)", contentSQL, err)
}
return
}
// ArticleKeywords get article keywords
func (d *Dao) ArticleKeywords(c context.Context, id int64) (res string, err error) {
keywordsSQL := fmt.Sprintf(_articleKeywordsSQL, d.hit(id))
if err = d.articleDB.QueryRow(c, keywordsSQL, id).Scan(&res); err != nil {
if err == sql.ErrNoRows {
err = nil
return
}
PromError("db:ArticleKeywords")
log.Error("dao.ArticleKeywords(%s) error(%+v)", keywordsSQL, err)
}
res = strings.Replace(res, "\001", ",", -1)
return
}
// ArticleMeta get article meta
func (d *Dao) ArticleMeta(c context.Context, id int64) (res *artmdl.Meta, err error) {
var (
row *xsql.Row
imageURLs, originImageURLs string
category = &artmdl.Category{}
author = &artmdl.Author{}
t int64
ct time.Time
)
res = &artmdl.Meta{Media: &artmdl.Media{}}
row = d.articleMetaStmt.QueryRow(c, id)
if err = row.Scan(&res.ID, &category.ID, &res.Title, &res.Summary, &res.BannerURL, &res.TemplateID, &res.State, &author.Mid, &res.Reprint, &imageURLs, &t, &ct, &res.Attributes, &res.Words, &res.Dynamic, &originImageURLs, &res.Media.MediaID, &res.Media.Spoiler); err != nil {
if err == sql.ErrNoRows {
res = nil
err = nil
return
}
PromError("db:ArticleMeta")
log.Error("dao.ArticleMeta.Scan error(%+v)", err)
return
}
res.PublishTime = xtime.Time(t)
res.Category = category
res.Author = author
res.Ctime = xtime.Time(ct.Unix())
res.ImageURLs = strings.Split(imageURLs, ",")
res.OriginImageURLs = strings.Split(originImageURLs, ",")
res.BannerURL = artmdl.CompleteURL(res.BannerURL)
res.ImageURLs = artmdl.CompleteURLs(res.ImageURLs)
res.OriginImageURLs = artmdl.CompleteURLs(res.OriginImageURLs)
res.Strong()
return
}
// ArticleMetas get article metats
func (d *Dao) ArticleMetas(c context.Context, aids []int64) (res map[int64]*artmdl.Meta, err error) {
var (
group, errCtx = errgroup.WithContext(c)
mutex = &sync.Mutex{}
)
if len(aids) == 0 {
return
}
res = make(map[int64]*artmdl.Meta)
keysLen := len(aids)
for i := 0; i < keysLen; i += _mysqlBulkSize {
var keys []int64
if (i + _mysqlBulkSize) > keysLen {
keys = aids[i:]
} else {
keys = aids[i : i+_mysqlBulkSize]
}
group.Go(func() (err error) {
var rows *xsql.Rows
metasSQL := fmt.Sprintf(_articlesMetaSQL, xstr.JoinInts(keys))
if rows, err = d.articleDB.Query(errCtx, metasSQL); err != nil {
PromError("db:ArticleMetas")
return
}
defer rows.Close()
for rows.Next() {
var (
imageURLs, originImageURLs string
t int64
ct time.Time
a = &artmdl.Meta{Category: &artmdl.Category{}, Author: &artmdl.Author{}, Media: &artmdl.Media{}}
)
err = rows.Scan(&a.ID, &a.Category.ID, &a.Title, &a.Summary, &a.BannerURL, &a.TemplateID, &a.State, &a.Author.Mid, &a.Reprint, &imageURLs, &t, &ct, &a.Attributes, &a.Words, &a.Dynamic, &originImageURLs, &a.Media.MediaID, &a.Media.Spoiler)
if err != nil {
return
}
a.ImageURLs = strings.Split(imageURLs, ",")
a.OriginImageURLs = strings.Split(originImageURLs, ",")
a.PublishTime = xtime.Time(t)
a.Ctime = xtime.Time(ct.Unix())
a.BannerURL = artmdl.CompleteURL(a.BannerURL)
a.ImageURLs = artmdl.CompleteURLs(a.ImageURLs)
a.OriginImageURLs = artmdl.CompleteURLs(a.OriginImageURLs)
a.Strong()
mutex.Lock()
res[a.ID] = a
mutex.Unlock()
}
err = rows.Err()
return err
})
}
if err = group.Wait(); err != nil {
PromError("db:ArticleMetas")
log.Error("dao.ArticleMetas error(%+v)", err)
return
}
if len(res) == 0 {
res = nil
}
return
}
// AllArticleMeta 所有状态/删除 的文章
func (d *Dao) AllArticleMeta(c context.Context, id int64) (res *artmdl.Meta, err error) {
var (
row *xsql.Row
imageURLs, originImageURLs string
category = &artmdl.Category{}
author = &artmdl.Author{}
t int64
ct time.Time
)
res = &artmdl.Meta{Media: &artmdl.Media{}}
row = d.allArticleMetaStmt.QueryRow(c, id)
if err = row.Scan(&res.ID, &category.ID, &res.Title, &res.Summary, &res.BannerURL, &res.TemplateID, &res.State, &author.Mid, &res.Reprint, &imageURLs, &t, &ct, &res.Attributes, &res.Words, &res.Dynamic, &originImageURLs, &res.Media.MediaID, &res.Media.Spoiler); err != nil {
if err == sql.ErrNoRows {
res = nil
err = nil
return
}
PromError("db:AllArticleMeta")
log.Error("row.AllArticleMeta.Scan error(%+v)", err)
return
}
res.PublishTime = xtime.Time(t)
res.Category = category
res.Author = author
res.Ctime = xtime.Time(ct.Unix())
res.ImageURLs = strings.Split(imageURLs, ",")
res.OriginImageURLs = strings.Split(originImageURLs, ",")
res.BannerURL = artmdl.CompleteURL(res.BannerURL)
res.ImageURLs = artmdl.CompleteURLs(res.ImageURLs)
res.OriginImageURLs = artmdl.CompleteURLs(res.OriginImageURLs)
res.Strong()
return
}
// UpperArticleCount get upper article count
func (d *Dao) UpperArticleCount(c context.Context, mid int64) (res int, err error) {
row := d.articleUpperCountStmt.QueryRow(c, mid)
if err = row.Scan(&res); err != nil {
if err == sql.ErrNoRows {
err = nil
return
}
PromError("db:UpperArticleCount")
log.Error("dao.UpperArticleCount error(%+v)", err)
}
return
}
// ArticleRemainCount returns the number that user could be use to posting new articles.
func (d *Dao) ArticleRemainCount(c context.Context, mid int64) (count int, err error) {
beginTime := time.Now().Format("2006-01-02") + " 00:00:00"
if err = d.articleUpCntTodayStmt.QueryRow(c, mid, beginTime).Scan(&count); err != nil {
if err == sql.ErrNoRows {
err = nil
return
}
PromError("db:ArticleRemainCount")
log.Error("dao.ArticleRemainCount(%d,%s) error(%+v)", mid, beginTime, err)
}
return
}
// TagArticles .
func (d *Dao) TagArticles(c context.Context, tags []int64) (aids []int64, err error) {
var (
rows *xsql.Rows
query string
tmps = make(map[int64]bool)
)
query = fmt.Sprintf(_tagArticlesSQL, xstr.JoinInts(tags))
if rows, err = d.articleDB.Query(c, query); err != nil {
PromError("dao:TagArticles")
log.Error("dao.TagArticles(%s) error(%+v)", query, err)
return
}
defer rows.Close()
for rows.Next() {
var (
tid int64
oid string
logDate xtime.Time
ts []int64
aid int64
now = time.Now()
)
rows.Scan(&tid, &oid, &logDate)
if now.Sub(logDate.Time()) > time.Hour*60 {
continue
}
ids := strings.Split(oid, "")
for _, id := range ids {
if aid, err = strconv.ParseInt(id, 10, 64); err != nil {
log.Error("dao.TagArticles.ParseInt(%s) error(%+v)", id, err)
return
}
if !tmps[aid] {
aids = append(aids, aid)
tmps[aid] = true
}
ts = append(ts, aid)
}
d.AddCacheAidsByTag(c, tid, &artmdl.TagArts{Tid: tid, Aids: ts})
}
return
}
// MediaArticle .
func (d *Dao) MediaArticle(c context.Context, mediaID int64, mid int64) (id int64, err error) {
var rows *xsql.Rows
if rows, err = d.articleDB.Query(c, _mediaArticleSQL, mid, mediaID); err != nil {
log.Error("dao.MediaArticle.Query error(%v)", err)
return
}
defer rows.Close()
for rows.Next() {
if err = rows.Scan(&id); err != nil {
log.Error("dao.MediaArticle.Scan error(%v)", err)
return
}
if id > 0 {
return
}
}
return
}
// MediaIDByID .
func (d *Dao) MediaIDByID(c context.Context, aid int64) (id int64, err error) {
row := d.articleDB.QueryRow(c, _mediaByIDSQL, aid)
if err = row.Scan(&id); err != nil {
log.Error("dao.MediaIDByID.Scan error(%v)", err)
}
return
}