diff options
| author | 2026-03-07 19:37:20 +0800 | |
|---|---|---|
| committer | 2026-03-07 19:37:20 +0800 | |
| commit | 563a4dfb78aaa97febd0763e9f81a740af0dd666 (patch) | |
| tree | f7ede5d05f1363021fa5b1902e9e569c2b274bf1 /refstore/files/batch_apply.go | |
| parent | refstore: Batch should also be staged (diff) | |
| signature | No signature | |
refstore/files: Implement batching
Diffstat (limited to 'refstore/files/batch_apply.go')
| -rw-r--r-- | refstore/files/batch_apply.go | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/refstore/files/batch_apply.go b/refstore/files/batch_apply.go new file mode 100644 index 00000000..4274df0b --- /dev/null +++ b/refstore/files/batch_apply.go @@ -0,0 +1,70 @@ +package files + +import ( + "errors" + + "codeberg.org/lindenii/furgit/refstore" +) + +func (batch *Batch) Apply() ([]refstore.BatchResult, error) { + if batch.closed { + return nil, errors.New("refstore/files: batch already closed") + } + + results := make([]refstore.BatchResult, len(batch.ops)) + seen := make(map[string]struct{}, len(batch.ops)) + + for i, op := range batch.ops { + results[i].Name = op.name + + if _, exists := seen[op.name]; exists { + batch.closed = true + + err := errors.New("refstore/files: duplicate batch operation for " + `"` + op.name + `"`) + for j := i; j < len(results); j++ { + results[j].Name = batch.ops[j].name + results[j].Error = err + } + + return results, err + } + + seen[op.name] = struct{}{} + } + + for i, op := range batch.ops { + tx := &Transaction{ + store: batch.store, + ops: []txOp{op}, + } + + if err := tx.validateOp(op); err != nil { + results[i].Error = err + continue + } + + err := tx.Commit() + if err == nil { + continue + } + + if isBatchRejected(err) { + results[i].Error = err + continue + } + + batch.closed = true + results[i].Error = err + + for j := i + 1; j < len(results); j++ { + results[j].Name = batch.ops[j].name + results[j].Error = err + } + + return results, err + } + + batch.closed = true + + return results, nil +} |
