Added tests, example and updated a few types
This commit is contained in:
committed by
Michal Jan Matczuk
parent
2942397ab6
commit
a62ba24cf9
@@ -14,20 +14,20 @@ var types = map[string]string{
|
|||||||
"blob": "[]byte",
|
"blob": "[]byte",
|
||||||
"boolean": "bool",
|
"boolean": "bool",
|
||||||
"counter": "int",
|
"counter": "int",
|
||||||
"date": "string",
|
"date": "time.Time",
|
||||||
"decimal": "float32",
|
"decimal": "inf.Dec",
|
||||||
"double": "float64",
|
"double": "float64",
|
||||||
"duration": "unit32",
|
"duration": "gocql.Duration",
|
||||||
"float": "float32",
|
"float": "float32",
|
||||||
"inet": "string",
|
"inet": "string",
|
||||||
"int": "int32",
|
"int": "int32",
|
||||||
"smallint": "int16",
|
"smallint": "int16",
|
||||||
"text": "string",
|
"text": "string",
|
||||||
"time": "uint32",
|
"time": "time.Duration",
|
||||||
"timestamp": "uint32",
|
"timestamp": "time.Time",
|
||||||
"timeuuid": "string",
|
"timeuuid": "[16]byte",
|
||||||
"tinyint": "int8",
|
"tinyint": "int8",
|
||||||
"uuid": "gocql.UUID",
|
"uuid": "[16]byte",
|
||||||
"varchar": "string",
|
"varchar": "string",
|
||||||
"varint": "int64",
|
"varint": "int64",
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ func mapScyllaToGoType(s string) string {
|
|||||||
|
|
||||||
typeStr := "struct {\n"
|
typeStr := "struct {\n"
|
||||||
for i, t := range types {
|
for i, t := range types {
|
||||||
typeStr = typeStr + "\t\tFiled" + strconv.Itoa(i+1) + " " + mapScyllaToGoType(t) + "\n"
|
typeStr = typeStr + "\t\tField" + strconv.Itoa(i+1) + " " + mapScyllaToGoType(t) + "\n"
|
||||||
}
|
}
|
||||||
typeStr = typeStr + "\t}"
|
typeStr = typeStr + "\t}"
|
||||||
|
|
||||||
|
|||||||
49
cmd/schemagen/map_types_test.go
Normal file
49
cmd/schemagen/map_types_test.go
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
// 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 main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMapScyllaToGoType(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{"ascii", "string"},
|
||||||
|
{"bigint", "int64"},
|
||||||
|
{"blob", "[]byte"},
|
||||||
|
{"boolean", "bool"},
|
||||||
|
{"counter", "int"},
|
||||||
|
{"date", "time.Time"},
|
||||||
|
{"decimal", "inf.Dec"},
|
||||||
|
{"double", "float64"},
|
||||||
|
{"duration", "gocql.Duration"},
|
||||||
|
{"float", "float32"},
|
||||||
|
{"inet", "string"},
|
||||||
|
{"int", "int32"},
|
||||||
|
{"smallint", "int16"},
|
||||||
|
{"text", "string"},
|
||||||
|
{"time", "time.Duration"},
|
||||||
|
{"timestamp", "time.Time"},
|
||||||
|
{"timeuuid", "[16]byte"},
|
||||||
|
{"tinyint", "int8"},
|
||||||
|
{"uuid", "[16]byte"},
|
||||||
|
{"varchar", "string"},
|
||||||
|
{"varint", "int64"},
|
||||||
|
{"map<int, text>", "map[int32]string"},
|
||||||
|
{"list<int>", "[]int32"},
|
||||||
|
{"set<int>", "[]int32"},
|
||||||
|
{"tuple<boolean, int, smallint>", "struct {\n\t\tField1 bool\n\t\tField2 int32\n\t\tField3 int16\n\t}"},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.input, func(t *testing.T) {
|
||||||
|
if got := mapScyllaToGoType(tt.input); got != tt.want {
|
||||||
|
t.Errorf("mapScyllaToGoType() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
_ "embed"
|
_ "embed"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"go/format"
|
||||||
"html/template"
|
"html/template"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"log"
|
"log"
|
||||||
@@ -84,7 +85,13 @@ func renderTemplate(md *gocql.KeyspaceMetadata) ([]byte, error) {
|
|||||||
imports := make([]string, 0)
|
imports := make([]string, 0)
|
||||||
for _, t := range md.Tables {
|
for _, t := range md.Tables {
|
||||||
for _, c := range t.Columns {
|
for _, c := range t.Columns {
|
||||||
if c.Validator == "uuid" && !existsInSlice(imports, "github.com/gocql/gocql") {
|
if (c.Validator == "timestamp" || c.Validator == "date" || c.Validator == "duration" || c.Validator == "time") && !existsInSlice(imports, "time") {
|
||||||
|
imports = append(imports, "time")
|
||||||
|
}
|
||||||
|
if c.Validator == "decimal" && !existsInSlice(imports, "gopkg.in/inf.v0") {
|
||||||
|
imports = append(imports, "gopkg.in/inf.v0")
|
||||||
|
}
|
||||||
|
if c.Validator == "duration" && !existsInSlice(imports, "github.com/gocql/gocql") {
|
||||||
imports = append(imports, "github.com/gocql/gocql")
|
imports = append(imports, "github.com/gocql/gocql")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -101,8 +108,7 @@ func renderTemplate(md *gocql.KeyspaceMetadata) ([]byte, error) {
|
|||||||
if err = t.Execute(buf, data); err != nil {
|
if err = t.Execute(buf, data); err != nil {
|
||||||
return nil, fmt.Errorf("template: %w", err)
|
return nil, fmt.Errorf("template: %w", err)
|
||||||
}
|
}
|
||||||
//return format.Source(buf.Bytes())
|
return format.Source(buf.Bytes())
|
||||||
return buf.Bytes(), nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSession() (gocqlx.Session, error) {
|
func createSession() (gocqlx.Session, error) {
|
||||||
|
|||||||
20
cmd/schemagen/testdata/models.go.txt
vendored
20
cmd/schemagen/testdata/models.go.txt
vendored
@@ -2,7 +2,9 @@
|
|||||||
|
|
||||||
package foobar
|
package foobar
|
||||||
|
|
||||||
import "github.com/scylladb/gocqlx/v2/table"
|
import (
|
||||||
|
"github.com/scylladb/gocqlx/v2/table"
|
||||||
|
)
|
||||||
|
|
||||||
// Table models.
|
// Table models.
|
||||||
var (
|
var (
|
||||||
@@ -41,3 +43,19 @@ var (
|
|||||||
SortKey: []string{},
|
SortKey: []string{},
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type PlaylistsStruct struct {
|
||||||
|
Album string
|
||||||
|
Artist string
|
||||||
|
Id [16]byte
|
||||||
|
SongId [16]byte
|
||||||
|
Title string
|
||||||
|
}
|
||||||
|
type SongsStruct struct {
|
||||||
|
Album string
|
||||||
|
Artist string
|
||||||
|
Data []byte
|
||||||
|
Id [16]byte
|
||||||
|
Tags []string
|
||||||
|
Title string
|
||||||
|
}
|
||||||
|
|||||||
165
example_test.go
165
example_test.go
@@ -37,6 +37,7 @@ func TestExample(t *testing.T) {
|
|||||||
session.ExecStmt(`DROP KEYSPACE examples`)
|
session.ExecStmt(`DROP KEYSPACE examples`)
|
||||||
|
|
||||||
basicCreateAndPopulateKeyspace(t, session)
|
basicCreateAndPopulateKeyspace(t, session)
|
||||||
|
createAndPopulateKeyspaceAllTypes(t, session)
|
||||||
basicReadScyllaVersion(t, session)
|
basicReadScyllaVersion(t, session)
|
||||||
|
|
||||||
datatypesBlob(t, session)
|
datatypesBlob(t, session)
|
||||||
@@ -154,6 +155,170 @@ func basicCreateAndPopulateKeyspace(t *testing.T, session gocqlx.Session) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This example shows how to use query builders and table models to build
|
||||||
|
// queries with all types. It uses "BindStruct" function for parameter binding and "Select"
|
||||||
|
// function for loading data to a slice.
|
||||||
|
func createAndPopulateKeyspaceAllTypes(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
// generated with schemagen
|
||||||
|
type CheckTypesStruct struct {
|
||||||
|
AsciI string
|
||||||
|
BigInt int64
|
||||||
|
BloB []byte
|
||||||
|
BooleaN bool
|
||||||
|
DatE time.Time
|
||||||
|
DecimaL inf.Dec
|
||||||
|
DoublE float64
|
||||||
|
DuratioN gocql.Duration
|
||||||
|
FloaT float32
|
||||||
|
Id [16]byte
|
||||||
|
InT int32
|
||||||
|
IneT string
|
||||||
|
ListInt []int32
|
||||||
|
MapIntText map[int32]string
|
||||||
|
SetInt []int32
|
||||||
|
SmallInt int16
|
||||||
|
TexT string
|
||||||
|
TimE time.Duration
|
||||||
|
TimestamP time.Time
|
||||||
|
TimeuuiD [16]byte
|
||||||
|
TinyInt int8
|
||||||
|
VarChar string
|
||||||
|
VarInt int64
|
||||||
|
}
|
||||||
|
|
||||||
|
err = session.ExecStmt(`CREATE TABLE IF NOT EXISTS examples.check_types (
|
||||||
|
asci_i ascii,
|
||||||
|
big_int bigint,
|
||||||
|
blo_b blob,
|
||||||
|
boolea_n boolean,
|
||||||
|
dat_e date,
|
||||||
|
decima_l decimal,
|
||||||
|
doubl_e double,
|
||||||
|
duratio_n duration,
|
||||||
|
floa_t float,
|
||||||
|
ine_t inet,
|
||||||
|
in_t int,
|
||||||
|
small_int smallint,
|
||||||
|
tex_t text,
|
||||||
|
tim_e time,
|
||||||
|
timestam_p timestamp,
|
||||||
|
timeuui_d timeuuid,
|
||||||
|
tiny_int tinyint,
|
||||||
|
id uuid PRIMARY KEY,
|
||||||
|
var_char varchar,
|
||||||
|
var_int varint,
|
||||||
|
map_int_text map<int, text>,
|
||||||
|
list_int list<int>,
|
||||||
|
set_int set<int>)`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("create table:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// generated with schemagen
|
||||||
|
checkTypesTable := table.New(table.Metadata{
|
||||||
|
Name: "examples.check_types",
|
||||||
|
Columns: []string{
|
||||||
|
"asci_i",
|
||||||
|
"big_int",
|
||||||
|
"blo_b",
|
||||||
|
"boolea_n",
|
||||||
|
"dat_e",
|
||||||
|
"decima_l",
|
||||||
|
"doubl_e",
|
||||||
|
"duratio_n",
|
||||||
|
"floa_t",
|
||||||
|
"id",
|
||||||
|
"in_t",
|
||||||
|
"ine_t",
|
||||||
|
"list_int",
|
||||||
|
"map_int_text",
|
||||||
|
"set_int",
|
||||||
|
"small_int",
|
||||||
|
"tex_t",
|
||||||
|
"tim_e",
|
||||||
|
"timestam_p",
|
||||||
|
"timeuui_d",
|
||||||
|
"tiny_int",
|
||||||
|
"var_char",
|
||||||
|
"var_int",
|
||||||
|
},
|
||||||
|
PartKey: []string{"id"},
|
||||||
|
SortKey: []string{},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Insert song using query builder.
|
||||||
|
insertCheckTypes := qb.Insert("examples.check_types").
|
||||||
|
Columns("asci_i", "big_int", "blo_b", "boolea_n", "dat_e", "decima_l", "doubl_e", "duratio_n", "floa_t", "ine_t", "in_t", "small_int", "tex_t", "tim_e", "timestam_p", "timeuui_d", "tiny_int", "id", "var_char", "var_int", "map_int_text", "list_int", "set_int").Query(session)
|
||||||
|
|
||||||
|
var byteId [16]byte
|
||||||
|
id := []byte("756716f7-2e54-4715-9f00-91dcbea6cf50")
|
||||||
|
copy(byteId[:], id)
|
||||||
|
|
||||||
|
date := time.Date(2021, time.December, 11, 10, 23, 0, 0, time.UTC)
|
||||||
|
var double float64 = 1.2
|
||||||
|
var float float32 = 1.3
|
||||||
|
var integer int32 = 123
|
||||||
|
listInt := []int32{1, 2, 3}
|
||||||
|
mapIntStr := map[int32]string{
|
||||||
|
1: "a",
|
||||||
|
2: "b",
|
||||||
|
}
|
||||||
|
setInt := []int32{2, 4, 6}
|
||||||
|
var smallInt int16 = 12
|
||||||
|
var tinyInt int8 = 14
|
||||||
|
var varInt int64 = 20
|
||||||
|
|
||||||
|
insertCheckTypes.BindStruct(CheckTypesStruct{
|
||||||
|
AsciI: "test qscci",
|
||||||
|
BigInt: 9223372036854775806, //MAXINT64 - 1,
|
||||||
|
BloB: []byte("this is blob test"),
|
||||||
|
BooleaN: false,
|
||||||
|
DatE: date,
|
||||||
|
DecimaL: *inf.NewDec(1, 1),
|
||||||
|
DoublE: double,
|
||||||
|
DuratioN: gocql.Duration{Months: 1, Days: 1, Nanoseconds: 86400},
|
||||||
|
FloaT: float,
|
||||||
|
Id: byteId,
|
||||||
|
InT: integer,
|
||||||
|
IneT: "127.0.0.1",
|
||||||
|
ListInt: listInt,
|
||||||
|
MapIntText: mapIntStr,
|
||||||
|
SetInt: setInt,
|
||||||
|
SmallInt: smallInt,
|
||||||
|
TexT: "text example",
|
||||||
|
TimE: 86400000000,
|
||||||
|
TimestamP: date,
|
||||||
|
TimeuuiD: gocql.TimeUUID(),
|
||||||
|
TinyInt: tinyInt,
|
||||||
|
VarChar: "test varchar",
|
||||||
|
VarInt: varInt,
|
||||||
|
})
|
||||||
|
if err := insertCheckTypes.ExecRelease(); err != nil {
|
||||||
|
t.Fatal("ExecRelease() failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Query and displays data.
|
||||||
|
queryCheckTypes := checkTypesTable.SelectQuery(session)
|
||||||
|
|
||||||
|
queryCheckTypes.BindStruct(&CheckTypesStruct{
|
||||||
|
Id: byteId,
|
||||||
|
})
|
||||||
|
|
||||||
|
var items []*CheckTypesStruct
|
||||||
|
if err := queryCheckTypes.Select(&items); err != nil {
|
||||||
|
t.Fatal("Select() failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, i := range items {
|
||||||
|
t.Logf("%+v", *i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This example shows how to load a single value using "Get" function.
|
// This example shows how to load a single value using "Get" function.
|
||||||
// Get can also work with UDTs and types that implement gocql marshalling functions.
|
// Get can also work with UDTs and types that implement gocql marshalling functions.
|
||||||
func basicReadScyllaVersion(t *testing.T, session gocqlx.Session) {
|
func basicReadScyllaVersion(t *testing.T, session gocqlx.Session) {
|
||||||
|
|||||||
Reference in New Issue
Block a user