Added api endpoints and tests

This commit is contained in:
2022-01-24 12:59:43 +01:00
parent 10b768743b
commit cfbdcc7f82
36 changed files with 1781 additions and 315 deletions

View File

@@ -1,104 +0,0 @@
package database
import (
"database/sql"
"fmt"
"gorm.io/gorm/clause"
)
type ArticleQueryOptions struct {
Name bool
Title bool
Summary bool
From int64
To int64
Limit int
}
func (db *Database) GetArticleByName(name string) (article *Article, err error) {
err = db.gormDB.Table("article").Where("name = ?", name).Scan(&article).Error
if article == nil {
return nil, sql.ErrNoRows
}
return article, err
}
func (db *Database) GetArticles(query string, options ArticleQueryOptions) ([]*Article, error) {
request := db.gormDB.Table("article")
var where bool
if options.Name {
if where {
request.Or("name LIKE ?", fmt.Sprintf("%%%s%%", query))
} else {
request.Where("name LIKE ?", fmt.Sprintf("%%%s%%", query))
where = true
}
}
if options.Title {
if where {
request.Or("title LIKE ?", fmt.Sprintf("%%%s%%", query))
} else {
request.Where("title LIKE ?", fmt.Sprintf("%%%s%%", query))
where = true
}
}
if options.Summary {
if where {
request.Or("summary LIKE ?", fmt.Sprintf("%%%s%%", query))
} else {
request.Where("summary LIKE ?", fmt.Sprintf("%%%s%%", query))
where = true
}
}
if !(options.From == 0 || options.To == 0) {
var from, to int64
if options.From != 0 {
from = options.From
}
if options.To != 0 {
to = options.To
}
request.Where("added BETWEEN ? AND ?", from, to)
}
if options.Limit > 0 {
request.Limit(options.Limit)
}
rows, err := request.Rows()
if err != nil {
return nil, err
}
var articles []*Article
for rows.Next() {
article := &Article{}
if err = db.gormDB.ScanRows(rows, article); err != nil {
return nil, err
}
articles = append(articles, article)
}
return articles, nil
}
func (db *Database) AddArticle(article Article, tags []Tag) error {
if err := db.gormDB.Table("article").Create(&article).Select("id", &article.ID).Error; err != nil {
return err
}
return db.gormDB.Table("article_tags").Create(ArticleTagsFromTagSlice(article, tags)).Error
}
func (db *Database) UpdateArticle(article Article, tags []Tag) error {
if err := db.gormDB.Table("article").Where("id = ?", article.ID).Save(article).Error; err != nil {
return err
}
return db.gormDB.Table("article_tags").Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "article_id"}, {Name: "tag_id"}},
DoNothing: true,
}).Create(ArticleTagsFromTagSlice(article, tags)).Error
}
func (db *Database) DeleteArticlesByNames(names ...string) error {
return db.gormDB.Table("article").Where("name IN (?)", names).Delete("*").Error
}

View File

@@ -5,29 +5,20 @@ import (
"gorm.io/gorm"
)
var globDatabase *Database
var globDatabase *gorm.DB
type Database struct {
gormDB *gorm.DB
func newDatabaseConnection(dialector gorm.Dialector) (*gorm.DB, error) {
return gorm.Open(dialector)
}
func newDatabaseConnection(dialector gorm.Dialector) (*Database, error) {
db, err := gorm.Open(dialector)
if err != nil {
return nil, err
}
return &Database{db}, nil
}
func NewSqlite3Connection(databaseFile string) (*Database, error) {
func NewSqlite3Connection(databaseFile string) (*gorm.DB, error) {
return newDatabaseConnection(sqlite.Open(databaseFile))
}
func GetDB() *Database {
func GetDB() *gorm.DB {
return globDatabase
}
func SetGlobDB(database *Database) {
func SetGlobDB(database *gorm.DB) {
globDatabase = database
}

View File

@@ -1,38 +0,0 @@
package database
import "fmt"
type Article struct {
ID int
Name string
Title string
Summary string
Image string
Added int64
Modified int64
Markdown string
Html string
}
func (a Article) ToArticleSummary() ArticleSummary {
return ArticleSummary{
Title: a.Title,
Summary: a.Summary,
Image: a.Image,
Link: fmt.Sprintf("/article/%s", a.Name),
}
}
type ArticleSummary struct {
Title string `json:"title"`
Summary string `json:"summary"`
Image string `json:"image"`
Link string `json:"link"`
}
type Author struct {
ID int
Name string
Email string
Password string
}

View File

@@ -1,54 +0,0 @@
package database
import (
"gorm.io/gorm/clause"
"strings"
)
type Tag struct {
ID int
Name string
}
func ArticleTagsFromTagSlice(article Article, tags []Tag) (tagsTable []ArticleTags) {
for _, tag := range tags {
tagsTable = append(tagsTable, ArticleTags{
ArticleID: article.ID,
TagID: tag.ID,
})
}
return
}
type ArticleTags struct {
ArticleID int
TagID int
}
func (db *Database) AddOrGetTags(names []string) (tags []Tag, err error) {
for i, name := range names {
names[i] = strings.ToLower(name)
}
err = db.gormDB.Table("tag").Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "name"}},
DoNothing: true,
}).Select("name").Create(&names).Error
if err != nil {
return nil, err
}
err = db.gormDB.Table("tag").Find(&tags).Where("name in (?)", &names).Error
return
}
func (db *Database) SetTags(article Article, tags []Tag) error {
return db.gormDB.Table("tags").Clauses(clause.OnConflict{
Columns: []clause.Column{{Name: "article_id"}, {Name: "tag_id"}},
DoNothing: true,
}).Create(ArticleTagsFromTagSlice(article, tags)).Error
}
func (db *Database) RemoveTags(article Article, tags []Tag) error {
return db.gormDB.Table("tags").Delete(ArticleTagsFromTagSlice(article, tags)).Error
}

9
database/utils.go Normal file
View File

@@ -0,0 +1,9 @@
package database
import "gorm.io/gorm"
func Exists(tx *gorm.DB, query interface{}, args ...interface{}) bool {
var exists bool
tx.Where(query, args...).Select("count(*) > 0").Find(&exists)
return exists
}