Signed-off-by: Seongmin Lee git@boltless.me
+132
Diff
round #1
+14
appview/db/db.go
+14
appview/db/db.go
···
1615
1615
return err
1616
1616
})
1617
1617
1618
+
orm.RunMigration(conn, logger, "migrate-legacy-comments", func(tx *sql.Tx) error {
1619
+
_, err := tx.Exec(`
1620
+
insert into pds_migration (name, did, collection, rkey)
1621
+
select
1622
+
'use-feed-comment',
1623
+
did,
1624
+
collection,
1625
+
rkey
1626
+
from comments
1627
+
where collection <> 'sh.tangled.feed.comment';
1628
+
`)
1629
+
return err
1630
+
})
1631
+
1618
1632
return &DB{
1619
1633
db,
1620
1634
logger,
+113
appview/migration/migrate_use_feed_comment.go
+113
appview/migration/migrate_use_feed_comment.go
···
1
+
package migration
2
+
3
+
import (
4
+
"context"
5
+
"fmt"
6
+
7
+
"github.com/bluesky-social/indigo/api/agnostic"
8
+
comatproto "github.com/bluesky-social/indigo/api/atproto"
9
+
"github.com/bluesky-social/indigo/atproto/atclient"
10
+
"github.com/bluesky-social/indigo/atproto/syntax"
11
+
"github.com/bluesky-social/indigo/lex/util"
12
+
"github.com/bluesky-social/indigo/xrpc"
13
+
"tangled.org/core/api/tangled"
14
+
"tangled.org/core/appview/db"
15
+
"tangled.org/core/orm"
16
+
)
17
+
18
+
func (s *Migration) migrateUseFeedComment(ctx context.Context, client *atclient.APIClient, did syntax.DID, record syntax.ATURI) error {
19
+
l := s.logger.With("aturi", record)
20
+
l.Debug("migrating record")
21
+
22
+
switch record.Collection() {
23
+
case tangled.RepoIssueCommentNSID:
24
+
case tangled.RepoPullCommentNSID:
25
+
default:
26
+
return fmt.Errorf("unexpected collection: '%s'", record.Collection())
27
+
}
28
+
29
+
comment, err := db.GetComment(s.db, orm.FilterEq("at_uri", record))
30
+
if err != nil {
31
+
return fmt.Errorf("db: %w", err)
32
+
}
33
+
34
+
comment.Collection = tangled.FeedCommentNSID
35
+
36
+
// only update from DB if comment is deleted
37
+
if comment.Deleted != nil {
38
+
l.Info("skipping pds migration for deleted record")
39
+
40
+
return nil
41
+
}
42
+
43
+
// fill missing reference CIDs
44
+
if comment.Subject.Cid == "" {
45
+
cid, err := s.getRecordCid(ctx, syntax.ATURI(comment.Subject.Uri))
46
+
if err != nil {
47
+
return fmt.Errorf("pds: getRecordCid for subject.uri: %w", err)
48
+
}
49
+
comment.Subject.Cid = cid.String()
50
+
}
51
+
if comment.ReplyTo != nil && comment.ReplyTo.Cid == "" {
52
+
uri, err := syntax.ParseATURI(comment.ReplyTo.Uri)
53
+
if err != nil {
54
+
return fmt.Errorf("invalid replyTo.uri: %w", err)
55
+
}
56
+
57
+
// assume parent comment is already migrated to `sh.tangled.feed.comment`.
58
+
// fail if it isn't ready
59
+
uri = syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", uri.Authority(), tangled.FeedCommentNSID, uri.RecordKey()))
60
+
61
+
cid, err := s.getRecordCid(ctx, uri)
62
+
if err != nil {
63
+
return fmt.Errorf("pds: getRecordCid for replyTo.uri: %w", err)
64
+
}
65
+
comment.ReplyTo.Uri = uri.String()
66
+
comment.ReplyTo.Cid = cid.String()
67
+
}
68
+
69
+
// use same rkey for new record
70
+
rkey := record.RecordKey().String()
71
+
72
+
if _, err := comatproto.RepoApplyWrites(ctx, client, &comatproto.RepoApplyWrites_Input{
73
+
Repo: did.String(),
74
+
Writes: []*comatproto.RepoApplyWrites_Input_Writes_Elem{
75
+
{RepoApplyWrites_Delete: &comatproto.RepoApplyWrites_Delete{
76
+
Collection: record.Collection().String(),
77
+
Rkey: rkey,
78
+
}},
79
+
{RepoApplyWrites_Create: &comatproto.RepoApplyWrites_Create{
80
+
Collection: tangled.FeedCommentNSID,
81
+
Rkey: &rkey,
82
+
Value: &util.LexiconTypeDecoder{Val: comment.AsRecord()},
83
+
}},
84
+
},
85
+
}); err != nil {
86
+
return fmt.Errorf("pds: applyWrites: %w", err)
87
+
}
88
+
89
+
return nil
90
+
}
91
+
92
+
func (s *Migration) getRecordCid(ctx context.Context, uri syntax.ATURI) (syntax.CID, error) {
93
+
ident, err := s.dir.Lookup(ctx, uri.Authority())
94
+
if err != nil {
95
+
return "", err
96
+
}
97
+
98
+
xrpcc := xrpc.Client{Host: ident.PDSEndpoint()}
99
+
out, err := agnostic.RepoGetRecord(ctx, &xrpcc, "", uri.Collection().String(), ident.DID.String(), uri.RecordKey().String())
100
+
if err != nil {
101
+
return "", err
102
+
}
103
+
if out.Cid == nil {
104
+
return "", fmt.Errorf("record CID is empty")
105
+
}
106
+
107
+
cid, err := syntax.ParseCID(*out.Cid)
108
+
if err != nil {
109
+
return "", err
110
+
}
111
+
112
+
return cid, nil
113
+
}
+5
appview/migration/migration.go
+5
appview/migration/migration.go
···
71
71
switch migration.Name {
72
72
case "add-repo-did":
73
73
err = s.migrateAddRepoDid(ctx, client, migration.Did, migration.RecordAtUri())
74
+
case "use-feed-comment":
75
+
err = s.migrateUseFeedComment(ctx, client, migration.Did, migration.RecordAtUri())
74
76
default:
75
77
return fmt.Errorf("unexpected migration name %s", migration.Name)
76
78
}
···
78
80
if err == nil {
79
81
l.Info("migrated")
80
82
migration.Status = models.PDSMigrationStatusDone
83
+
migration.ErrorMsg = nil
84
+
migration.RetryCount = 0
85
+
migration.RetryAfter = 0
81
86
} else {
82
87
l.Warn("failed to migrate", "err", err)
83
88
History
2 rounds
0 comments
boltless.me
submitted
#1
1 commit
expand
collapse
appview: migrate legacy comment pds records
Signed-off-by: Seongmin Lee <git@boltless.me>
merge conflicts detected
expand
collapse
expand
collapse
- appview/migration/migration.go:71
expand 0 comments
boltless.me
submitted
#0
1 commit
expand
collapse
appview: migrate legacy comment pds records
Signed-off-by: Seongmin Lee <git@boltless.me>