Files
gocqlx/qb/insert.go
Josh Giles 12d360a0c3 Support for literals in INSERT and UPDATE and comparisons
The 'value' interface represents a CQL value for use in a comparison,
update, or intitialization operation. A consistent interface for this
allows us to easily support specifying default-named, custom-named,
literal, and evaluated-function values in all these contexts.

Parameters to Func should probably also be values to support full
composition, but that would be a breaking change because Func's
properties are exposed.

The value interface could itself be exposed if we wanted to allow
clients to pass their own values to SetValue, etc, but for now it is a
package-internal abstraction.

BLA
2018-04-20 14:52:47 +02:00

133 lines
2.9 KiB
Go

// Copyright (C) 2017 ScyllaDB
// Use of this source code is governed by a ALv2-style
// license that can be found in the LICENSE file.
package qb
// INSERT reference:
// https://cassandra.apache.org/doc/latest/cql/dml.html#insert
import (
"bytes"
)
// initializer specifies an value for a column in an insert operation.
type initializer struct {
column string
value value
}
// InsertBuilder builds CQL INSERT statements.
type InsertBuilder struct {
table string
columns []initializer
unique bool
using using
}
// Insert returns a new InsertBuilder with the given table name.
func Insert(table string) *InsertBuilder {
return &InsertBuilder{
table: table,
}
}
// ToCql builds the query into a CQL string and named args.
func (b *InsertBuilder) ToCql() (stmt string, names []string) {
cql := bytes.Buffer{}
cql.WriteString("INSERT ")
cql.WriteString("INTO ")
cql.WriteString(b.table)
cql.WriteByte(' ')
cql.WriteByte('(')
for i, c := range b.columns {
cql.WriteString(c.column)
if i < len(b.columns)-1 {
cql.WriteByte(',')
}
}
cql.WriteString(") ")
cql.WriteString("VALUES (")
for i, c := range b.columns {
names = append(names, c.value.writeCql(&cql)...)
if i < len(b.columns)-1 {
cql.WriteByte(',')
}
}
cql.WriteString(") ")
if b.unique {
cql.WriteString("IF NOT EXISTS ")
}
names = append(names, b.using.writeCql(&cql)...)
stmt = cql.String()
return
}
// Into sets the INTO clause of the query.
func (b *InsertBuilder) Into(table string) *InsertBuilder {
b.table = table
return b
}
// Columns adds insert columns to the query.
func (b *InsertBuilder) Columns(columns ...string) *InsertBuilder {
for _, c := range columns {
b.columns = append(b.columns, initializer{
column: c,
value: param(c),
})
}
return b
}
// NamedColumn adds an insert column with a custom parameter name.
func (b *InsertBuilder) NamedColumn(column, name string) *InsertBuilder {
b.columns = append(b.columns, initializer{
column: column,
value: param(name),
})
return b
}
// LitColumn adds an insert column with a literal value to the query.
func (b *InsertBuilder) LitColumn(column, literal string) *InsertBuilder {
b.columns = append(b.columns, initializer{
column: column,
value: lit(literal),
})
return b
}
// FuncColumn adds an insert column initialized by evaluating a CQL function.
func (b *InsertBuilder) FuncColumn(column string, fn *Func) *InsertBuilder {
b.columns = append(b.columns, initializer{
column: column,
value: fn,
})
return b
}
// Unique sets a IF NOT EXISTS clause on the query.
func (b *InsertBuilder) Unique() *InsertBuilder {
b.unique = true
return b
}
// Timestamp sets a USING TIMESTAMP clause on the query.
func (b *InsertBuilder) Timestamp() *InsertBuilder {
b.using.timestamp = true
return b
}
// TTL sets a USING TTL clause on the query.
func (b *InsertBuilder) TTL() *InsertBuilder {
b.using.ttl = true
return b
}