package processing import "strings" // LooksLikeMySQLTupleLine reports whether line starts a mysqldump VALUES tuple. func LooksLikeMySQLTupleLine(line string) bool { s := strings.TrimLeft(line, " \t") return strings.HasPrefix(s, "(") } // ParseMySQLTupleFields parses all fields from the first (...) tuple on the line. func ParseMySQLTupleFields(line string) []string { return ParseMySQLTupleFieldsN(line, 0) } // ParseMySQLTupleFieldsN parses up to maxFields (0 = all) from the first (...) tuple. func ParseMySQLTupleFieldsN(line string, maxFields int) []string { start := strings.Index(line, "(") if start < 0 { return nil } body := line[start+1:] var out []string for i := 0; i < len(body); { if maxFields > 0 && len(out) >= maxFields { break } for i < len(body) && (body[i] == ' ' || body[i] == '\t' || body[i] == ',') { i++ } if i >= len(body) || body[i] == ')' { break } if body[i] == '\'' { i++ var b strings.Builder for i < len(body) { ch := body[i] if ch == '\\' && i+1 < len(body) { b.WriteByte(body[i+1]) i += 2 continue } if ch == '\'' { if i+1 < len(body) && body[i+1] == '\'' { b.WriteByte('\'') i += 2 continue } i++ break } b.WriteByte(ch) i++ } out = append(out, b.String()) continue } j := i for j < len(body) && body[j] != ',' && body[j] != ')' { j++ } out = append(out, strings.TrimSpace(body[i:j])) i = j } return out }