68 lines
1.5 KiB
Go
68 lines
1.5 KiB
Go
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
|
||
|
|
}
|