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 }