227 lines
5.4 KiB
Go
227 lines
5.4 KiB
Go
|
package repository
|
||
|
|
||
|
import (
|
||
|
"database/sql"
|
||
|
"errors"
|
||
|
"fmt"
|
||
|
"time"
|
||
|
|
||
|
"git.jamestombleson.com/jtom38/newsbot-api/internal/domain"
|
||
|
"github.com/huandu/go-sqlbuilder"
|
||
|
)
|
||
|
|
||
|
type ArticleRepository struct {
|
||
|
conn *sql.DB
|
||
|
defaultLimit int
|
||
|
defaultOffset int
|
||
|
}
|
||
|
|
||
|
func NewArticleRepository(conn *sql.DB) ArticleRepository {
|
||
|
return ArticleRepository{
|
||
|
conn: conn,
|
||
|
defaultLimit: 50,
|
||
|
defaultOffset: 50,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (ar ArticleRepository) GetById(id int64) (domain.ArticleEntity, error) {
|
||
|
builder := sqlbuilder.NewSelectBuilder()
|
||
|
builder.Select("*")
|
||
|
builder.From("articles").Where(
|
||
|
builder.E("id", id),
|
||
|
)
|
||
|
builder.Limit(1)
|
||
|
|
||
|
query, args := builder.Build()
|
||
|
rows, err := ar.conn.Query(query, args...)
|
||
|
if err != nil {
|
||
|
return domain.ArticleEntity{}, err
|
||
|
}
|
||
|
|
||
|
data := ar.processRows(rows)
|
||
|
if len(data) == 0 {
|
||
|
return domain.ArticleEntity{}, errors.New(ErrUserNotFound)
|
||
|
}
|
||
|
|
||
|
return data[0], nil
|
||
|
}
|
||
|
|
||
|
func (ar ArticleRepository) GetByUrl(url string) (domain.ArticleEntity, error) {
|
||
|
builder := sqlbuilder.NewSelectBuilder()
|
||
|
builder.Select("*")
|
||
|
builder.From("articles").Where(
|
||
|
builder.E("url", url),
|
||
|
)
|
||
|
builder.Limit(1)
|
||
|
|
||
|
query, args := builder.Build()
|
||
|
rows, err := ar.conn.Query(query, args...)
|
||
|
if err != nil {
|
||
|
return domain.ArticleEntity{}, err
|
||
|
}
|
||
|
|
||
|
data := ar.processRows(rows)
|
||
|
if len(data) == 0 {
|
||
|
return domain.ArticleEntity{}, errors.New(ErrUserNotFound)
|
||
|
}
|
||
|
|
||
|
return data[0], nil
|
||
|
}
|
||
|
|
||
|
func (ar ArticleRepository) List(limit int) ([]domain.ArticleEntity, error) {
|
||
|
builder := sqlbuilder.NewSelectBuilder()
|
||
|
builder.Select("*")
|
||
|
builder.From("articles")
|
||
|
//builder.OrderBy("pubdate")
|
||
|
builder.Limit(limit)
|
||
|
//builder.Offset(50)
|
||
|
|
||
|
query, args := builder.Build()
|
||
|
rows, err := ar.conn.Query(query, args...)
|
||
|
if err != nil {
|
||
|
return []domain.ArticleEntity{}, err
|
||
|
}
|
||
|
|
||
|
data := ar.processRows(rows)
|
||
|
if len(data) == 0 {
|
||
|
return []domain.ArticleEntity{}, errors.New(ErrUserNotFound)
|
||
|
}
|
||
|
|
||
|
return data, nil
|
||
|
}
|
||
|
|
||
|
func (ar ArticleRepository) ListByPage(page, limit int) ([]domain.ArticleEntity, error) {
|
||
|
builder := sqlbuilder.NewSelectBuilder()
|
||
|
builder.Select("*")
|
||
|
builder.From("articles")
|
||
|
builder.OrderBy("pubdate desc")
|
||
|
builder.Offset(page * limit)
|
||
|
builder.Limit(limit)
|
||
|
|
||
|
query, args := builder.Build()
|
||
|
rows, err := ar.conn.Query(query, args...)
|
||
|
if err != nil {
|
||
|
return []domain.ArticleEntity{}, err
|
||
|
}
|
||
|
|
||
|
data := ar.processRows(rows)
|
||
|
if len(data) == 0 {
|
||
|
return []domain.ArticleEntity{}, errors.New(ErrUserNotFound)
|
||
|
}
|
||
|
|
||
|
return data, nil
|
||
|
}
|
||
|
|
||
|
func (ar ArticleRepository) ListByPublishDate(limit int) ([]domain.ArticleEntity, error) {
|
||
|
builder := sqlbuilder.NewSelectBuilder()
|
||
|
builder.Select("*")
|
||
|
builder.From("articles")
|
||
|
//builder.OrderBy("pubdate")
|
||
|
builder.Limit(limit)
|
||
|
//builder.Offset(50)
|
||
|
|
||
|
query, args := builder.Build()
|
||
|
rows, err := ar.conn.Query(query, args...)
|
||
|
if err != nil {
|
||
|
return []domain.ArticleEntity{}, err
|
||
|
}
|
||
|
|
||
|
data := ar.processRows(rows)
|
||
|
if len(data) == 0 {
|
||
|
return []domain.ArticleEntity{}, errors.New(ErrUserNotFound)
|
||
|
}
|
||
|
return data, nil
|
||
|
}
|
||
|
|
||
|
func (ar ArticleRepository) ListBySource(sourceName string, limit int) ([]domain.ArticleEntity, error) {
|
||
|
builder := sqlbuilder.NewSelectBuilder()
|
||
|
builder.Select("*")
|
||
|
builder.From("articles")
|
||
|
builder.JoinWithOption("InnerJoin", "sources", "articles.sourceId=sources.Id")
|
||
|
builder.OrderBy("pubdate")
|
||
|
builder.Limit(limit)
|
||
|
builder.Offset(50)
|
||
|
|
||
|
query, args := builder.Build()
|
||
|
rows, err := ar.conn.Query(query, args...)
|
||
|
if err != nil {
|
||
|
return []domain.ArticleEntity{}, err
|
||
|
}
|
||
|
|
||
|
data := ar.processRows(rows)
|
||
|
if len(data) == 0 {
|
||
|
return []domain.ArticleEntity{}, errors.New(ErrUserNotFound)
|
||
|
}
|
||
|
return data, nil
|
||
|
}
|
||
|
|
||
|
func (ar ArticleRepository) Create(sourceId int64, tags, title, url, thumbnailUrl, description, authorName, authorImageUrl string, pubDate time.Time, isVideo bool) (int64, error) {
|
||
|
dt := time.Now()
|
||
|
queryBuilder := sqlbuilder.NewInsertBuilder()
|
||
|
queryBuilder.InsertInto("articles")
|
||
|
queryBuilder.Cols("UpdatedAt", "CreatedAt", "SourceId", "Tags", "Title", "Url", "PubDate", "IsVideo", "ThumbnailUrl", "Description", "AuthorName", "AuthorImageUrl")
|
||
|
queryBuilder.Values(dt, dt, sourceId, tags, title, url, pubDate, isVideo, thumbnailUrl, description, authorName, authorImageUrl)
|
||
|
query, args := queryBuilder.Build()
|
||
|
|
||
|
_, err := ar.conn.Exec(query, args...)
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
|
||
|
return 1, nil
|
||
|
}
|
||
|
|
||
|
func (ur ArticleRepository) processRows(rows *sql.Rows) []domain.ArticleEntity {
|
||
|
items := []domain.ArticleEntity{}
|
||
|
|
||
|
for rows.Next() {
|
||
|
var id int64
|
||
|
var createdAt time.Time
|
||
|
var updatedAt time.Time
|
||
|
var deletedAt sql.NullTime
|
||
|
var sourceId int64
|
||
|
var tags string
|
||
|
var title string
|
||
|
var url string
|
||
|
var pubDate time.Time
|
||
|
var isVideo bool
|
||
|
var thumbnail string
|
||
|
var description string
|
||
|
var authorName string
|
||
|
var authorImageUrl string
|
||
|
err := rows.Scan(
|
||
|
&id, &createdAt, &updatedAt,
|
||
|
&deletedAt, &sourceId, &tags,
|
||
|
&title, &url, &pubDate,
|
||
|
&isVideo, &thumbnail, &description,
|
||
|
&authorName, &authorImageUrl)
|
||
|
if err != nil {
|
||
|
fmt.Println(err)
|
||
|
}
|
||
|
|
||
|
item := domain.ArticleEntity{
|
||
|
ID: id,
|
||
|
CreatedAt: createdAt,
|
||
|
UpdatedAt: updatedAt,
|
||
|
SourceID: sourceId,
|
||
|
Tags: tags,
|
||
|
Title: title,
|
||
|
Url: url,
|
||
|
PubDate: pubDate,
|
||
|
IsVideo: isVideo,
|
||
|
Thumbnail: thumbnail,
|
||
|
Description: description,
|
||
|
AuthorName: authorName,
|
||
|
AuthorImageUrl: authorImageUrl,
|
||
|
}
|
||
|
|
||
|
if deletedAt.Valid {
|
||
|
item.DeletedAt = deletedAt.Time
|
||
|
}
|
||
|
|
||
|
items = append(items, item)
|
||
|
}
|
||
|
|
||
|
return items
|
||
|
}
|