@@ -35,6 +35,8 @@ type Field struct {
3535 Name string
3636 Type ktType
3737 Comment string
38+ // EmbedFields contains the embedded fields that require scanning.
39+ EmbedFields []Field
3840}
3941
4042type Struct struct {
@@ -184,8 +186,22 @@ func (v QueryValue) ResultSet() string {
184186 if v .Struct == nil {
185187 return jdbcGet (v .Typ , 1 )
186188 }
187- for i , f := range v .Struct .Fields {
188- out = append (out , jdbcGet (f .Type , i + 1 ))
189+
190+ idx := 0
191+ for _ , f := range v .Struct .Fields {
192+ if len (f .EmbedFields ) > 0 {
193+ var classConstr strings.Builder
194+ classConstr .WriteString (fmt .Sprintf ("%s(\n " , f .Type .DataType ))
195+ for _ , ef := range f .EmbedFields {
196+ classConstr .WriteString (indent (fmt .Sprintf ("%s,\n " , jdbcGet (ef .Type , idx + 1 )), 0 , 4 ))
197+ idx ++
198+ }
199+ classConstr .WriteString (")" )
200+ out = append (out , classConstr .String ())
201+ } else {
202+ out = append (out , jdbcGet (f .Type , idx + 1 ))
203+ idx ++
204+ }
189205 }
190206 ret := indent (strings .Join (out , ",\n " ), 4 , - 1 )
191207 ret = indent (v .Struct .Name + "(\n " + ret + "\n )" , 12 , 0 )
@@ -305,9 +321,10 @@ func BuildDataClasses(conf Config, req *plugin.GenerateRequest) []Struct {
305321 }
306322 for _ , column := range table .Columns {
307323 s .Fields = append (s .Fields , Field {
308- Name : memberName (column .Name , req .Settings ),
309- Type : makeType (req , column ),
310- Comment : column .Comment ,
324+ Name : memberName (column .Name , req .Settings ),
325+ Type : makeType (req , column ),
326+ Comment : column .Comment ,
327+ EmbedFields : nil ,
311328 })
312329 }
313330 structs = append (structs , s )
@@ -398,6 +415,46 @@ func ktInnerType(req *plugin.GenerateRequest, col *plugin.Column) (string, bool)
398415type goColumn struct {
399416 id int
400417 * plugin.Column
418+ embed * goEmbed
419+ }
420+
421+ type goEmbed struct {
422+ modelType string
423+ modelName string
424+ fields []Field
425+ }
426+
427+ // look through all the structs and attempt to find a matching one to embed
428+ // We need the name of the struct and its field names.
429+ func newGoEmbed (embed * plugin.Identifier , structs []Struct , defaultSchema string ) * goEmbed {
430+ if embed == nil {
431+ return nil
432+ }
433+
434+ for _ , s := range structs {
435+ embedSchema := defaultSchema
436+ if embed .Schema != "" {
437+ embedSchema = embed .Schema
438+ }
439+
440+ // compare the other attributes
441+ if embed .Catalog != s .Table .Catalog || embed .Name != s .Table .Name || embedSchema != s .Table .Schema {
442+ continue
443+ }
444+
445+ fields := make ([]Field , len (s .Fields ))
446+ for i , f := range s .Fields {
447+ fields [i ] = f
448+ }
449+
450+ return & goEmbed {
451+ modelType : s .Name ,
452+ modelName : strings .ToLower (string (s .Name [0 ])) + s .Name [1 :],
453+ fields : fields ,
454+ }
455+ }
456+
457+ return nil
401458}
402459
403460func ktColumnsToStruct (req * plugin.GenerateRequest , name string , columns []goColumn , namer func (* plugin.Column , int ) string ) * Struct {
@@ -415,9 +472,22 @@ func ktColumnsToStruct(req *plugin.GenerateRequest, name string, columns []goCol
415472 fieldName = fmt .Sprintf ("%s_%d" , fieldName , v + 1 )
416473 }
417474 field := Field {
418- ID : c .id ,
419- Name : fieldName ,
420- Type : makeType (req , c .Column ),
475+ ID : c .id ,
476+ }
477+ if c .embed == nil {
478+ field .Name = fieldName
479+ field .Type = makeType (req , c .Column )
480+ } else {
481+ field .Name = c .embed .modelName
482+ field .Type = ktType {
483+ Name : c .embed .modelType ,
484+ IsEnum : false ,
485+ IsArray : false ,
486+ IsNull : false ,
487+ DataType : c .embed .modelType ,
488+ Engine : req .Settings .Engine ,
489+ }
490+ field .EmbedFields = c .embed .fields
421491 }
422492 gs .Fields = append (gs .Fields , field )
423493 nameSeen [c .Name ]++
@@ -526,13 +596,14 @@ func BuildQueries(req *plugin.GenerateRequest, structs []Struct) ([]Query, error
526596 binding : refs ,
527597 }
528598
529- if len (query .Columns ) == 1 {
599+ forceStruct := len (query .Columns ) == 1 && query .Columns [0 ].EmbedTable != nil
600+ if len (query .Columns ) == 1 && ! forceStruct {
530601 c := query .Columns [0 ]
531602 gq .Ret = QueryValue {
532603 Name : "results" ,
533604 Typ : makeType (req , c ),
534605 }
535- } else if len (query .Columns ) > 1 {
606+ } else if len (query .Columns ) > 1 || forceStruct {
536607 var gs * Struct
537608 var emit bool
538609
@@ -560,9 +631,11 @@ func BuildQueries(req *plugin.GenerateRequest, structs []Struct) ([]Query, error
560631 if gs == nil {
561632 var columns []goColumn
562633 for i , c := range query .Columns {
634+ embed := newGoEmbed (c .EmbedTable , structs , req .Catalog .DefaultSchema )
563635 columns = append (columns , goColumn {
564636 id : i ,
565637 Column : c ,
638+ embed : embed ,
566639 })
567640 }
568641 gs = ktColumnsToStruct (req , gq .ClassName + "Row" , columns , ktColumnName )
0 commit comments