+487
-6
api/tangled/cbor_gen.go
+487
-6
api/tangled/cbor_gen.go
···
6881
6881
}
6882
6882
6883
6883
cw := cbg.NewCborWriter(w)
6884
-
fieldCount := 5
6884
+
fieldCount := 7
6885
6885
6886
6886
if t.Body == nil {
6887
+
fieldCount--
6888
+
}
6889
+
6890
+
if t.Mentions == nil {
6891
+
fieldCount--
6892
+
}
6893
+
6894
+
if t.References == nil {
6887
6895
fieldCount--
6888
6896
}
6889
6897
···
6988
6996
return err
6989
6997
}
6990
6998
6999
+
// t.Mentions ([]string) (slice)
7000
+
if t.Mentions != nil {
7001
+
7002
+
if len("mentions") > 1000000 {
7003
+
return xerrors.Errorf("Value in field \"mentions\" was too long")
7004
+
}
7005
+
7006
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("mentions"))); err != nil {
7007
+
return err
7008
+
}
7009
+
if _, err := cw.WriteString(string("mentions")); err != nil {
7010
+
return err
7011
+
}
7012
+
7013
+
if len(t.Mentions) > 8192 {
7014
+
return xerrors.Errorf("Slice value in field t.Mentions was too long")
7015
+
}
7016
+
7017
+
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Mentions))); err != nil {
7018
+
return err
7019
+
}
7020
+
for _, v := range t.Mentions {
7021
+
if len(v) > 1000000 {
7022
+
return xerrors.Errorf("Value in field v was too long")
7023
+
}
7024
+
7025
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil {
7026
+
return err
7027
+
}
7028
+
if _, err := cw.WriteString(string(v)); err != nil {
7029
+
return err
7030
+
}
7031
+
7032
+
}
7033
+
}
7034
+
6991
7035
// t.CreatedAt (string) (string)
6992
7036
if len("createdAt") > 1000000 {
6993
7037
return xerrors.Errorf("Value in field \"createdAt\" was too long")
···
7010
7054
if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
7011
7055
return err
7012
7056
}
7057
+
7058
+
// t.References ([]string) (slice)
7059
+
if t.References != nil {
7060
+
7061
+
if len("references") > 1000000 {
7062
+
return xerrors.Errorf("Value in field \"references\" was too long")
7063
+
}
7064
+
7065
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("references"))); err != nil {
7066
+
return err
7067
+
}
7068
+
if _, err := cw.WriteString(string("references")); err != nil {
7069
+
return err
7070
+
}
7071
+
7072
+
if len(t.References) > 8192 {
7073
+
return xerrors.Errorf("Slice value in field t.References was too long")
7074
+
}
7075
+
7076
+
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.References))); err != nil {
7077
+
return err
7078
+
}
7079
+
for _, v := range t.References {
7080
+
if len(v) > 1000000 {
7081
+
return xerrors.Errorf("Value in field v was too long")
7082
+
}
7083
+
7084
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil {
7085
+
return err
7086
+
}
7087
+
if _, err := cw.WriteString(string(v)); err != nil {
7088
+
return err
7089
+
}
7090
+
7091
+
}
7092
+
}
7013
7093
return nil
7014
7094
}
7015
7095
···
7038
7118
7039
7119
n := extra
7040
7120
7041
-
nameBuf := make([]byte, 9)
7121
+
nameBuf := make([]byte, 10)
7042
7122
for i := uint64(0); i < n; i++ {
7043
7123
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
7044
7124
if err != nil {
···
7107
7187
}
7108
7188
7109
7189
t.Title = string(sval)
7190
+
}
7191
+
// t.Mentions ([]string) (slice)
7192
+
case "mentions":
7193
+
7194
+
maj, extra, err = cr.ReadHeader()
7195
+
if err != nil {
7196
+
return err
7197
+
}
7198
+
7199
+
if extra > 8192 {
7200
+
return fmt.Errorf("t.Mentions: array too large (%d)", extra)
7201
+
}
7202
+
7203
+
if maj != cbg.MajArray {
7204
+
return fmt.Errorf("expected cbor array")
7205
+
}
7206
+
7207
+
if extra > 0 {
7208
+
t.Mentions = make([]string, extra)
7209
+
}
7210
+
7211
+
for i := 0; i < int(extra); i++ {
7212
+
{
7213
+
var maj byte
7214
+
var extra uint64
7215
+
var err error
7216
+
_ = maj
7217
+
_ = extra
7218
+
_ = err
7219
+
7220
+
{
7221
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
7222
+
if err != nil {
7223
+
return err
7224
+
}
7225
+
7226
+
t.Mentions[i] = string(sval)
7227
+
}
7228
+
7229
+
}
7110
7230
}
7111
7231
// t.CreatedAt (string) (string)
7112
7232
case "createdAt":
···
7119
7239
7120
7240
t.CreatedAt = string(sval)
7121
7241
}
7242
+
// t.References ([]string) (slice)
7243
+
case "references":
7244
+
7245
+
maj, extra, err = cr.ReadHeader()
7246
+
if err != nil {
7247
+
return err
7248
+
}
7249
+
7250
+
if extra > 8192 {
7251
+
return fmt.Errorf("t.References: array too large (%d)", extra)
7252
+
}
7253
+
7254
+
if maj != cbg.MajArray {
7255
+
return fmt.Errorf("expected cbor array")
7256
+
}
7257
+
7258
+
if extra > 0 {
7259
+
t.References = make([]string, extra)
7260
+
}
7261
+
7262
+
for i := 0; i < int(extra); i++ {
7263
+
{
7264
+
var maj byte
7265
+
var extra uint64
7266
+
var err error
7267
+
_ = maj
7268
+
_ = extra
7269
+
_ = err
7270
+
7271
+
{
7272
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
7273
+
if err != nil {
7274
+
return err
7275
+
}
7276
+
7277
+
t.References[i] = string(sval)
7278
+
}
7279
+
7280
+
}
7281
+
}
7122
7282
7123
7283
default:
7124
7284
// Field doesn't exist on this type, so ignore it
···
7137
7297
}
7138
7298
7139
7299
cw := cbg.NewCborWriter(w)
7140
-
fieldCount := 5
7300
+
fieldCount := 7
7301
+
7302
+
if t.Mentions == nil {
7303
+
fieldCount--
7304
+
}
7305
+
7306
+
if t.References == nil {
7307
+
fieldCount--
7308
+
}
7141
7309
7142
7310
if t.ReplyTo == nil {
7143
7311
fieldCount--
···
7244
7412
}
7245
7413
}
7246
7414
7415
+
// t.Mentions ([]string) (slice)
7416
+
if t.Mentions != nil {
7417
+
7418
+
if len("mentions") > 1000000 {
7419
+
return xerrors.Errorf("Value in field \"mentions\" was too long")
7420
+
}
7421
+
7422
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("mentions"))); err != nil {
7423
+
return err
7424
+
}
7425
+
if _, err := cw.WriteString(string("mentions")); err != nil {
7426
+
return err
7427
+
}
7428
+
7429
+
if len(t.Mentions) > 8192 {
7430
+
return xerrors.Errorf("Slice value in field t.Mentions was too long")
7431
+
}
7432
+
7433
+
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Mentions))); err != nil {
7434
+
return err
7435
+
}
7436
+
for _, v := range t.Mentions {
7437
+
if len(v) > 1000000 {
7438
+
return xerrors.Errorf("Value in field v was too long")
7439
+
}
7440
+
7441
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil {
7442
+
return err
7443
+
}
7444
+
if _, err := cw.WriteString(string(v)); err != nil {
7445
+
return err
7446
+
}
7447
+
7448
+
}
7449
+
}
7450
+
7247
7451
// t.CreatedAt (string) (string)
7248
7452
if len("createdAt") > 1000000 {
7249
7453
return xerrors.Errorf("Value in field \"createdAt\" was too long")
···
7266
7470
if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
7267
7471
return err
7268
7472
}
7473
+
7474
+
// t.References ([]string) (slice)
7475
+
if t.References != nil {
7476
+
7477
+
if len("references") > 1000000 {
7478
+
return xerrors.Errorf("Value in field \"references\" was too long")
7479
+
}
7480
+
7481
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("references"))); err != nil {
7482
+
return err
7483
+
}
7484
+
if _, err := cw.WriteString(string("references")); err != nil {
7485
+
return err
7486
+
}
7487
+
7488
+
if len(t.References) > 8192 {
7489
+
return xerrors.Errorf("Slice value in field t.References was too long")
7490
+
}
7491
+
7492
+
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.References))); err != nil {
7493
+
return err
7494
+
}
7495
+
for _, v := range t.References {
7496
+
if len(v) > 1000000 {
7497
+
return xerrors.Errorf("Value in field v was too long")
7498
+
}
7499
+
7500
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil {
7501
+
return err
7502
+
}
7503
+
if _, err := cw.WriteString(string(v)); err != nil {
7504
+
return err
7505
+
}
7506
+
7507
+
}
7508
+
}
7269
7509
return nil
7270
7510
}
7271
7511
···
7294
7534
7295
7535
n := extra
7296
7536
7297
-
nameBuf := make([]byte, 9)
7537
+
nameBuf := make([]byte, 10)
7298
7538
for i := uint64(0); i < n; i++ {
7299
7539
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
7300
7540
if err != nil {
···
7362
7602
}
7363
7603
7364
7604
t.ReplyTo = (*string)(&sval)
7605
+
}
7606
+
}
7607
+
// t.Mentions ([]string) (slice)
7608
+
case "mentions":
7609
+
7610
+
maj, extra, err = cr.ReadHeader()
7611
+
if err != nil {
7612
+
return err
7613
+
}
7614
+
7615
+
if extra > 8192 {
7616
+
return fmt.Errorf("t.Mentions: array too large (%d)", extra)
7617
+
}
7618
+
7619
+
if maj != cbg.MajArray {
7620
+
return fmt.Errorf("expected cbor array")
7621
+
}
7622
+
7623
+
if extra > 0 {
7624
+
t.Mentions = make([]string, extra)
7625
+
}
7626
+
7627
+
for i := 0; i < int(extra); i++ {
7628
+
{
7629
+
var maj byte
7630
+
var extra uint64
7631
+
var err error
7632
+
_ = maj
7633
+
_ = extra
7634
+
_ = err
7635
+
7636
+
{
7637
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
7638
+
if err != nil {
7639
+
return err
7640
+
}
7641
+
7642
+
t.Mentions[i] = string(sval)
7643
+
}
7644
+
7365
7645
}
7366
7646
}
7367
7647
// t.CreatedAt (string) (string)
···
7374
7654
}
7375
7655
7376
7656
t.CreatedAt = string(sval)
7657
+
}
7658
+
// t.References ([]string) (slice)
7659
+
case "references":
7660
+
7661
+
maj, extra, err = cr.ReadHeader()
7662
+
if err != nil {
7663
+
return err
7664
+
}
7665
+
7666
+
if extra > 8192 {
7667
+
return fmt.Errorf("t.References: array too large (%d)", extra)
7668
+
}
7669
+
7670
+
if maj != cbg.MajArray {
7671
+
return fmt.Errorf("expected cbor array")
7672
+
}
7673
+
7674
+
if extra > 0 {
7675
+
t.References = make([]string, extra)
7676
+
}
7677
+
7678
+
for i := 0; i < int(extra); i++ {
7679
+
{
7680
+
var maj byte
7681
+
var extra uint64
7682
+
var err error
7683
+
_ = maj
7684
+
_ = extra
7685
+
_ = err
7686
+
7687
+
{
7688
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
7689
+
if err != nil {
7690
+
return err
7691
+
}
7692
+
7693
+
t.References[i] = string(sval)
7694
+
}
7695
+
7696
+
}
7377
7697
}
7378
7698
7379
7699
default:
···
7892
8212
}
7893
8213
7894
8214
cw := cbg.NewCborWriter(w)
8215
+
fieldCount := 6
7895
8216
7896
-
if _, err := cw.Write([]byte{164}); err != nil {
8217
+
if t.Mentions == nil {
8218
+
fieldCount--
8219
+
}
8220
+
8221
+
if t.References == nil {
8222
+
fieldCount--
8223
+
}
8224
+
8225
+
if _, err := cw.Write(cbg.CborEncodeMajorType(cbg.MajMap, uint64(fieldCount))); err != nil {
7897
8226
return err
7898
8227
}
7899
8228
···
7962
8291
return err
7963
8292
}
7964
8293
8294
+
// t.Mentions ([]string) (slice)
8295
+
if t.Mentions != nil {
8296
+
8297
+
if len("mentions") > 1000000 {
8298
+
return xerrors.Errorf("Value in field \"mentions\" was too long")
8299
+
}
8300
+
8301
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("mentions"))); err != nil {
8302
+
return err
8303
+
}
8304
+
if _, err := cw.WriteString(string("mentions")); err != nil {
8305
+
return err
8306
+
}
8307
+
8308
+
if len(t.Mentions) > 8192 {
8309
+
return xerrors.Errorf("Slice value in field t.Mentions was too long")
8310
+
}
8311
+
8312
+
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.Mentions))); err != nil {
8313
+
return err
8314
+
}
8315
+
for _, v := range t.Mentions {
8316
+
if len(v) > 1000000 {
8317
+
return xerrors.Errorf("Value in field v was too long")
8318
+
}
8319
+
8320
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil {
8321
+
return err
8322
+
}
8323
+
if _, err := cw.WriteString(string(v)); err != nil {
8324
+
return err
8325
+
}
8326
+
8327
+
}
8328
+
}
8329
+
7965
8330
// t.CreatedAt (string) (string)
7966
8331
if len("createdAt") > 1000000 {
7967
8332
return xerrors.Errorf("Value in field \"createdAt\" was too long")
···
7983
8348
}
7984
8349
if _, err := cw.WriteString(string(t.CreatedAt)); err != nil {
7985
8350
return err
8351
+
}
8352
+
8353
+
// t.References ([]string) (slice)
8354
+
if t.References != nil {
8355
+
8356
+
if len("references") > 1000000 {
8357
+
return xerrors.Errorf("Value in field \"references\" was too long")
8358
+
}
8359
+
8360
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len("references"))); err != nil {
8361
+
return err
8362
+
}
8363
+
if _, err := cw.WriteString(string("references")); err != nil {
8364
+
return err
8365
+
}
8366
+
8367
+
if len(t.References) > 8192 {
8368
+
return xerrors.Errorf("Slice value in field t.References was too long")
8369
+
}
8370
+
8371
+
if err := cw.WriteMajorTypeHeader(cbg.MajArray, uint64(len(t.References))); err != nil {
8372
+
return err
8373
+
}
8374
+
for _, v := range t.References {
8375
+
if len(v) > 1000000 {
8376
+
return xerrors.Errorf("Value in field v was too long")
8377
+
}
8378
+
8379
+
if err := cw.WriteMajorTypeHeader(cbg.MajTextString, uint64(len(v))); err != nil {
8380
+
return err
8381
+
}
8382
+
if _, err := cw.WriteString(string(v)); err != nil {
8383
+
return err
8384
+
}
8385
+
8386
+
}
7986
8387
}
7987
8388
return nil
7988
8389
}
···
8012
8413
8013
8414
n := extra
8014
8415
8015
-
nameBuf := make([]byte, 9)
8416
+
nameBuf := make([]byte, 10)
8016
8417
for i := uint64(0); i < n; i++ {
8017
8418
nameLen, ok, err := cbg.ReadFullStringIntoBuf(cr, nameBuf, 1000000)
8018
8419
if err != nil {
···
8061
8462
8062
8463
t.LexiconTypeID = string(sval)
8063
8464
}
8465
+
// t.Mentions ([]string) (slice)
8466
+
case "mentions":
8467
+
8468
+
maj, extra, err = cr.ReadHeader()
8469
+
if err != nil {
8470
+
return err
8471
+
}
8472
+
8473
+
if extra > 8192 {
8474
+
return fmt.Errorf("t.Mentions: array too large (%d)", extra)
8475
+
}
8476
+
8477
+
if maj != cbg.MajArray {
8478
+
return fmt.Errorf("expected cbor array")
8479
+
}
8480
+
8481
+
if extra > 0 {
8482
+
t.Mentions = make([]string, extra)
8483
+
}
8484
+
8485
+
for i := 0; i < int(extra); i++ {
8486
+
{
8487
+
var maj byte
8488
+
var extra uint64
8489
+
var err error
8490
+
_ = maj
8491
+
_ = extra
8492
+
_ = err
8493
+
8494
+
{
8495
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
8496
+
if err != nil {
8497
+
return err
8498
+
}
8499
+
8500
+
t.Mentions[i] = string(sval)
8501
+
}
8502
+
8503
+
}
8504
+
}
8064
8505
// t.CreatedAt (string) (string)
8065
8506
case "createdAt":
8066
8507
···
8071
8512
}
8072
8513
8073
8514
t.CreatedAt = string(sval)
8515
+
}
8516
+
// t.References ([]string) (slice)
8517
+
case "references":
8518
+
8519
+
maj, extra, err = cr.ReadHeader()
8520
+
if err != nil {
8521
+
return err
8522
+
}
8523
+
8524
+
if extra > 8192 {
8525
+
return fmt.Errorf("t.References: array too large (%d)", extra)
8526
+
}
8527
+
8528
+
if maj != cbg.MajArray {
8529
+
return fmt.Errorf("expected cbor array")
8530
+
}
8531
+
8532
+
if extra > 0 {
8533
+
t.References = make([]string, extra)
8534
+
}
8535
+
8536
+
for i := 0; i < int(extra); i++ {
8537
+
{
8538
+
var maj byte
8539
+
var extra uint64
8540
+
var err error
8541
+
_ = maj
8542
+
_ = extra
8543
+
_ = err
8544
+
8545
+
{
8546
+
sval, err := cbg.ReadStringWithMax(cr, 1000000)
8547
+
if err != nil {
8548
+
return err
8549
+
}
8550
+
8551
+
t.References[i] = string(sval)
8552
+
}
8553
+
8554
+
}
8074
8555
}
8075
8556
8076
8557
default:
+7
-5
api/tangled/issuecomment.go
+7
-5
api/tangled/issuecomment.go
···
17
17
} //
18
18
// RECORDTYPE: RepoIssueComment
19
19
type RepoIssueComment struct {
20
-
LexiconTypeID string `json:"$type,const=sh.tangled.repo.issue.comment" cborgen:"$type,const=sh.tangled.repo.issue.comment"`
21
-
Body string `json:"body" cborgen:"body"`
22
-
CreatedAt string `json:"createdAt" cborgen:"createdAt"`
23
-
Issue string `json:"issue" cborgen:"issue"`
24
-
ReplyTo *string `json:"replyTo,omitempty" cborgen:"replyTo,omitempty"`
20
+
LexiconTypeID string `json:"$type,const=sh.tangled.repo.issue.comment" cborgen:"$type,const=sh.tangled.repo.issue.comment"`
21
+
Body string `json:"body" cborgen:"body"`
22
+
CreatedAt string `json:"createdAt" cborgen:"createdAt"`
23
+
Issue string `json:"issue" cborgen:"issue"`
24
+
Mentions []string `json:"mentions,omitempty" cborgen:"mentions,omitempty"`
25
+
References []string `json:"references,omitempty" cborgen:"references,omitempty"`
26
+
ReplyTo *string `json:"replyTo,omitempty" cborgen:"replyTo,omitempty"`
25
27
}
+6
-4
api/tangled/pullcomment.go
+6
-4
api/tangled/pullcomment.go
···
17
17
} //
18
18
// RECORDTYPE: RepoPullComment
19
19
type RepoPullComment struct {
20
-
LexiconTypeID string `json:"$type,const=sh.tangled.repo.pull.comment" cborgen:"$type,const=sh.tangled.repo.pull.comment"`
21
-
Body string `json:"body" cborgen:"body"`
22
-
CreatedAt string `json:"createdAt" cborgen:"createdAt"`
23
-
Pull string `json:"pull" cborgen:"pull"`
20
+
LexiconTypeID string `json:"$type,const=sh.tangled.repo.pull.comment" cborgen:"$type,const=sh.tangled.repo.pull.comment"`
21
+
Body string `json:"body" cborgen:"body"`
22
+
CreatedAt string `json:"createdAt" cborgen:"createdAt"`
23
+
Mentions []string `json:"mentions,omitempty" cborgen:"mentions,omitempty"`
24
+
Pull string `json:"pull" cborgen:"pull"`
25
+
References []string `json:"references,omitempty" cborgen:"references,omitempty"`
24
26
}
+7
-5
api/tangled/repoissue.go
+7
-5
api/tangled/repoissue.go
···
17
17
} //
18
18
// RECORDTYPE: RepoIssue
19
19
type RepoIssue struct {
20
-
LexiconTypeID string `json:"$type,const=sh.tangled.repo.issue" cborgen:"$type,const=sh.tangled.repo.issue"`
21
-
Body *string `json:"body,omitempty" cborgen:"body,omitempty"`
22
-
CreatedAt string `json:"createdAt" cborgen:"createdAt"`
23
-
Repo string `json:"repo" cborgen:"repo"`
24
-
Title string `json:"title" cborgen:"title"`
20
+
LexiconTypeID string `json:"$type,const=sh.tangled.repo.issue" cborgen:"$type,const=sh.tangled.repo.issue"`
21
+
Body *string `json:"body,omitempty" cborgen:"body,omitempty"`
22
+
CreatedAt string `json:"createdAt" cborgen:"createdAt"`
23
+
Mentions []string `json:"mentions,omitempty" cborgen:"mentions,omitempty"`
24
+
References []string `json:"references,omitempty" cborgen:"references,omitempty"`
25
+
Repo string `json:"repo" cborgen:"repo"`
26
+
Title string `json:"title" cborgen:"title"`
25
27
}
+9
appview/db/db.go
+9
appview/db/db.go
···
561
561
email_notifications integer not null default 0
562
562
);
563
563
564
+
create table if not exists reference_links (
565
+
id integer primary key autoincrement,
566
+
from_at text not null,
567
+
to_at text not null,
568
+
unique (from_at, to_at)
569
+
);
570
+
564
571
create table if not exists migrations (
565
572
id integer primary key autoincrement,
566
573
name text unique
···
571
578
create index if not exists idx_notifications_recipient_read on notifications(recipient_did, read);
572
579
create index if not exists idx_stars_created on stars(created);
573
580
create index if not exists idx_stars_repo_at_created on stars(repo_at, created);
581
+
create index if not exists idx_references_from_at on reference_links(from_at);
582
+
create index if not exists idx_references_to_at on reference_links(to_at);
574
583
`)
575
584
if err != nil {
576
585
return nil, err
+73
-18
appview/db/issues.go
+73
-18
appview/db/issues.go
···
10
10
"time"
11
11
12
12
"github.com/bluesky-social/indigo/atproto/syntax"
13
+
"tangled.org/core/api/tangled"
13
14
"tangled.org/core/appview/models"
14
15
"tangled.org/core/appview/pagination"
15
16
)
···
69
70
returning rowid, issue_id
70
71
`, issue.RepoAt, issue.Did, issue.Rkey, newIssueId, issue.Title, issue.Body)
71
72
72
-
return row.Scan(&issue.Id, &issue.IssueId)
73
+
err = row.Scan(&issue.Id, &issue.IssueId)
74
+
if err != nil {
75
+
return fmt.Errorf("scan row: %w", err)
76
+
}
77
+
78
+
if err := putReferences(tx, issue.AtUri(), issue.References); err != nil {
79
+
return fmt.Errorf("put reference_links: %w", err)
80
+
}
81
+
return nil
73
82
}
74
83
75
84
func updateIssue(tx *sql.Tx, issue *models.Issue) error {
···
79
88
set title = ?, body = ?, edited = ?
80
89
where did = ? and rkey = ?
81
90
`, issue.Title, issue.Body, time.Now().Format(time.RFC3339), issue.Did, issue.Rkey)
82
-
return err
91
+
if err != nil {
92
+
return err
93
+
}
94
+
95
+
if err := putReferences(tx, issue.AtUri(), issue.References); err != nil {
96
+
return fmt.Errorf("put reference_links: %w", err)
97
+
}
98
+
return nil
83
99
}
84
100
85
101
func GetIssuesPaginated(e Execer, page pagination.Page, filters ...filter) ([]models.Issue, error) {
···
234
250
}
235
251
}
236
252
253
+
// collect references for each issue
254
+
allReferencs, err := GetReferencesAll(e, FilterIn("from_at", issueAts))
255
+
if err != nil {
256
+
return nil, fmt.Errorf("failed to query reference_links: %w", err)
257
+
}
258
+
for issueAt, references := range allReferencs {
259
+
if issue, ok := issueMap[issueAt.String()]; ok {
260
+
issue.References = references
261
+
}
262
+
}
263
+
237
264
var issues []models.Issue
238
265
for _, i := range issueMap {
239
266
issues = append(issues, *i)
···
323
350
return ids, nil
324
351
}
325
352
326
-
func AddIssueComment(e Execer, c models.IssueComment) (int64, error) {
327
-
result, err := e.Exec(
353
+
func AddIssueComment(tx *sql.Tx, c models.IssueComment) (int64, error) {
354
+
result, err := tx.Exec(
328
355
`insert into issue_comments (
329
356
did,
330
357
rkey,
···
363
390
return 0, err
364
391
}
365
392
393
+
if err := putReferences(tx, c.AtUri(), c.References); err != nil {
394
+
return 0, fmt.Errorf("put reference_links: %w", err)
395
+
}
396
+
366
397
return id, nil
367
398
}
368
399
···
386
417
}
387
418
388
419
func GetIssueComments(e Execer, filters ...filter) ([]models.IssueComment, error) {
389
-
var comments []models.IssueComment
420
+
commentMap := make(map[string]*models.IssueComment)
390
421
391
422
var conditions []string
392
423
var args []any
···
465
496
comment.ReplyTo = &replyTo.V
466
497
}
467
498
468
-
comments = append(comments, comment)
499
+
atUri := comment.AtUri().String()
500
+
commentMap[atUri] = &comment
469
501
}
470
502
471
503
if err = rows.Err(); err != nil {
472
504
return nil, err
473
505
}
474
506
507
+
// collect references for each comments
508
+
commentAts := slices.Collect(maps.Keys(commentMap))
509
+
allReferencs, err := GetReferencesAll(e, FilterIn("from_at", commentAts))
510
+
if err != nil {
511
+
return nil, fmt.Errorf("failed to query reference_links: %w", err)
512
+
}
513
+
for commentAt, references := range allReferencs {
514
+
if comment, ok := commentMap[commentAt.String()]; ok {
515
+
comment.References = references
516
+
}
517
+
}
518
+
519
+
var comments []models.IssueComment
520
+
for _, c := range commentMap {
521
+
comments = append(comments, *c)
522
+
}
523
+
524
+
sort.Slice(comments, func(i, j int) bool {
525
+
return comments[i].Created.After(comments[j].Created)
526
+
})
527
+
475
528
return comments, nil
476
529
}
477
530
478
-
func DeleteIssues(e Execer, filters ...filter) error {
479
-
var conditions []string
480
-
var args []any
481
-
for _, filter := range filters {
482
-
conditions = append(conditions, filter.Condition())
483
-
args = append(args, filter.Arg()...)
531
+
func DeleteIssues(tx *sql.Tx, did, rkey string) error {
532
+
_, err := tx.Exec(
533
+
`delete from issues
534
+
where did = ? and rkey = ?`,
535
+
did,
536
+
rkey,
537
+
)
538
+
if err != nil {
539
+
return fmt.Errorf("delete issue: %w", err)
484
540
}
485
541
486
-
whereClause := ""
487
-
if conditions != nil {
488
-
whereClause = " where " + strings.Join(conditions, " and ")
542
+
uri := syntax.ATURI(fmt.Sprintf("at://%s/%s/%s", did, tangled.RepoIssueNSID, rkey))
543
+
err = deleteReferences(tx, uri)
544
+
if err != nil {
545
+
return fmt.Errorf("delete reference_links: %w", err)
489
546
}
490
547
491
-
query := fmt.Sprintf(`delete from issues %s`, whereClause)
492
-
_, err := e.Exec(query, args...)
493
-
return err
548
+
return nil
494
549
}
495
550
496
551
func CloseIssues(e Execer, filters ...filter) error {
+31
-5
appview/db/pulls.go
+31
-5
appview/db/pulls.go
···
432
432
submissionIds := slices.Collect(maps.Keys(submissionMap))
433
433
comments, err := GetPullComments(e, FilterIn("submission_id", submissionIds))
434
434
if err != nil {
435
-
return nil, err
435
+
return nil, fmt.Errorf("failed to get pull comments: %w", err)
436
436
}
437
437
for _, comment := range comments {
438
438
if submission, ok := submissionMap[comment.SubmissionId]; ok {
···
492
492
}
493
493
defer rows.Close()
494
494
495
-
var comments []models.PullComment
495
+
commentMap := make(map[string]*models.PullComment)
496
496
for rows.Next() {
497
497
var comment models.PullComment
498
498
var createdAt string
···
514
514
comment.Created = t
515
515
}
516
516
517
-
comments = append(comments, comment)
517
+
atUri := comment.AtUri().String()
518
+
commentMap[atUri] = &comment
518
519
}
519
520
520
521
if err := rows.Err(); err != nil {
521
522
return nil, err
522
523
}
523
524
525
+
// collect references for each comments
526
+
commentAts := slices.Collect(maps.Keys(commentMap))
527
+
allReferencs, err := GetReferencesAll(e, FilterIn("from_at", commentAts))
528
+
if err != nil {
529
+
return nil, fmt.Errorf("failed to query reference_links: %w", err)
530
+
}
531
+
for commentAt, references := range allReferencs {
532
+
if comment, ok := commentMap[commentAt.String()]; ok {
533
+
comment.References = references
534
+
}
535
+
}
536
+
537
+
var comments []models.PullComment
538
+
for _, c := range commentMap {
539
+
comments = append(comments, *c)
540
+
}
541
+
542
+
sort.Slice(comments, func(i, j int) bool {
543
+
return comments[i].Created.Before(comments[j].Created)
544
+
})
545
+
524
546
return comments, nil
525
547
}
526
548
···
600
622
return pulls, nil
601
623
}
602
624
603
-
func NewPullComment(e Execer, comment *models.PullComment) (int64, error) {
625
+
func NewPullComment(tx *sql.Tx, comment *models.PullComment) (int64, error) {
604
626
query := `insert into pull_comments (owner_did, repo_at, submission_id, comment_at, pull_id, body) values (?, ?, ?, ?, ?, ?)`
605
-
res, err := e.Exec(
627
+
res, err := tx.Exec(
606
628
query,
607
629
comment.OwnerDid,
608
630
comment.RepoAt,
···
618
640
i, err := res.LastInsertId()
619
641
if err != nil {
620
642
return 0, err
643
+
}
644
+
645
+
if err := putReferences(tx, comment.AtUri(), comment.References); err != nil {
646
+
return 0, fmt.Errorf("put reference_links: %w", err)
621
647
}
622
648
623
649
return i, nil
+93
-14
appview/db/reference.go
+93
-14
appview/db/reference.go
···
10
10
"tangled.org/core/appview/models"
11
11
)
12
12
13
-
// FindReferences resolves refLinks to Issue/PR/IssueComment/PullComment ATURIs.
13
+
// ValidateReferenceLinks resolves refLinks to Issue/PR/IssueComment/PullComment ATURIs.
14
14
// It will ignore missing refLinks.
15
-
func FindReferences(e Execer, refLinks []models.ReferenceLink) ([]syntax.ATURI, error) {
15
+
func ValidateReferenceLinks(e Execer, refLinks []models.ReferenceLink) ([]syntax.ATURI, error) {
16
16
var (
17
17
issueRefs []models.ReferenceLink
18
18
pullRefs []models.ReferenceLink
···
27
27
}
28
28
issueUris, err := findIssueReferences(e, issueRefs)
29
29
if err != nil {
30
-
return nil, err
30
+
return nil, fmt.Errorf("find issue references: %w", err)
31
31
}
32
32
pullUris, err := findPullReferences(e, pullRefs)
33
33
if err != nil {
34
-
return nil, err
34
+
return nil, fmt.Errorf("find pull references: %w", err)
35
35
}
36
36
37
37
return append(issueUris, pullUris...), nil
···
101
101
}
102
102
uris = append(uris, uri)
103
103
}
104
+
if err := rows.Err(); err != nil {
105
+
return nil, fmt.Errorf("iterate rows: %w", err)
106
+
}
107
+
104
108
return uris, nil
105
109
}
106
110
···
120
124
)
121
125
select
122
126
p.owner_did, p.rkey,
123
-
c.owner_did, c.rkey
127
+
c.comment_at
124
128
from input inp
125
129
join repos r
126
130
on r.did = inp.owner_did
···
146
150
for rows.Next() {
147
151
// Scan rows
148
152
var pullOwner, pullRkey string
149
-
var commentOwner, commentRkey sql.NullString
153
+
var commentUri sql.NullString
150
154
var uri syntax.ATURI
151
-
if err := rows.Scan(&pullOwner, &pullRkey, &commentOwner, &commentRkey); err != nil {
155
+
if err := rows.Scan(&pullOwner, &pullRkey, &commentUri); err != nil {
152
156
return nil, err
153
157
}
154
-
if commentOwner.Valid && commentRkey.Valid {
155
-
uri = syntax.ATURI(fmt.Sprintf(
156
-
"at://%s/%s/%s",
157
-
commentOwner.String,
158
-
tangled.RepoPullCommentNSID,
159
-
commentRkey.String,
160
-
))
158
+
if commentUri.Valid {
159
+
// no-op
160
+
uri = syntax.ATURI(commentUri.String)
161
161
} else {
162
162
uri = syntax.ATURI(fmt.Sprintf(
163
163
"at://%s/%s/%s",
···
170
170
}
171
171
return uris, nil
172
172
}
173
+
174
+
func putReferences(tx *sql.Tx, fromAt syntax.ATURI, references []syntax.ATURI) error {
175
+
fmt.Println("insering references", references)
176
+
err := deleteReferences(tx, fromAt)
177
+
if err != nil {
178
+
return fmt.Errorf("delete old reference_links: %w", err)
179
+
}
180
+
if len(references) == 0 {
181
+
return nil
182
+
}
183
+
184
+
values := make([]string, 0, len(references))
185
+
args := make([]any, 0, len(references)*2)
186
+
for _, ref := range references {
187
+
values = append(values, "(?, ?)")
188
+
args = append(args, fromAt, ref)
189
+
}
190
+
_, err = tx.Exec(
191
+
fmt.Sprintf(
192
+
`insert into reference_links (from_at, to_at)
193
+
values %s`,
194
+
strings.Join(values, ","),
195
+
),
196
+
args...,
197
+
)
198
+
if err != nil {
199
+
return fmt.Errorf("insert new reference_links: %w", err)
200
+
}
201
+
return nil
202
+
}
203
+
204
+
func deleteReferences(tx *sql.Tx, fromAt syntax.ATURI) error {
205
+
_, err := tx.Exec(`delete from reference_links where from_at = ?`, fromAt)
206
+
return err
207
+
}
208
+
209
+
func GetReferencesAll(e Execer, filters ...filter) (map[syntax.ATURI][]syntax.ATURI, error) {
210
+
var (
211
+
conditions []string
212
+
args []any
213
+
)
214
+
for _, filter := range filters {
215
+
conditions = append(conditions, filter.Condition())
216
+
args = append(args, filter.Arg()...)
217
+
}
218
+
219
+
whereClause := ""
220
+
if conditions != nil {
221
+
whereClause = " where " + strings.Join(conditions, " and ")
222
+
}
223
+
224
+
rows, err := e.Query(
225
+
fmt.Sprintf(
226
+
`select from_at, to_at from reference_links %s`,
227
+
whereClause,
228
+
),
229
+
args...,
230
+
)
231
+
if err != nil {
232
+
return nil, fmt.Errorf("query reference_links: %w", err)
233
+
}
234
+
defer rows.Close()
235
+
236
+
result := make(map[syntax.ATURI][]syntax.ATURI)
237
+
238
+
for rows.Next() {
239
+
var from, to syntax.ATURI
240
+
if err := rows.Scan(&from, &to); err != nil {
241
+
return nil, fmt.Errorf("scan row: %w", err)
242
+
}
243
+
244
+
result[from] = append(result[from], to)
245
+
}
246
+
if err := rows.Err(); err != nil {
247
+
return nil, fmt.Errorf("iterate rows: %w", err)
248
+
}
249
+
250
+
return result, nil
251
+
}
+22
-5
appview/ingester.go
+22
-5
appview/ingester.go
···
841
841
return nil
842
842
843
843
case jmodels.CommitOperationDelete:
844
+
tx, err := ddb.BeginTx(ctx, nil)
845
+
if err != nil {
846
+
l.Error("failed to begin transaction", "err", err)
847
+
return err
848
+
}
849
+
defer tx.Rollback()
850
+
844
851
if err := db.DeleteIssues(
845
-
ddb,
846
-
db.FilterEq("did", did),
847
-
db.FilterEq("rkey", rkey),
852
+
tx,
853
+
did,
854
+
rkey,
848
855
); err != nil {
849
856
l.Error("failed to delete", "err", err)
850
857
return fmt.Errorf("failed to delete issue record: %w", err)
858
+
}
859
+
if err := tx.Commit(); err != nil {
860
+
l.Error("failed to commit txn", "err", err)
861
+
return err
851
862
}
852
863
853
864
return nil
···
888
899
return fmt.Errorf("failed to validate comment: %w", err)
889
900
}
890
901
891
-
_, err = db.AddIssueComment(ddb, *comment)
902
+
tx, err := ddb.Begin()
903
+
if err != nil {
904
+
return fmt.Errorf("failed to start transaction: %w", err)
905
+
}
906
+
defer tx.Rollback()
907
+
908
+
_, err = db.AddIssueComment(tx, *comment)
892
909
if err != nil {
893
910
return fmt.Errorf("failed to create issue comment: %w", err)
894
911
}
895
912
896
-
return nil
913
+
return tx.Commit()
897
914
898
915
case jmodels.CommitOperationDelete:
899
916
if err := db.DeleteIssueComments(
+55
-19
appview/issues/issues.go
+55
-19
appview/issues/issues.go
···
241
241
}
242
242
l = l.With("did", issue.Did, "rkey", issue.Rkey)
243
243
244
+
tx, err := rp.db.Begin()
245
+
if err != nil {
246
+
l.Error("failed to start transaction", "err", err)
247
+
rp.pages.Notice(w, "issue-comment", "Failed to create comment, try again later.")
248
+
return
249
+
}
250
+
defer tx.Rollback()
251
+
244
252
// delete from PDS
245
253
client, err := rp.oauth.AuthorizedClient(r)
246
254
if err != nil {
···
261
269
}
262
270
263
271
// delete from db
264
-
if err := db.DeleteIssues(rp.db, db.FilterEq("id", issue.Id)); err != nil {
272
+
if err := db.DeleteIssues(tx, issue.Did, issue.Rkey); err != nil {
265
273
l.Error("failed to delete issue", "err", err)
266
274
rp.pages.Notice(w, noticeId, "Failed to delete issue.")
267
275
return
268
276
}
277
+
tx.Commit()
269
278
270
279
rp.notifier.DeleteIssue(r.Context(), issue)
271
280
···
402
411
replyTo = &replyToUri
403
412
}
404
413
405
-
mentions, _ := rp.refResolver.Resolve(r.Context(), body)
414
+
mentions, references := rp.refResolver.Resolve(r.Context(), body)
406
415
407
416
comment := models.IssueComment{
408
-
Did: user.Did,
409
-
Rkey: tid.TID(),
410
-
IssueAt: issue.AtUri().String(),
411
-
ReplyTo: replyTo,
412
-
Body: body,
413
-
Created: time.Now(),
417
+
Did: user.Did,
418
+
Rkey: tid.TID(),
419
+
IssueAt: issue.AtUri().String(),
420
+
ReplyTo: replyTo,
421
+
Body: body,
422
+
Created: time.Now(),
423
+
Mentions: mentions,
424
+
References: references,
414
425
}
415
426
if err = rp.validator.ValidateIssueComment(&comment); err != nil {
416
427
l.Error("failed to validate comment", "err", err)
···
447
458
}
448
459
}()
449
460
450
-
commentId, err := db.AddIssueComment(rp.db, comment)
461
+
tx, err := rp.db.Begin()
462
+
if err != nil {
463
+
l.Error("failed to start transaction", "err", err)
464
+
rp.pages.Notice(w, "issue-comment", "Failed to create comment, try again later.")
465
+
return
466
+
}
467
+
defer tx.Rollback()
468
+
469
+
commentId, err := db.AddIssueComment(tx, comment)
451
470
if err != nil {
452
471
l.Error("failed to create comment", "err", err)
453
472
rp.pages.Notice(w, "issue-comment", "Failed to create comment.")
454
473
return
455
474
}
475
+
err = tx.Commit()
476
+
if err != nil {
477
+
l.Error("failed to commit transaction", "err", err)
478
+
rp.pages.Notice(w, "issue-comment", "Failed to create comment, try again later.")
479
+
return
480
+
}
456
481
457
482
// reset atUri to make rollback a no-op
458
483
atUri = ""
···
569
594
newComment.Edited = &now
570
595
record := newComment.AsRecord()
571
596
572
-
_, err = db.AddIssueComment(rp.db, newComment)
597
+
tx, err := rp.db.Begin()
598
+
if err != nil {
599
+
l.Error("failed to start transaction", "err", err)
600
+
rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.")
601
+
return
602
+
}
603
+
defer tx.Rollback()
604
+
605
+
_, err = db.AddIssueComment(tx, newComment)
573
606
if err != nil {
574
607
l.Error("failed to perferom update-description query", "err", err)
575
608
rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.")
576
609
return
577
610
}
611
+
tx.Commit()
578
612
579
613
// rkey is optional, it was introduced later
580
614
if newComment.Rkey != "" {
···
881
915
})
882
916
case http.MethodPost:
883
917
body := r.FormValue("body")
884
-
mentions, _ := rp.refResolver.Resolve(r.Context(), body)
918
+
mentions, references := rp.refResolver.Resolve(r.Context(), body)
885
919
886
920
issue := &models.Issue{
887
-
RepoAt: f.RepoAt(),
888
-
Rkey: tid.TID(),
889
-
Title: r.FormValue("title"),
890
-
Body: body,
891
-
Open: true,
892
-
Did: user.Did,
893
-
Created: time.Now(),
894
-
Repo: &f.Repo,
921
+
RepoAt: f.RepoAt(),
922
+
Rkey: tid.TID(),
923
+
Title: r.FormValue("title"),
924
+
Body: body,
925
+
Open: true,
926
+
Did: user.Did,
927
+
Created: time.Now(),
928
+
Mentions: mentions,
929
+
References: references,
930
+
Repo: &f.Repo,
895
931
}
896
932
897
933
if err := rp.validator.ValidateIssue(issue); err != nil {
+64
-28
appview/models/issue.go
+64
-28
appview/models/issue.go
···
10
10
)
11
11
12
12
type Issue struct {
13
-
Id int64
14
-
Did string
15
-
Rkey string
16
-
RepoAt syntax.ATURI
17
-
IssueId int
18
-
Created time.Time
19
-
Edited *time.Time
20
-
Deleted *time.Time
21
-
Title string
22
-
Body string
23
-
Open bool
13
+
Id int64
14
+
Did string
15
+
Rkey string
16
+
RepoAt syntax.ATURI
17
+
IssueId int
18
+
Created time.Time
19
+
Edited *time.Time
20
+
Deleted *time.Time
21
+
Title string
22
+
Body string
23
+
Open bool
24
+
Mentions []syntax.DID
25
+
References []syntax.ATURI
24
26
25
27
// optionally, populate this when querying for reverse mappings
26
28
// like comment counts, parent repo etc.
···
34
36
}
35
37
36
38
func (i *Issue) AsRecord() tangled.RepoIssue {
39
+
mentions := make([]string, len(i.Mentions))
40
+
for i, did := range i.Mentions {
41
+
mentions[i] = string(did)
42
+
}
43
+
references := make([]string, len(i.References))
44
+
for i, uri := range i.References {
45
+
references[i] = string(uri)
46
+
}
37
47
return tangled.RepoIssue{
38
-
Repo: i.RepoAt.String(),
39
-
Title: i.Title,
40
-
Body: &i.Body,
41
-
CreatedAt: i.Created.Format(time.RFC3339),
48
+
Repo: i.RepoAt.String(),
49
+
Title: i.Title,
50
+
Body: &i.Body,
51
+
Mentions: mentions,
52
+
References: references,
53
+
CreatedAt: i.Created.Format(time.RFC3339),
42
54
}
43
55
}
44
56
···
161
173
}
162
174
163
175
type IssueComment struct {
164
-
Id int64
165
-
Did string
166
-
Rkey string
167
-
IssueAt string
168
-
ReplyTo *string
169
-
Body string
170
-
Created time.Time
171
-
Edited *time.Time
172
-
Deleted *time.Time
176
+
Id int64
177
+
Did string
178
+
Rkey string
179
+
IssueAt string
180
+
ReplyTo *string
181
+
Body string
182
+
Created time.Time
183
+
Edited *time.Time
184
+
Deleted *time.Time
185
+
Mentions []syntax.DID
186
+
References []syntax.ATURI
173
187
}
174
188
175
189
func (i *IssueComment) AtUri() syntax.ATURI {
···
177
191
}
178
192
179
193
func (i *IssueComment) AsRecord() tangled.RepoIssueComment {
194
+
mentions := make([]string, len(i.Mentions))
195
+
for i, did := range i.Mentions {
196
+
mentions[i] = string(did)
197
+
}
198
+
references := make([]string, len(i.References))
199
+
for i, uri := range i.References {
200
+
references[i] = string(uri)
201
+
}
180
202
return tangled.RepoIssueComment{
181
-
Body: i.Body,
182
-
Issue: i.IssueAt,
183
-
CreatedAt: i.Created.Format(time.RFC3339),
184
-
ReplyTo: i.ReplyTo,
203
+
Body: i.Body,
204
+
Issue: i.IssueAt,
205
+
CreatedAt: i.Created.Format(time.RFC3339),
206
+
ReplyTo: i.ReplyTo,
207
+
Mentions: mentions,
208
+
References: references,
185
209
}
186
210
}
187
211
···
205
229
return nil, err
206
230
}
207
231
232
+
i := record
233
+
mentions := make([]syntax.DID, len(record.Mentions))
234
+
for i, did := range record.Mentions {
235
+
mentions[i] = syntax.DID(did)
236
+
}
237
+
references := make([]syntax.ATURI, len(record.References))
238
+
for i, uri := range i.References {
239
+
references[i] = syntax.ATURI(uri)
240
+
}
241
+
208
242
comment := IssueComment{
209
243
Did: ownerDid,
210
244
Rkey: rkey,
···
212
246
IssueAt: record.Issue,
213
247
ReplyTo: record.ReplyTo,
214
248
Created: created,
249
+
Mentions: mentions,
250
+
References: references,
215
251
}
216
252
217
253
return &comment, nil
+26
appview/models/pull.go
+26
appview/models/pull.go
···
148
148
Body string
149
149
150
150
// meta
151
+
Mentions []syntax.DID
152
+
References []syntax.ATURI
153
+
154
+
// meta
151
155
Created time.Time
152
156
}
157
+
158
+
func (p *PullComment) AtUri() syntax.ATURI {
159
+
return syntax.ATURI(p.CommentAt)
160
+
}
161
+
162
+
// func (p *PullComment) AsRecord() tangled.RepoPullComment {
163
+
// mentions := make([]string, len(p.Mentions))
164
+
// for i, did := range p.Mentions {
165
+
// mentions[i] = string(did)
166
+
// }
167
+
// references := make([]string, len(p.References))
168
+
// for i, uri := range p.References {
169
+
// references[i] = string(uri)
170
+
// }
171
+
// return tangled.RepoPullComment{
172
+
// Pull: p.PullAt,
173
+
// Body: p.Body,
174
+
// Mentions: mentions,
175
+
// References: references,
176
+
// CreatedAt: p.Created.Format(time.RFC3339),
177
+
// }
178
+
// }
153
179
154
180
func (p *Pull) LastRoundNumber() int {
155
181
return len(p.Submissions) - 1
+3
-1
appview/pulls/pulls.go
+3
-1
appview/pulls/pulls.go
···
733
733
return
734
734
}
735
735
736
-
mentions, _ := s.refResolver.Resolve(r.Context(), body)
736
+
mentions, references := s.refResolver.Resolve(r.Context(), body)
737
737
738
738
// Start a transaction
739
739
tx, err := s.db.BeginTx(r.Context(), nil)
···
777
777
Body: body,
778
778
CommentAt: atResp.Uri,
779
779
SubmissionId: pull.Submissions[roundNumber].ID,
780
+
Mentions: mentions,
781
+
References: references,
780
782
}
781
783
782
784
// Create the pull comment in the database with the commentAt field
+2
-2
appview/refresolver/resolver.go
+2
-2
appview/refresolver/resolver.go
···
34
34
}
35
35
36
36
func (r *Resolver) Resolve(ctx context.Context, source string) ([]syntax.DID, []syntax.ATURI) {
37
-
l := r.logger.With("method", "find_references")
37
+
l := r.logger.With("method", "Resolve")
38
38
rawMentions, rawRefs := markup.FindReferences(r.config.Core.AppviewHost, source)
39
39
l.Debug("found possible references", "mentions", rawMentions, "refs", rawRefs)
40
40
idents := r.idResolver.ResolveIdents(ctx, rawMentions)
···
55
55
rawRef.Handle = string(ident.DID)
56
56
resolvedRefs = append(resolvedRefs, rawRef)
57
57
}
58
-
aturiRefs, err := db.FindReferences(r.execer, resolvedRefs)
58
+
aturiRefs, err := db.ValidateReferenceLinks(r.execer, resolvedRefs)
59
59
if err != nil {
60
60
l.Error("failed running query", "err", err)
61
61
}
+14
lexicons/issue/comment.json
+14
lexicons/issue/comment.json
···
29
29
"replyTo": {
30
30
"type": "string",
31
31
"format": "at-uri"
32
+
},
33
+
"mentions": {
34
+
"type": "array",
35
+
"items": {
36
+
"type": "string",
37
+
"format": "did"
38
+
}
39
+
},
40
+
"references": {
41
+
"type": "array",
42
+
"items": {
43
+
"type": "string",
44
+
"format": "at-uri"
45
+
}
32
46
}
33
47
}
34
48
}
+14
lexicons/issue/issue.json
+14
lexicons/issue/issue.json
···
24
24
"createdAt": {
25
25
"type": "string",
26
26
"format": "datetime"
27
+
},
28
+
"mentions": {
29
+
"type": "array",
30
+
"items": {
31
+
"type": "string",
32
+
"format": "did"
33
+
}
34
+
},
35
+
"references": {
36
+
"type": "array",
37
+
"items": {
38
+
"type": "string",
39
+
"format": "at-uri"
40
+
}
27
41
}
28
42
}
29
43
}
+14
lexicons/pulls/comment.json
+14
lexicons/pulls/comment.json
···
25
25
"createdAt": {
26
26
"type": "string",
27
27
"format": "datetime"
28
+
},
29
+
"mentions": {
30
+
"type": "array",
31
+
"items": {
32
+
"type": "string",
33
+
"format": "did"
34
+
}
35
+
},
36
+
"references": {
37
+
"type": "array",
38
+
"items": {
39
+
"type": "string",
40
+
"format": "at-uri"
41
+
}
28
42
}
29
43
}
30
44
}