diff --git a/qb/select.go b/qb/select.go index b4680f4..afb5777 100644 --- a/qb/select.go +++ b/qb/select.go @@ -175,6 +175,12 @@ func (b *SelectBuilder) TimeoutNamed(name string) *SelectBuilder { return b } +// ServiceLevel adds a USING SERVICE LEVEL clause with the given name to the query +func (b *SelectBuilder) ServiceLevel(name string) *SelectBuilder { + b.using.ServiceLevel(name) + return b +} + // Where adds an expression to the WHERE clause of the query. Expressions are // ANDed together in the generated CQL. func (b *SelectBuilder) Where(w ...Cmp) *SelectBuilder { diff --git a/qb/select_test.go b/qb/select_test.go index 80df9ca..21f8c0a 100644 --- a/qb/select_test.go +++ b/qb/select_test.go @@ -89,6 +89,17 @@ func TestSelectBuilder(t *testing.T) { S: "SELECT * FROM cycling.cyclist_name WHERE id=? AND firstname>? USING TIMEOUT ? ", N: []string{"expr", "firstname", "to"}, }, + // Add SERVICE LEVEL + { + B: Select("cycling.cyclist_name").Where(w, Gt("firstname")).ServiceLevel("foo"), + S: "SELECT * FROM cycling.cyclist_name WHERE id=? AND firstname>? USING SERVICE LEVEL 'foo' ", + N: []string{"expr", "firstname"}, + }, + { + B: Select("cycling.cyclist_name").Where(w, Gt("firstname")).ServiceLevel("foo's").Timeout(10 * time.Second), + S: "SELECT * FROM cycling.cyclist_name WHERE id=? AND firstname>? USING TIMEOUT 10s AND SERVICE LEVEL 'foo''s' ", + N: []string{"expr", "firstname"}, + }, // Add GROUP BY { B: Select("cycling.cyclist_name").Columns("MAX(stars) as max_stars").GroupBy("id"), diff --git a/qb/using.go b/qb/using.go index 32a199e..b4038e1 100644 --- a/qb/using.go +++ b/qb/using.go @@ -7,6 +7,7 @@ package qb import ( "bytes" "fmt" + "strings" "time" ) @@ -27,6 +28,7 @@ type using struct { ttl int64 timestamp int64 timeout time.Duration + serviceLevel string } func (u *using) TTL(d time.Duration) *using { @@ -68,6 +70,11 @@ func (u *using) TimeoutNamed(name string) *using { return u } +func (u *using) ServiceLevel(name string) *using { + u.serviceLevel = name + return u +} + func (u *using) writeCql(cql *bytes.Buffer) (names []string) { writePreamble := u.preambleWriter() @@ -101,6 +108,11 @@ func (u *using) writeCql(cql *bytes.Buffer) (names []string) { names = append(names, u.timeoutName) } + if u.serviceLevel != "" { + writePreamble(cql) + fmt.Fprintf(cql, "SERVICE LEVEL '%s' ", strings.ReplaceAll(u.serviceLevel, "'", "''")) + } + return } diff --git a/qb/using_test.go b/qb/using_test.go index 69c2665..f2825bc 100644 --- a/qb/using_test.go +++ b/qb/using_test.go @@ -143,6 +143,21 @@ func TestUsing(t *testing.T) { B: new(using).TimestampNamed("ts").Timestamp(time.Date(2005, 5, 5, 0, 0, 0, 0, time.UTC)), S: "USING TIMESTAMP 1115251200000000 ", }, + // ServiceLevel + { + B: new(using).ServiceLevel("foo"), + S: "USING SERVICE LEVEL 'foo' ", + }, + // ServiceLevel with additional Timeout + { + B: new(using).ServiceLevel("foo").Timeout(time.Second), + S: "USING TIMEOUT 1s AND SERVICE LEVEL 'foo' ", + }, + // ServiceLevel with a silly, but legal, name + { + B: new(using).ServiceLevel(`^&*^\!@#&($%^!';[](+`), + S: `USING SERVICE LEVEL '^&*^\!@#&($%^!'';[](+' `, + }, } for _, test := range table {