package batchfields import ( "regexp" "strings" "unicode/utf8" ) const ( ItemIDLimit = 64 DetailReasonLimit = 512 FailureReasonByteLimit = 4096 ) var mysqlErrorAfterSQL = regexp.MustCompile(`(?i): Error [0-9]{3,5} \([0-9A-Z]{5}\): [^\r\n]{0,160}`) func DetailReason(value string) string { runes := []rune(strings.TrimSpace(value)) if len(runes) > DetailReasonLimit { return string(runes[:DetailReasonLimit]) } return string(runes) } func ItemID(value string) string { if utf8.RuneCountInString(value) > ItemIDLimit { return "" } return value } func FailureReason(value string) string { value = strings.ToValidUTF8(strings.TrimSpace(value), "") upper := strings.ToUpper(value) for _, marker := range []string{": INSERT INTO ", ": UPDATE ", ": SELECT ", ": DELETE FROM "} { if index := strings.Index(upper, marker); index >= 0 { databaseError := mysqlErrorAfterSQL.FindString(value[index+len(marker):]) value = value[:index] + " (SQL omitted)" + databaseError break } } if len(value) <= FailureReasonByteLimit { return value } end := FailureReasonByteLimit - 3 for end > 0 && !utf8.RuneStart(value[end]) { end-- } return value[:end] + "..." }