Write on the margins of the internet. Powered by the AT Protocol. margin.at
extension web atproto comments
at ui-refactor 208 lines 6.6 kB view raw
1package db 2 3import ( 4 "time" 5) 6 7func (db *DB) CreateAnnotation(a *Annotation) error { 8 _, err := db.Exec(db.Rebind(` 9 INSERT INTO annotations (uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid) 10 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) 11 ON CONFLICT(uri) DO UPDATE SET 12 motivation = excluded.motivation, 13 body_value = excluded.body_value, 14 body_format = excluded.body_format, 15 body_uri = excluded.body_uri, 16 target_title = excluded.target_title, 17 selector_json = excluded.selector_json, 18 tags_json = excluded.tags_json, 19 indexed_at = excluded.indexed_at, 20 cid = excluded.cid 21 `), a.URI, a.AuthorDID, a.Motivation, a.BodyValue, a.BodyFormat, a.BodyURI, a.TargetSource, a.TargetHash, a.TargetTitle, a.SelectorJSON, a.TagsJSON, a.CreatedAt, a.IndexedAt, a.CID) 22 return err 23} 24 25func (db *DB) GetAnnotationByURI(uri string) (*Annotation, error) { 26 var a Annotation 27 err := db.QueryRow(db.Rebind(` 28 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 29 FROM annotations 30 WHERE uri = ? 31 `), uri).Scan(&a.URI, &a.AuthorDID, &a.Motivation, &a.BodyValue, &a.BodyFormat, &a.BodyURI, &a.TargetSource, &a.TargetHash, &a.TargetTitle, &a.SelectorJSON, &a.TagsJSON, &a.CreatedAt, &a.IndexedAt, &a.CID) 32 if err != nil { 33 return nil, err 34 } 35 return &a, nil 36} 37 38func (db *DB) GetAnnotationsByTargetHash(targetHash string, limit, offset int) ([]Annotation, error) { 39 rows, err := db.Query(db.Rebind(` 40 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 41 FROM annotations 42 WHERE target_hash = ? 43 ORDER BY created_at DESC 44 LIMIT ? OFFSET ? 45 `), targetHash, limit, offset) 46 if err != nil { 47 return nil, err 48 } 49 defer rows.Close() 50 51 return scanAnnotations(rows) 52} 53 54func (db *DB) GetAnnotationsByAuthor(authorDID string, limit, offset int) ([]Annotation, error) { 55 rows, err := db.Query(db.Rebind(` 56 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 57 FROM annotations 58 WHERE author_did = ? 59 ORDER BY created_at DESC 60 LIMIT ? OFFSET ? 61 `), authorDID, limit, offset) 62 if err != nil { 63 return nil, err 64 } 65 defer rows.Close() 66 67 return scanAnnotations(rows) 68} 69 70func (db *DB) GetAnnotationsByMotivation(motivation string, limit, offset int) ([]Annotation, error) { 71 rows, err := db.Query(db.Rebind(` 72 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 73 FROM annotations 74 WHERE motivation = ? 75 ORDER BY created_at DESC 76 LIMIT ? OFFSET ? 77 `), motivation, limit, offset) 78 if err != nil { 79 return nil, err 80 } 81 defer rows.Close() 82 83 return scanAnnotations(rows) 84} 85 86func (db *DB) GetRecentAnnotations(limit, offset int) ([]Annotation, error) { 87 rows, err := db.Query(db.Rebind(` 88 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 89 FROM annotations 90 ORDER BY created_at DESC 91 LIMIT ? OFFSET ? 92 `), limit, offset) 93 if err != nil { 94 return nil, err 95 } 96 defer rows.Close() 97 98 return scanAnnotations(rows) 99} 100 101func (db *DB) GetAnnotationsByTag(tag string, limit, offset int) ([]Annotation, error) { 102 pattern := "%\"" + tag + "\"%" 103 rows, err := db.Query(db.Rebind(` 104 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 105 FROM annotations 106 WHERE tags_json LIKE ? 107 ORDER BY created_at DESC 108 LIMIT ? OFFSET ? 109 `), pattern, limit, offset) 110 if err != nil { 111 return nil, err 112 } 113 defer rows.Close() 114 115 return scanAnnotations(rows) 116} 117 118func (db *DB) DeleteAnnotation(uri string) error { 119 _, err := db.Exec(db.Rebind(`DELETE FROM annotations WHERE uri = ?`), uri) 120 return err 121} 122 123func (db *DB) UpdateAnnotation(uri, bodyValue, tagsJSON, cid string) error { 124 _, err := db.Exec(db.Rebind(` 125 UPDATE annotations 126 SET body_value = ?, tags_json = ?, cid = ?, indexed_at = ? 127 WHERE uri = ? 128 `), bodyValue, tagsJSON, cid, time.Now(), uri) 129 return err 130} 131 132func (db *DB) GetAnnotationsByTagAndAuthor(tag, authorDID string, limit, offset int) ([]Annotation, error) { 133 pattern := "%\"" + tag + "\"%" 134 rows, err := db.Query(db.Rebind(` 135 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 136 FROM annotations 137 WHERE author_did = ? AND tags_json LIKE ? 138 ORDER BY created_at DESC 139 LIMIT ? OFFSET ? 140 `), authorDID, pattern, limit, offset) 141 if err != nil { 142 return nil, err 143 } 144 defer rows.Close() 145 146 return scanAnnotations(rows) 147} 148 149func (db *DB) GetAnnotationsByAuthorAndTargetHash(authorDID, targetHash string, limit, offset int) ([]Annotation, error) { 150 rows, err := db.Query(db.Rebind(` 151 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 152 FROM annotations 153 WHERE author_did = ? AND target_hash = ? 154 ORDER BY created_at DESC 155 LIMIT ? OFFSET ? 156 `), authorDID, targetHash, limit, offset) 157 if err != nil { 158 return nil, err 159 } 160 defer rows.Close() 161 162 return scanAnnotations(rows) 163} 164 165func (db *DB) GetAnnotationsByURIs(uris []string) ([]Annotation, error) { 166 if len(uris) == 0 { 167 return []Annotation{}, nil 168 } 169 170 query := db.Rebind(` 171 SELECT uri, author_did, motivation, body_value, body_format, body_uri, target_source, target_hash, target_title, selector_json, tags_json, created_at, indexed_at, cid 172 FROM annotations 173 WHERE uri IN (` + buildPlaceholders(len(uris)) + `) 174 `) 175 176 args := make([]interface{}, len(uris)) 177 for i, uri := range uris { 178 args[i] = uri 179 } 180 181 rows, err := db.Query(query, args...) 182 if err != nil { 183 return nil, err 184 } 185 defer rows.Close() 186 187 return scanAnnotations(rows) 188} 189 190func (db *DB) GetAnnotationURIs(authorDID string) ([]string, error) { 191 rows, err := db.Query(db.Rebind(` 192 SELECT uri FROM annotations WHERE author_did = ? 193 `), authorDID) 194 if err != nil { 195 return nil, err 196 } 197 defer rows.Close() 198 199 var uris []string 200 for rows.Next() { 201 var uri string 202 if err := rows.Scan(&uri); err != nil { 203 return nil, err 204 } 205 uris = append(uris, uri) 206 } 207 return uris, nil 208}