(raw string, a []Edit)
| 58 | } |
| 59 | |
| 60 | func Mutate(raw string, a []Edit) (string, error) { |
| 61 | if len(a) == 0 { |
| 62 | return raw, nil |
| 63 | } |
| 64 | |
| 65 | sort.Slice(a, func(i, j int) bool { return a[i].Location > a[j].Location }) |
| 66 | |
| 67 | s := raw |
| 68 | for idx, edit := range a { |
| 69 | start := edit.Location |
| 70 | if start > len(s) || start < 0 { |
| 71 | return "", fmt.Errorf("edit start location is out of bounds") |
| 72 | } |
| 73 | var oldLen int |
| 74 | if edit.OldFunc != nil { |
| 75 | oldLen = edit.OldFunc(s[start:]) |
| 76 | } else { |
| 77 | oldLen = len(edit.Old) |
| 78 | } |
| 79 | |
| 80 | stop := edit.Location + oldLen |
| 81 | if stop > len(s) { |
| 82 | return "", fmt.Errorf("edit stop location is out of bounds") |
| 83 | } |
| 84 | |
| 85 | // If this is not the first edit, (applied backwards), check if |
| 86 | // this edit overlaps the previous one (and is therefore a developer error) |
| 87 | if idx != 0 { |
| 88 | prevEdit := a[idx-1] |
| 89 | if prevEdit.Location < edit.Location+oldLen { |
| 90 | return "", fmt.Errorf("2 edits overlap") |
| 91 | } |
| 92 | } |
| 93 | |
| 94 | s = s[:start] + edit.New + s[stop:] |
| 95 | } |
| 96 | return s, nil |
| 97 | } |
| 98 | |
| 99 | func StripComments(sql string) (string, []string, error) { |
| 100 | s := bufio.NewScanner(strings.NewReader(strings.TrimSpace(sql))) |
no outgoing calls