transformer: add transformer for unsetting empty values
This commit is contained in:
committed by
Michal Jan Matczuk
parent
504f6523d9
commit
e502c7cc40
@@ -19,6 +19,7 @@ import (
|
||||
"github.com/scylladb/gocqlx/v2/qb"
|
||||
"github.com/scylladb/gocqlx/v2/table"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"gopkg.in/inf.v0"
|
||||
)
|
||||
|
||||
// Running examples locally:
|
||||
@@ -47,6 +48,7 @@ func TestExample(t *testing.T) {
|
||||
pagingEfficientFullTableScan(t, session)
|
||||
|
||||
lwtLock(t, session)
|
||||
unsetEmptyValues(t, session)
|
||||
}
|
||||
|
||||
// This example shows how to use query builders and table models to build
|
||||
@@ -705,6 +707,76 @@ func lwtLock(t *testing.T, session gocqlx.Session) {
|
||||
}
|
||||
}
|
||||
|
||||
// This example shows how to reuse the same insert statement with
|
||||
// partially filled parameters without generating tombstones for empty columns.
|
||||
func unsetEmptyValues(t *testing.T, session gocqlx.Session) {
|
||||
err := session.ExecStmt(`CREATE KEYSPACE IF NOT EXISTS examples WITH replication = {'class': 'SimpleStrategy', 'replication_factor': 1}`)
|
||||
if err != nil {
|
||||
t.Fatal("create keyspace:", err)
|
||||
}
|
||||
|
||||
type Operation struct {
|
||||
ID string
|
||||
ClientID string
|
||||
Type string
|
||||
PaymentID string
|
||||
Fee *inf.Dec
|
||||
}
|
||||
err = session.ExecStmt(`CREATE TABLE IF NOT EXISTS examples.operations (
|
||||
id text PRIMARY KEY,
|
||||
client_id text,
|
||||
type text,
|
||||
payment_id text,
|
||||
fee decimal)`)
|
||||
if err != nil {
|
||||
t.Fatal("create table:", err)
|
||||
}
|
||||
|
||||
insertOperation := qb.Insert("examples.operations").
|
||||
Columns("id", "client_id", "type", "payment_id", "fee")
|
||||
|
||||
// Insert operation with empty paymentID.
|
||||
insertQuery := insertOperation.Query(session).
|
||||
WithBindTransformer(gocqlx.UnsetEmptyTransformer).
|
||||
BindStruct(Operation{
|
||||
ID: "1",
|
||||
ClientID: "42",
|
||||
Type: "Transfer",
|
||||
Fee: inf.NewDec(1, 1),
|
||||
})
|
||||
if err := insertQuery.ExecRelease(); err != nil {
|
||||
t.Fatal("ExecRelease() failed:", err)
|
||||
}
|
||||
|
||||
// Set default transformer to avoid setting it for each query.
|
||||
gocqlx.DefaultBindTransformer = gocqlx.UnsetEmptyTransformer
|
||||
defer func() {
|
||||
gocqlx.DefaultBindTransformer = nil
|
||||
}()
|
||||
|
||||
// Insert operation with empty fee.
|
||||
insertQuery = insertOperation.Query(session).
|
||||
BindStruct(Operation{
|
||||
ID: "2",
|
||||
ClientID: "42",
|
||||
Type: "Input",
|
||||
PaymentID: "1",
|
||||
})
|
||||
if err := insertQuery.ExecRelease(); err != nil {
|
||||
t.Fatal("ExecRelease() failed:", err)
|
||||
}
|
||||
|
||||
// Query and displays data.
|
||||
var ops []*Operation
|
||||
if err := qb.Select("examples.operations").Query(session).Select(&ops); err != nil {
|
||||
t.Fatal("Select() failed:", err)
|
||||
}
|
||||
|
||||
for _, op := range ops {
|
||||
t.Logf("%+v", *op)
|
||||
}
|
||||
}
|
||||
|
||||
func mustParseUUID(s string) gocql.UUID {
|
||||
u, err := gocql.ParseUUID(s)
|
||||
if err != nil {
|
||||
|
||||
@@ -4,6 +4,12 @@
|
||||
|
||||
package gocqlx
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
|
||||
"github.com/gocql/gocql"
|
||||
)
|
||||
|
||||
// Transformer transforms the value of the named parameter to another value.
|
||||
type Transformer func(name string, val interface{}) interface{}
|
||||
|
||||
@@ -11,3 +17,14 @@ type Transformer func(name string, val interface{}) interface{}
|
||||
//
|
||||
// A custom transformer can always be set per Query.
|
||||
var DefaultBindTransformer Transformer
|
||||
|
||||
// UnsetEmptyTransformer unsets all empty parameters.
|
||||
// It helps to avoid tombstones when using the same insert/update
|
||||
// statement for filled and partially filled named parameters.
|
||||
var UnsetEmptyTransformer = func(name string, val interface{}) interface{} {
|
||||
v := reflect.ValueOf(val)
|
||||
if v.IsZero() {
|
||||
return gocql.UnsetValue
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user