Builder is not in a position to validate the statement and the effort is duplicated when the query is build. The checked errors are simple and do not occur most of the time.
144 lines
2.9 KiB
Go
144 lines
2.9 KiB
Go
package qb
|
|
|
|
// SELECT reference:
|
|
// http://docs.datastax.com/en/dse/5.1/cql/cql/cql_reference/cql_commands/cqlSelect.html
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
)
|
|
|
|
type Order bool
|
|
|
|
const (
|
|
ASC Order = true
|
|
DESC = false
|
|
)
|
|
|
|
type SelectBuilder struct {
|
|
table string
|
|
columns columns
|
|
distinct columns
|
|
where where
|
|
groupBy columns
|
|
orderBy string
|
|
order Order
|
|
limit uint
|
|
limitPerPartition uint
|
|
allowFiltering bool
|
|
}
|
|
|
|
// Select returns a new SelectBuilder with the given table name.
|
|
func Select(table string) *SelectBuilder {
|
|
return &SelectBuilder{
|
|
table: table,
|
|
}
|
|
}
|
|
|
|
func (b *SelectBuilder) ToCql() (stmt string, names []string) {
|
|
cql := bytes.Buffer{}
|
|
|
|
cql.WriteString("SELECT ")
|
|
switch {
|
|
case len(b.distinct) > 0:
|
|
cql.WriteString("DISTINCT ")
|
|
b.distinct.writeCql(&cql)
|
|
case len(b.groupBy) > 0:
|
|
b.groupBy.writeCql(&cql)
|
|
cql.WriteByte(',')
|
|
b.columns.writeCql(&cql)
|
|
case len(b.columns) == 0:
|
|
cql.WriteByte('*')
|
|
default:
|
|
b.columns.writeCql(&cql)
|
|
}
|
|
cql.WriteString(" FROM ")
|
|
cql.WriteString(b.table)
|
|
cql.WriteByte(' ')
|
|
|
|
names = b.where.writeCql(&cql)
|
|
|
|
if len(b.groupBy) > 0 {
|
|
cql.WriteString("GROUP BY ")
|
|
b.groupBy.writeCql(&cql)
|
|
cql.WriteByte(' ')
|
|
}
|
|
|
|
if b.orderBy != "" {
|
|
cql.WriteString("ORDER BY ")
|
|
cql.WriteString(b.orderBy)
|
|
if b.order {
|
|
cql.WriteString(" ASC ")
|
|
} else {
|
|
cql.WriteString(" DESC ")
|
|
}
|
|
}
|
|
|
|
if b.limit != 0 {
|
|
cql.WriteString("LIMIT ")
|
|
cql.WriteString(fmt.Sprint(b.limit))
|
|
cql.WriteByte(' ')
|
|
}
|
|
|
|
if b.limitPerPartition != 0 {
|
|
cql.WriteString("PER PARTITION LIMIT ")
|
|
cql.WriteString(fmt.Sprint(b.limitPerPartition))
|
|
cql.WriteByte(' ')
|
|
}
|
|
|
|
if b.allowFiltering {
|
|
cql.WriteString("ALLOW FILTERING ")
|
|
}
|
|
|
|
stmt = cql.String()
|
|
return
|
|
}
|
|
|
|
// From sets the table to be selected from.
|
|
func (b *SelectBuilder) From(table string) *SelectBuilder {
|
|
b.table = table
|
|
return b
|
|
}
|
|
|
|
func (b *SelectBuilder) Columns(columns ...string) *SelectBuilder {
|
|
b.columns = append(b.columns, columns...)
|
|
return b
|
|
}
|
|
|
|
func (b *SelectBuilder) Distinct(columns... string) *SelectBuilder {
|
|
b.distinct = append(b.distinct, columns...)
|
|
return b
|
|
}
|
|
|
|
func (b *SelectBuilder) Where(w ...Cmp) *SelectBuilder {
|
|
b.where = append(b.where, w...)
|
|
return b
|
|
}
|
|
|
|
// GroupBy sets GROUP BY clause on the query. Columns must be a primary key,
|
|
// this will automatically add the the columns as first selectors.
|
|
func (b *SelectBuilder) GroupBy(columns... string) *SelectBuilder {
|
|
b.groupBy = append(b.groupBy, columns...)
|
|
return b
|
|
}
|
|
|
|
func (b *SelectBuilder) OrderBy(column string, o Order) *SelectBuilder {
|
|
b.orderBy, b.order = column, o
|
|
return b
|
|
}
|
|
|
|
func (b *SelectBuilder) Limit(limit uint) *SelectBuilder {
|
|
b.limit = limit
|
|
return b
|
|
}
|
|
|
|
func (b *SelectBuilder) LimitPerPartition(limit uint) *SelectBuilder {
|
|
b.limitPerPartition = limit
|
|
return b
|
|
}
|
|
|
|
func (b *SelectBuilder) AllowFiltering() *SelectBuilder {
|
|
b.allowFiltering = true
|
|
return b
|
|
}
|