package controller import ( "arimelody-web/model" "database/sql" "strings" "github.com/jmoiron/sqlx" ) func GetBlogPost(db *sqlx.DB, id string) (*model.BlogPost, error) { var blog = model.BlogPost{} rows, err := db.Query( "SELECT post.id,post.title,post.description,post.visible," + "post.publish_date,post.author,post.markdown," + "post.bluesky_actor,post.bluesky_record," + "post.fediverse_account,post.fediverse_status," + "author.id,author.username,author.avatar_url " + "FROM blogpost AS post " + "JOIN account AS author ON post.author=author.id " + "WHERE post.id=$1", id, ) if err != nil { if strings.Contains(err.Error(), "no rows") { return nil, nil } return nil, err } blueskyActor := sql.NullString{} blueskyRecord := sql.NullString{} fediverseAccount := sql.NullString{} fediverseStatus := sql.NullString{} if !rows.Next() { return nil, nil } err = rows.Scan( &blog.ID, &blog.Title, &blog.Description, &blog.Visible, &blog.PublishDate, &blog.Author.ID, &blog.Markdown, &blueskyActor, &blueskyRecord, &fediverseAccount, &fediverseStatus, &blog.Author.ID, &blog.Author.DisplayName, &blog.Author.AvatarURL, ) if err != nil { return nil, err } if blueskyActor.Valid && blueskyRecord.Valid { blog.Bluesky = &model.BlueskyRecord{ ActorDID: blueskyActor.String, RecordID: blueskyRecord.String, } } if fediverseAccount.Valid && fediverseStatus.Valid { blog.Fediverse = &model.FediverseActivity{ AccountID: fediverseAccount.String, StatusID: fediverseStatus.String, } } return &blog, nil } func GetBlogPosts(db *sqlx.DB, onlyVisible bool, limit int, offset int) ([]*model.BlogPost, error) { var blogs = []*model.BlogPost{} query := "SELECT post.id,post.title,post.publish_date," + "post.description,post.visible," + "author.id,author.username,author.avatar_url " + "FROM blogpost AS post " + "JOIN account AS author ON post.author=author.id" if onlyVisible { query += " WHERE visible=true" } query += " ORDER BY publish_date DESC" var rows *sql.Rows var err error if limit < 0 { rows, err = db.Query(query) } else { rows, err = db.Query(query + " LIMIT $1 OFFSET $2", limit, offset) } if err != nil { return nil, err } for rows.Next() { blog := model.BlogPost{} err = rows.Scan( &blog.ID, &blog.Title, &blog.PublishDate, &blog.Description, &blog.Visible, &blog.Author.ID, &blog.Author.DisplayName, &blog.Author.AvatarURL, ) if err != nil { return nil, err } blogs = append(blogs, &blog) } return blogs, nil } func GetBlogPostCount(db *sqlx.DB, onlyVisible bool) (int, error) { query := "SELECT count(*) FROM blogpost" if onlyVisible { query += " WHERE visible=true" } var count int err := db.Get(&count, query) return count, err } func CreateBlogPost(db *sqlx.DB, post *model.BlogPost) error { var blueskyActor *string var blueskyRecord *string if post.Bluesky != nil { blueskyActor = &post.Bluesky.ActorDID blueskyRecord = &post.Bluesky.RecordID } var fediverseAccount *string var fediverseStatus *string if post.Fediverse != nil { fediverseAccount = &post.Fediverse.AccountID fediverseStatus = &post.Fediverse.StatusID } _, err := db.Exec( "INSERT INTO blogpost (" + "id,title,description,visible," + "publish_date,author,markdown," + "bluesky_actor,bluesky_record," + "fediverse_account,fediverse_status) " + "VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11)", post.ID, post.Title, post.Description, post.Visible, post.PublishDate, post.Author.ID, post.Markdown, blueskyActor, blueskyRecord, fediverseAccount, fediverseStatus, ) return err } func UpdateBlogPost(db *sqlx.DB, postID string, post *model.BlogPost) error { var blueskyActor string var blueskyRecord string if post.Bluesky != nil { blueskyActor = post.Bluesky.ActorDID blueskyRecord = post.Bluesky.RecordID } var fediverseAccount string var fediverseStatus string if post.Fediverse != nil { fediverseAccount = post.Fediverse.AccountID fediverseStatus = post.Fediverse.StatusID } _, err := db.Exec( "UPDATE blogpost SET " + "id=$2,title=$3,description=$4,visible=$5," + "publish_date=$6,author=$7,markdown=$8," + "bluesky_actor=$9,bluesky_record=$10," + "fediverse_account=$11,fediverse_status=$12 " + "WHERE id=$1", postID, post.ID, post.Title, post.Description, post.Visible, post.PublishDate, post.Author.ID, post.Markdown, blueskyActor, blueskyRecord, fediverseAccount, fediverseStatus, ) return err } func DeleteBlogPost(db *sqlx.DB, postID string) error { _, err := db.Exec( "DELETE FROM blogpost "+ "WHERE id=$1", postID, ) if err != nil { return err } return nil }