fix: accept datetime-local history filters
This commit is contained in:
@@ -366,8 +366,8 @@ func normalizeRawFrameQuery(query RawFrameQuery) RawFrameQuery {
|
|||||||
query.Phone = strings.TrimSpace(query.Phone)
|
query.Phone = strings.TrimSpace(query.Phone)
|
||||||
query.DeviceID = strings.TrimSpace(query.DeviceID)
|
query.DeviceID = strings.TrimSpace(query.DeviceID)
|
||||||
query.MessageID = strings.TrimSpace(query.MessageID)
|
query.MessageID = strings.TrimSpace(query.MessageID)
|
||||||
query.DateFrom = strings.TrimSpace(query.DateFrom)
|
query.DateFrom = normalizeDateTimeLiteral(query.DateFrom)
|
||||||
query.DateTo = strings.TrimSpace(query.DateTo)
|
query.DateTo = normalizeDateTimeLiteral(query.DateTo)
|
||||||
if query.Limit <= 0 {
|
if query.Limit <= 0 {
|
||||||
query.Limit = 20
|
query.Limit = 20
|
||||||
}
|
}
|
||||||
@@ -380,8 +380,8 @@ func normalizeLocationQuery(query LocationQuery) LocationQuery {
|
|||||||
query.VIN = strings.TrimSpace(query.VIN)
|
query.VIN = strings.TrimSpace(query.VIN)
|
||||||
query.Phone = strings.TrimSpace(query.Phone)
|
query.Phone = strings.TrimSpace(query.Phone)
|
||||||
query.DeviceID = strings.TrimSpace(query.DeviceID)
|
query.DeviceID = strings.TrimSpace(query.DeviceID)
|
||||||
query.DateFrom = strings.TrimSpace(query.DateFrom)
|
query.DateFrom = normalizeDateTimeLiteral(query.DateFrom)
|
||||||
query.DateTo = strings.TrimSpace(query.DateTo)
|
query.DateTo = normalizeDateTimeLiteral(query.DateTo)
|
||||||
if query.Limit <= 0 {
|
if query.Limit <= 0 {
|
||||||
query.Limit = 20
|
query.Limit = 20
|
||||||
}
|
}
|
||||||
@@ -394,8 +394,8 @@ func normalizeMileagePointQuery(query MileagePointQuery) MileagePointQuery {
|
|||||||
query.VIN = strings.TrimSpace(query.VIN)
|
query.VIN = strings.TrimSpace(query.VIN)
|
||||||
query.Phone = strings.TrimSpace(query.Phone)
|
query.Phone = strings.TrimSpace(query.Phone)
|
||||||
query.DeviceID = strings.TrimSpace(query.DeviceID)
|
query.DeviceID = strings.TrimSpace(query.DeviceID)
|
||||||
query.DateFrom = strings.TrimSpace(query.DateFrom)
|
query.DateFrom = normalizeDateTimeLiteral(query.DateFrom)
|
||||||
query.DateTo = strings.TrimSpace(query.DateTo)
|
query.DateTo = normalizeDateTimeLiteral(query.DateTo)
|
||||||
if query.Limit <= 0 {
|
if query.Limit <= 0 {
|
||||||
query.Limit = 20
|
query.Limit = 20
|
||||||
}
|
}
|
||||||
@@ -482,10 +482,10 @@ func rawFrameWhere(query RawFrameQuery) []string {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if query.DateFrom != "" {
|
if query.DateFrom != "" {
|
||||||
add("ts >= '" + quote(query.DateFrom) + "'")
|
add("ts >= '" + quote(normalizeDateTimeLiteral(query.DateFrom)) + "'")
|
||||||
}
|
}
|
||||||
if query.DateTo != "" {
|
if query.DateTo != "" {
|
||||||
add("ts <= '" + quote(query.DateTo) + "'")
|
add("ts <= '" + quote(normalizeDateTimeLiteral(query.DateTo)) + "'")
|
||||||
}
|
}
|
||||||
return where
|
return where
|
||||||
}
|
}
|
||||||
@@ -511,10 +511,10 @@ func locationWhere(query LocationQuery) []string {
|
|||||||
add("device_id = '" + quote(query.DeviceID) + "'")
|
add("device_id = '" + quote(query.DeviceID) + "'")
|
||||||
}
|
}
|
||||||
if query.DateFrom != "" {
|
if query.DateFrom != "" {
|
||||||
add("ts >= '" + quote(query.DateFrom) + "'")
|
add("ts >= '" + quote(normalizeDateTimeLiteral(query.DateFrom)) + "'")
|
||||||
}
|
}
|
||||||
if query.DateTo != "" {
|
if query.DateTo != "" {
|
||||||
add("ts <= '" + quote(query.DateTo) + "'")
|
add("ts <= '" + quote(normalizeDateTimeLiteral(query.DateTo)) + "'")
|
||||||
}
|
}
|
||||||
return where
|
return where
|
||||||
}
|
}
|
||||||
@@ -540,10 +540,10 @@ func mileagePointWhere(query MileagePointQuery) []string {
|
|||||||
add("device_id = '" + quote(query.DeviceID) + "'")
|
add("device_id = '" + quote(query.DeviceID) + "'")
|
||||||
}
|
}
|
||||||
if query.DateFrom != "" {
|
if query.DateFrom != "" {
|
||||||
add("ts >= '" + quote(query.DateFrom) + "'")
|
add("ts >= '" + quote(normalizeDateTimeLiteral(query.DateFrom)) + "'")
|
||||||
}
|
}
|
||||||
if query.DateTo != "" {
|
if query.DateTo != "" {
|
||||||
add("ts <= '" + quote(query.DateTo) + "'")
|
add("ts <= '" + quote(normalizeDateTimeLiteral(query.DateTo)) + "'")
|
||||||
}
|
}
|
||||||
return where
|
return where
|
||||||
}
|
}
|
||||||
@@ -793,7 +793,7 @@ func parseMessageID(value string) (int64, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func validDateTime(value string) bool {
|
func validDateTime(value string) bool {
|
||||||
value = strings.TrimSpace(value)
|
value = normalizeDateTimeLiteral(value)
|
||||||
if value == "" {
|
if value == "" {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -805,6 +805,14 @@ func validDateTime(value string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func normalizeDateTimeLiteral(value string) string {
|
||||||
|
value = strings.TrimSpace(value)
|
||||||
|
if len(value) == len("2006-01-02T15:04:05") && value[10] == 'T' {
|
||||||
|
return value[:10] + " " + value[11:]
|
||||||
|
}
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
func safeIdentifier(value string) bool {
|
func safeIdentifier(value string) bool {
|
||||||
if value == "" {
|
if value == "" {
|
||||||
return false
|
return false
|
||||||
|
|||||||
@@ -256,6 +256,18 @@ func TestRawFrameHandlerRejectsInvalidLimit(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestParseRawFrameQueryAcceptsDatetimeLocalValues(t *testing.T) {
|
||||||
|
request := httptest.NewRequest(http.MethodGet, "/api/history/raw-frames?dateFrom=2026-07-01T00:00:00&dateTo=2026-07-02T00:00:00", nil)
|
||||||
|
|
||||||
|
query, err := parseRawFrameQuery(request)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("parseRawFrameQuery() error = %v", err)
|
||||||
|
}
|
||||||
|
if query.DateFrom != "2026-07-01 00:00:00" || query.DateTo != "2026-07-02 00:00:00" {
|
||||||
|
t.Fatalf("date range = %q -> %q", query.DateFrom, query.DateTo)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseMessageIDSupportsDecimalAndHex(t *testing.T) {
|
func TestParseMessageIDSupportsDecimalAndHex(t *testing.T) {
|
||||||
for raw, want := range map[string]int64{
|
for raw, want := range map[string]int64{
|
||||||
"512": 512,
|
"512": 512,
|
||||||
@@ -323,8 +335,8 @@ func TestBuildRawFrameSQLUsesLiteralsForTDengine(t *testing.T) {
|
|||||||
VehicleKey: "JT808:013307811350",
|
VehicleKey: "JT808:013307811350",
|
||||||
VIN: "VIN'1",
|
VIN: "VIN'1",
|
||||||
MessageID: "0x0200",
|
MessageID: "0x0200",
|
||||||
DateFrom: "2026-07-01 00:00:00",
|
DateFrom: "2026-07-01T00:00:00",
|
||||||
DateTo: "2026-07-01 23:59:59",
|
DateTo: "2026-07-01T23:59:59",
|
||||||
Limit: 20,
|
Limit: 20,
|
||||||
Offset: 5,
|
Offset: 5,
|
||||||
})
|
})
|
||||||
@@ -336,6 +348,8 @@ func TestBuildRawFrameSQLUsesLiteralsForTDengine(t *testing.T) {
|
|||||||
"vehicle_key = 'JT808:013307811350'",
|
"vehicle_key = 'JT808:013307811350'",
|
||||||
"vin = 'VIN''1'",
|
"vin = 'VIN''1'",
|
||||||
"message_id = 512",
|
"message_id = 512",
|
||||||
|
"ts >= '2026-07-01 00:00:00'",
|
||||||
|
"ts <= '2026-07-01 23:59:59'",
|
||||||
"LIMIT 20 OFFSET 5",
|
"LIMIT 20 OFFSET 5",
|
||||||
} {
|
} {
|
||||||
if !strings.Contains(sqlText, want) {
|
if !strings.Contains(sqlText, want) {
|
||||||
|
|||||||
Reference in New Issue
Block a user