diff --git a/cmd/schemagen/keyspace.tmpl b/cmd/schemagen/keyspace.tmpl index ed48c96..1a463e5 100644 --- a/cmd/schemagen/keyspace.tmpl +++ b/cmd/schemagen/keyspace.tmpl @@ -2,7 +2,12 @@ package {{.PackageName}} -import "github.com/scylladb/gocqlx/v2/table" +import ( + "github.com/scylladb/gocqlx/v2/table" + {{- range .Imports}} + "{{.}}" + {{- end}} +) // Table models. var ( @@ -30,3 +35,27 @@ var ( {{end}} {{end}} ) + +{{with .UserTypes}} +{{range .}} +{{- $type_name := .Name | camelize}} +{{- $field_types := .FieldTypes}} +type {{$type_name}}Type struct { +{{- range $index, $element := .FieldNames}} + {{- $type := index $field_types $index}} + {{. | camelize}} {{getNativeTypeSting $type | mapScyllaToGoType}} +{{- end}} +} +{{- end}} +{{- end}} + +{{with .Tables}} +{{range .}} +{{- $model_name := .Name | camelize}} +type {{$model_name}}Struct struct { +{{- range .Columns}} + {{.Name | camelize}} {{.Validator | mapScyllaToGoType}} +{{- end}} +} +{{- end}} +{{- end}} diff --git a/cmd/schemagen/map_types.go b/cmd/schemagen/map_types.go new file mode 100644 index 0000000..2582e4a --- /dev/null +++ b/cmd/schemagen/map_types.go @@ -0,0 +1,87 @@ +package main + +import ( + "regexp" + "strconv" + "strings" + + "github.com/gocql/gocql" +) + +var types = map[string]string{ + "ascii": "string", + "bigint": "int64", + "blob": "[]byte", + "boolean": "bool", + "counter": "int", + "date": "string", + "decimal": "float32", + "double": "float64", + "duration": "unit32", + "float": "float32", + "inet": "string", + "int": "int32", + "smallint": "int16", + "text": "string", + "time": "uint32", + "timestamp": "uint32", + "timeuuid": "string", + "tinyint": "int8", + "uuid": "gocql.UUID", + "varchar": "string", + "varint": "int64", +} + +func mapScyllaToGoType(s string) string { + mapRegex := regexp.MustCompile(`map<([a-z]*), ([a-z]*)>`) + setRegex := regexp.MustCompile(`set<([a-z]*)>`) + listRegex := regexp.MustCompile(`list<([a-z]*)>`) + tupleRegex := regexp.MustCompile(`tuple<(?:([a-z]*),? ?)*>`) + match := mapRegex.FindAllStringSubmatch(s, -1) + if match != nil { + key := match[0][1] + value := match[0][2] + + return "map[" + types[key] + "]" + types[value] + } + + match = setRegex.FindAllStringSubmatch(s, -1) + if match != nil { + key := match[0][1] + + return "[]" + types[key] + } + + match = listRegex.FindAllStringSubmatch(s, -1) + if match != nil { + key := match[0][1] + + return "[]" + types[key] + } + + match = tupleRegex.FindAllStringSubmatch(s, -1) + if match != nil { + tuple := match[0][0] + subStr := tuple[6 : len(tuple)-1] + types := strings.Split(subStr, ", ") + + typeStr := "struct {\n" + for i, t := range types { + typeStr = typeStr + "\t\tFiled" + strconv.Itoa(i+1) + " " + mapScyllaToGoType(t) + "\n" + } + typeStr = typeStr + "\t}" + + return typeStr + } + + t, exists := types[s] + if exists { + return t + } + + return camelize(s) + "Type" +} + +func getNativeTypeSting(t gocql.NativeType) string { + return t.String() +} diff --git a/cmd/schemagen/schemagen.go b/cmd/schemagen/schemagen.go index 27266fd..747b1d6 100644 --- a/cmd/schemagen/schemagen.go +++ b/cmd/schemagen/schemagen.go @@ -5,7 +5,6 @@ import ( _ "embed" "flag" "fmt" - "go/format" "html/template" "io/ioutil" "log" @@ -74,22 +73,36 @@ func renderTemplate(md *gocql.KeyspaceMetadata) ([]byte, error) { t, err := template. New("keyspace.tmpl"). Funcs(template.FuncMap{"camelize": camelize}). + Funcs(template.FuncMap{"mapScyllaToGoType": mapScyllaToGoType}). + Funcs(template.FuncMap{"getNativeTypeSting": getNativeTypeSting}). Parse(keyspaceTmpl) if err != nil { log.Fatalln("unable to parse models template:", err) } + imports := make([]string, 0) + for _, t := range md.Tables { + for _, c := range t.Columns { + if c.Validator == "uuid" && !existsInSlice(imports, "github.com/gocql/gocql") { + imports = append(imports, "github.com/gocql/gocql") + } + } + } + buf := &bytes.Buffer{} data := map[string]interface{}{ "PackageName": *flagPkgname, "Tables": md.Tables, + "UserTypes": md.UserTypes, + "Imports": imports, } if err = t.Execute(buf, data); err != nil { 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) { @@ -106,3 +119,13 @@ func createSession() (gocqlx.Session, error) { func clusterHosts() []string { return strings.Split(*flagCluster, ",") } + +func existsInSlice(s []string, v string) bool { + for _, i := range s { + if v == i { + return true + } + } + + return false +} diff --git a/go.mod b/go.mod index c207cdb..f8ff801 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module github.com/scylladb/gocqlx/v2 go 1.17 require ( - github.com/gocql/gocql v0.0.0-20200131111108-92af2e088537 + github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 github.com/google/go-cmp v0.5.4 github.com/psanford/memfs v0.0.0-20210214183328-a001468d78ef github.com/scylladb/go-reflectx v1.0.1 @@ -12,7 +12,7 @@ require ( ) require ( - github.com/golang/snappy v0.0.1 // indirect + github.com/golang/snappy v0.0.4 // indirect github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed // indirect golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect ) diff --git a/go.sum b/go.sum index e92d4c1..00894b5 100644 --- a/go.sum +++ b/go.sum @@ -5,9 +5,14 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/gocql/gocql v0.0.0-20200131111108-92af2e088537 h1:NaMut1fdw76YYX/TPinSAbai4DShF5tPort3bHpET6g= github.com/gocql/gocql v0.0.0-20200131111108-92af2e088537/go.mod h1:DL0ekTmBSTdlNF25Orwt/JMzqIq3EJ4MVa/J/uK64OY= +github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1 h1:px9qUCy/RNJNsfCam4m2IxWGxNuimkrioEF0vrrbPsg= +github.com/gocql/gocql v0.0.0-20211015133455-b225f9b53fa1/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.4 h1:L8R9j+yAqZuZjsqh/z+F1NCffTKKLShY6zXTItVIZ8M= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8=