+11
-2
server/handle_repo_apply_writes.go
+11
-2
server/handle_repo_apply_writes.go
···
20
20
Value *MarshalableMap `json:"value,omitempty"`
21
21
}
22
22
23
+
type ComAtprotoRepoApplyWritesResponse struct {
24
+
Commit RepoCommit `json:"commit"`
25
+
Results []ApplyWriteResult `json:"results"`
26
+
}
27
+
23
28
func (s *Server) handleApplyWrites(e echo.Context) error {
24
29
repo := e.Get("repo").(*models.RepoActor)
25
30
···
49
54
})
50
55
}
51
56
52
-
if err := s.repoman.applyWrites(repo.Repo, ops, req.SwapCommit); err != nil {
57
+
results, err := s.repoman.applyWrites(repo.Repo, ops, req.SwapCommit)
58
+
if err != nil {
53
59
s.logger.Error("error applying writes", "error", err)
54
60
return helpers.ServerError(e, nil)
55
61
}
56
62
57
-
return nil
63
+
return e.JSON(200, ComAtprotoRepoApplyWritesResponse{
64
+
Commit: *results[0].Commit,
65
+
Results: results,
66
+
})
58
67
}
+5
-2
server/handle_repo_create_record.go
+5
-2
server/handle_repo_create_record.go
···
40
40
optype = OpTypeUpdate
41
41
}
42
42
43
-
if err := s.repoman.applyWrites(repo.Repo, []Op{
43
+
results, err := s.repoman.applyWrites(repo.Repo, []Op{
44
44
{
45
45
Type: optype,
46
46
Collection: req.Collection,
···
49
49
Record: &req.Record,
50
50
SwapRecord: req.SwapRecord,
51
51
},
52
-
}, req.SwapCommit); err != nil {
52
+
}, req.SwapCommit)
53
+
if err != nil {
53
54
s.logger.Error("error applying writes", "error", err)
54
55
return helpers.ServerError(e, nil)
55
56
}
57
+
58
+
return e.JSON(200, results[0])
56
59
57
60
return nil
58
61
}
+4
-3
server/handle_repo_put_record.go
+4
-3
server/handle_repo_put_record.go
···
40
40
optype = OpTypeUpdate
41
41
}
42
42
43
-
if err := s.repoman.applyWrites(repo.Repo, []Op{
43
+
results, err := s.repoman.applyWrites(repo.Repo, []Op{
44
44
{
45
45
Type: optype,
46
46
Collection: req.Collection,
···
49
49
Record: &req.Record,
50
50
SwapRecord: req.SwapRecord,
51
51
},
52
-
}, req.SwapCommit); err != nil {
52
+
}, req.SwapCommit)
53
+
if err != nil {
53
54
s.logger.Error("error applying writes", "error", err)
54
55
return helpers.ServerError(e, nil)
55
56
}
56
57
57
-
return nil
58
+
return e.JSON(200, results[0])
58
59
}
+41
-17
server/repo.go
+41
-17
server/repo.go
···
82
82
return nil
83
83
}
84
84
85
+
type ApplyWriteResult struct {
86
+
Uri string `json:"string"`
87
+
Cid string `json:"cid"`
88
+
Commit *RepoCommit `json:"commit"`
89
+
ValidationStatus *string `json:"validationStatus"`
90
+
}
91
+
92
+
type RepoCommit struct {
93
+
Cid string `json:"cid"`
94
+
Rev string `json:"rev"`
95
+
}
96
+
85
97
// TODO make use of swap commit
86
-
func (rm *RepoMan) applyWrites(urepo models.Repo, writes []Op, swapCommit *string) error {
98
+
func (rm *RepoMan) applyWrites(urepo models.Repo, writes []Op, swapCommit *string) ([]ApplyWriteResult, error) {
87
99
rootcid, err := cid.Cast(urepo.Root)
88
100
if err != nil {
89
-
return err
101
+
return nil, err
90
102
}
91
103
92
104
dbs := blockstore.New(urepo.Did, rm.db)
···
96
108
97
109
for i, op := range writes {
98
110
if op.Type != OpTypeCreate && op.Rkey == nil {
99
-
return fmt.Errorf("invalid rkey")
111
+
return nil, fmt.Errorf("invalid rkey")
100
112
} else if op.Rkey == nil {
101
113
op.Rkey = to.StringPtr(rm.clock.Next().String())
102
114
writes[i].Rkey = op.Rkey
···
104
116
105
117
_, err := syntax.ParseRecordKey(*op.Rkey)
106
118
if err != nil {
107
-
return err
119
+
return nil, err
108
120
}
109
121
110
122
switch op.Type {
111
123
case OpTypeCreate:
112
124
nc, err := r.PutRecord(context.TODO(), op.Collection+"/"+*op.Rkey, op.Record)
113
125
if err != nil {
114
-
return err
126
+
return nil, err
115
127
}
116
128
117
129
d, _ := data.MarshalCBOR(*op.Record)
···
126
138
case OpTypeDelete:
127
139
err := r.DeleteRecord(context.TODO(), op.Collection+"/"+*op.Rkey)
128
140
if err != nil {
129
-
return err
141
+
return nil, err
130
142
}
131
143
case OpTypeUpdate:
132
144
nc, err := r.UpdateRecord(context.TODO(), op.Collection+"/"+*op.Rkey, op.Record)
133
145
if err != nil {
134
-
return err
146
+
return nil, err
135
147
}
136
148
137
149
d, _ := data.MarshalCBOR(*op.Record)
···
148
160
149
161
newroot, rev, err := r.Commit(context.TODO(), urepo.SignFor)
150
162
if err != nil {
151
-
return err
163
+
return nil, err
152
164
}
153
165
154
166
buf := new(bytes.Buffer)
···
159
171
})
160
172
161
173
if _, err := carstore.LdWrite(buf, hb); err != nil {
162
-
return err
174
+
return nil, err
163
175
}
164
176
165
177
diffops, err := r.DiffSince(context.TODO(), rootcid)
166
178
if err != nil {
167
-
return err
179
+
return nil, err
168
180
}
169
181
170
182
ops := make([]*atproto.SyncSubscribeRepos_RepoOp, 0, len(diffops))
···
194
206
195
207
blk, err := dbs.Get(context.TODO(), op.NewCid)
196
208
if err != nil {
197
-
return err
209
+
return nil, err
198
210
}
199
211
200
212
if _, err := carstore.LdWrite(buf, blk.Cid().Bytes(), blk.RawData()); err != nil {
201
-
return err
213
+
return nil, err
202
214
}
203
215
}
204
216
205
217
for _, op := range dbs.GetLog() {
206
218
if _, err := carstore.LdWrite(buf, op.Cid().Bytes(), op.RawData()); err != nil {
207
-
return err
219
+
return nil, err
208
220
}
209
221
}
222
+
223
+
var results []ApplyWriteResult
210
224
211
225
var blobs []lexutil.LexLink
212
226
for _, entry := range entries {
···
214
228
Columns: []clause.Column{{Name: "did"}, {Name: "nsid"}, {Name: "rkey"}},
215
229
UpdateAll: true,
216
230
}).Create(&entry).Error; err != nil {
217
-
return err
231
+
return nil, err
218
232
}
219
233
220
234
// we should actually check the type (i.e. delete, create,., update) here but we'll do it later
221
235
cids, err := rm.incrementBlobRefs(urepo, entry.Value)
222
236
if err != nil {
223
-
return err
237
+
return nil, err
224
238
}
225
239
226
240
for _, c := range cids {
227
241
blobs = append(blobs, lexutil.LexLink(c))
228
242
}
243
+
244
+
results = append(results, ApplyWriteResult{
245
+
Uri: "at://" + urepo.Did + "/" + entry.Nsid + "/" + entry.Rkey,
246
+
Cid: entry.Cid,
247
+
Commit: &RepoCommit{
248
+
Cid: newroot.String(),
249
+
Rev: rev,
250
+
},
251
+
ValidationStatus: to.StringPtr("valid"), // TODO: obviously this might not be true atm lol
252
+
})
229
253
}
230
254
231
255
rm.s.evtman.AddEvent(context.TODO(), &events.XRPCStreamEvent{
···
243
267
})
244
268
245
269
if err := dbs.UpdateRepo(context.TODO(), newroot, rev); err != nil {
246
-
return err
270
+
return nil, err
247
271
}
248
272
249
-
return nil
273
+
return results, nil
250
274
}
251
275
252
276
func (rm *RepoMan) getRecordProof(urepo models.Repo, collection, rkey string) (cid.Cid, []blocks.Block, error) {