func IncrLikeCount(articleId int64, userId int64) (int, error) {
	db := db.NewDB()
	err := db.Begin()

	hasLiked, err := HasLikeArticle(articleId, userId, db)
	if nil != err {
		db.Rollback()
		return 0, err
	}

	article, err := ArticleById(articleId)

	articleOwnerId := article.UserId
	if err != nil {
		db.Rollback()
		return 0, err
	}

	if articleOwnerId <= 0 {
		db.Rollback()
		return 0, errors.New(exception.NOT_EXIST_ARTICLE_ERROR.Error())
	}

	var sql = "update article set like_count=like_count+? where user_id = ? and id = ? "
	var incrCount, valid int = 1, 1
	if hasLiked {
		incrCount = -1
		valid = 0
	}
	_, err = db.Execute(sql, []interface{}{incrCount, articleOwnerId, articleId})
	if nil == err {
		var articleLike = entities.ArticleLike{UserId: userId, ArticleId: articleId, Valid: valid, CreatedAt: time.Now()}
		err = SaveOrUpdate(articleLike, db)
	}

	if nil == err {
		sql = "update user set like_count=like_count+1  where id = ? "
		_, err = db.Execute(sql, []interface{}{articleOwnerId})
	}

	if nil == err {
		err = db.Commit()
	} else {
		incrCount = 0
		err = db.Rollback()
	}

	return incrCount, err
}
func UpdateArticle(article *entities.Article) error {

	var err error
	db := db.NewDB()
	db.Begin()

	sql := "update article set title = ? ,tags=?,categories=?, content=?, updated_at=now() where user_id = ? and  id = ? "

	_, err = db.Raw(sql, []interface{}{article.Title, article.Tags, article.Categories, article.Content, article.UserId, article.Id}).Exec()

	if nil == err {
		var categories []entities.Category
		if len(article.Categories) > 0 {
			categoryNames := strings.Split(article.Categories, ",")
			categories = entities.NewCategories(article.UserId, categoryNames)
		}
		BatchSaveOrUpdateCategory(db, categories)
	}

	if nil == err {
		db.Commit()
	} else {
		db.Rollback()
	}

	return err
}
func SaveArticle(article *entities.Article) error {

	var err error
	db := db.NewDB()
	db.Begin()

	bBuffer := bytes.NewBufferString("insert into article (user_id,title, tags,categories, content, created_at) ")
	bBuffer.WriteString("values(?,?,?,?,?,now())")

	_, err = db.Raw(bBuffer.String(), []interface{}{article.UserId, article.Title, article.Tags, article.Categories, article.Content}).Exec()

	if nil == err {
		var categories []entities.Category
		if len(article.Categories) > 0 {
			categoryNames := strings.Split(article.Categories, ",")
			categories = entities.NewCategories(article.UserId, categoryNames)
		}
		BatchSaveOrUpdateCategory(db, categories)
	}

	if nil == err {
		db.Commit()
	} else {
		db.Rollback()
	}

	return err
}
func IncrViewCount(articleId int64, userId int64, ip string) (bool, error) {

	db := db.NewDB()
	err := db.Begin()

	hasViewed, err := HasViewArticle(articleId, userId, ip, db)
	if nil != err || hasViewed {
		db.Rollback()
		return false, err
	}
	article, err := ArticleById(articleId)

	articleOwnerId := article.UserId
	if err != nil {
		db.Rollback()
		return false, err
	}

	if articleOwnerId <= 0 {
		db.Rollback()
		return false, errors.New(exception.NOT_EXIST_ARTICLE_ERROR.Error())
	}

	var sql = "update article set view_count=view_count+1  where user_id = ? and id = ? "

	_, err = db.Execute(sql, []interface{}{articleOwnerId, articleId})
	if nil == err {
		var articleView = entities.ArticleView{UserId: userId, ArticleId: articleId, Ip: ip, CreatedAt: time.Now()}
		err = SaveArticleView(articleView, db)
	}

	if nil == err {
		sql = "update user set view_count=view_count+1  where id = ? "
		_, err = db.Execute(sql, []interface{}{articleOwnerId})
	}

	if nil == err {
		err = db.Commit()
	} else {
		err = db.Rollback()
	}

	return nil == err, err
}
func TestTransaction(t *testing.T) {
	db := db.NewDB()

	err := db.Begin()
	var sql = "update article set view_count=view_count+1  where user_id = ? and id = ? "
	db.Execute(sql, []interface{}{1, 35120})

	if err == nil {
		db.Commit()
	} else {
		db.Rollback()
	}
}