diff options
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 +} |
