diff --git a/qb/using.go b/qb/using.go index 7e4cbe0..32a199e 100644 --- a/qb/using.go +++ b/qb/using.go @@ -94,7 +94,7 @@ func (u *using) writeCql(cql *bytes.Buffer) (names []string) { if u.timeout != 0 { writePreamble(cql) - fmt.Fprintf(cql, "TIMEOUT %s ", u.timeout) + fmt.Fprintf(cql, "TIMEOUT %s ", formatDuration(u.timeout)) } else if u.timeoutName != "" { writePreamble(cql) cql.WriteString("TIMEOUT ? ") diff --git a/qb/using_test.go b/qb/using_test.go index fe856b1..69c2665 100644 --- a/qb/using_test.go +++ b/qb/using_test.go @@ -57,6 +57,11 @@ func TestUsing(t *testing.T) { B: new(using).Timeout(time.Second), S: "USING TIMEOUT 1s ", }, + // Timeout faction + { + B: new(using).Timeout(time.Second + 100*time.Millisecond), + S: "USING TIMEOUT 1s100ms ", + }, // TimeoutNamed { B: new(using).TimeoutNamed("to"), diff --git a/qb/utils.go b/qb/utils.go index ffa4ab4..8ffc2a5 100644 --- a/qb/utils.go +++ b/qb/utils.go @@ -6,6 +6,9 @@ package qb import ( "bytes" + "fmt" + "strings" + "time" ) // placeholders returns a string with count ? placeholders joined with commas. @@ -31,3 +34,26 @@ func (cols columns) writeCql(cql *bytes.Buffer) { } } } + +func formatDuration(d time.Duration) string { + // Round the duration to the nearest millisecond + // Extract hours, minutes, seconds, and milliseconds + minutes := d / time.Minute + d %= time.Minute + seconds := d / time.Second + d %= time.Second + milliseconds := d / time.Millisecond + + // Format the duration string + var res []string + if minutes > 0 { + res = append(res, fmt.Sprintf("%dm", minutes)) + } + if seconds > 0 { + res = append(res, fmt.Sprintf("%ds", seconds)) + } + if milliseconds > 0 { + res = append(res, fmt.Sprintf("%dms", milliseconds)) + } + return strings.Join(res, "") +} diff --git a/qb/utils_test.go b/qb/utils_test.go new file mode 100644 index 0000000..d11afb7 --- /dev/null +++ b/qb/utils_test.go @@ -0,0 +1,61 @@ +package qb + +import ( + "testing" + "time" +) + +func TestFormatDuration(t *testing.T) { + tests := []struct { + name string + input time.Duration + expected string + }{ + { + name: "Zero duration", + input: 0, + expected: "", + }, + { + input: 500 * time.Millisecond, + expected: "500ms", + }, + { + input: 10 * time.Second, + expected: "10s", + }, + { + input: 3 * time.Minute, + expected: "3m", + }, + { + input: (2 * time.Minute) + (30 * time.Second), + expected: "2m30s", + }, + { + input: (15 * time.Second) + (250 * time.Millisecond), + expected: "15s250ms", + }, + { + input: (1 * time.Minute) + (45 * time.Second) + (123 * time.Millisecond), + expected: "1m45s123ms", + }, + { + input: (5 * time.Minute) + (1 * time.Second) + (999 * time.Millisecond), + expected: "5m1s999ms", + }, + { + input: (2 * time.Second) + (1500 * time.Millisecond), // 3 seconds, 500ms + expected: "3s500ms", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + actual := formatDuration(tt.input) + if actual != tt.expected { + t.Errorf("got %q, want %q", actual, tt.expected) + } + }) + } +}