chore: 并入 iotlcm-worker-svr 历史到 worker-svr/(原提交 96f0f4e)
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
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] + "..."
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package batchfields
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func TestItemIDRejectsOversizedCardIdentifier(t *testing.T) {
|
||||
if got := ItemID(strings.Repeat("9", 65)); got != "" {
|
||||
t.Fatalf("oversized identifier = %q, want empty", got)
|
||||
}
|
||||
if got := ItemID(strings.Repeat("9", 64)); len(got) != 64 {
|
||||
t.Fatalf("64-character identifier = %q", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDetailReasonFitsColumn(t *testing.T) {
|
||||
if got := DetailReason(strings.Repeat("错", 513)); utf8.RuneCountInString(got) != 512 {
|
||||
t.Fatalf("detail reason length = %d", utf8.RuneCountInString(got))
|
||||
}
|
||||
}
|
||||
|
||||
func TestFailureReasonOmitsStatementAndFitsColumn(t *testing.T) {
|
||||
value := "insert failed: INSERT INTO batch_detail VALUES (" + strings.Repeat("错", 30000) + ")"
|
||||
got := FailureReason(value)
|
||||
if strings.Contains(got, "VALUES") || len(got) > FailureReasonByteLimit || !utf8.ValidString(got) {
|
||||
t.Fatalf("unsafe failure reason: %q", got)
|
||||
}
|
||||
got = FailureReason(strings.Repeat("错", 30000))
|
||||
if len(got) > FailureReasonByteLimit || !utf8.ValidString(got) {
|
||||
t.Fatalf("invalid truncated UTF-8 reason")
|
||||
}
|
||||
got = FailureReason("insert detail failed: INSERT INTO batch_detail VALUES ('" + strings.Repeat("9", 1000) + "'): Error 1406 (22001): Data too long for column 'item_id' at row 1")
|
||||
if strings.Contains(got, "VALUES") || !strings.Contains(got, "Error 1406 (22001)") {
|
||||
t.Fatalf("SQL should be removed but database error preserved: %q", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user