Monorepo for Tangled
1package db
2
3import (
4 "database/sql"
5 "encoding/json"
6 "time"
7
8 "tangled.org/core/appview/models"
9)
10
11func InsertBlueskyPosts(e Execer, posts []models.BskyPost) error {
12 if len(posts) == 0 {
13 return nil
14 }
15
16 stmt, err := e.Prepare(`
17 insert or replace into bluesky_posts (rkey, text, created_at, langs, facets, embed, like_count, reply_count, repost_count, quote_count)
18 values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
19 `)
20 if err != nil {
21 return err
22 }
23 defer stmt.Close()
24
25 for _, post := range posts {
26 var langsJSON, facetsJSON, embedJSON []byte
27
28 if len(post.Langs) > 0 {
29 langsJSON, _ = json.Marshal(post.Langs)
30 }
31 if len(post.Facets) > 0 {
32 facetsJSON, _ = json.Marshal(post.Facets)
33 }
34 if post.Embed != nil {
35 embedJSON, _ = json.Marshal(post.Embed)
36 }
37
38 _, err := stmt.Exec(
39 post.Rkey,
40 post.Text,
41 post.CreatedAt.Format(time.RFC3339),
42 nullString(langsJSON),
43 nullString(facetsJSON),
44 nullString(embedJSON),
45 post.LikeCount,
46 post.ReplyCount,
47 post.RepostCount,
48 post.QuoteCount,
49 )
50 if err != nil {
51 return err
52 }
53 }
54
55 return nil
56}
57
58func nullString(b []byte) any {
59 if len(b) == 0 {
60 return nil
61 }
62 return string(b)
63}
64
65func GetBlueskyPosts(e Execer, limit int) ([]models.BskyPost, error) {
66 query := `
67 select rkey, text, created_at, langs, facets, embed, like_count, reply_count, repost_count, quote_count
68 from bluesky_posts
69 order by created_at desc
70 limit ?
71 `
72
73 rows, err := e.Query(query, limit)
74 if err != nil {
75 return nil, err
76 }
77 defer rows.Close()
78
79 var posts []models.BskyPost
80 for rows.Next() {
81 var rkey, text, createdAt string
82 var langs, facets, embed sql.Null[string]
83 var likeCount, replyCount, repostCount, quoteCount int64
84
85 err := rows.Scan(&rkey, &text, &createdAt, &langs, &facets, &embed, &likeCount, &replyCount, &repostCount, "eCount)
86 if err != nil {
87 return nil, err
88 }
89
90 post := models.BskyPost{
91 Rkey: rkey,
92 Text: text,
93 LikeCount: likeCount,
94 ReplyCount: replyCount,
95 RepostCount: repostCount,
96 QuoteCount: quoteCount,
97 }
98
99 if t, err := time.Parse(time.RFC3339, createdAt); err == nil {
100 post.CreatedAt = t
101 }
102 if langs.Valid && langs.V != "" {
103 json.Unmarshal([]byte(langs.V), &post.Langs)
104 }
105 if facets.Valid && facets.V != "" {
106 json.Unmarshal([]byte(facets.V), &post.Facets)
107 }
108 if embed.Valid && embed.V != "" {
109 json.Unmarshal([]byte(embed.V), &post.Embed)
110 }
111
112 posts = append(posts, post)
113 }
114
115 return posts, rows.Err()
116}