Skip to content

Commit

Permalink
feat: add new field type Asterisk (go-gorm#609)
Browse files Browse the repository at this point in the history
* feat: add new field type Asterisk

* feat: fix asterisk sql build

* feat: update template for asterisk
  • Loading branch information
tr1v3r authored Aug 18, 2022
1 parent dafd3fb commit fe07709
Show file tree
Hide file tree
Showing 6 changed files with 111 additions and 4 deletions.
24 changes: 24 additions & 0 deletions do_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,30 @@ func TestDO_methods(t *testing.T) {
Expr: teacher.Select(teacher.Name.As("n")).Distinct(),
Result: "SELECT DISTINCT `teacher`.`name` AS `n`",
},
{
Expr: teacher.Select(field.ALL),
Result: "SELECT *",
},
{
Expr: teacher.Select(field.ALL.Count()),
Result: "SELECT COUNT(*)",
},
{
Expr: teacher.Select(field.ALL.Distinct().Count()),
Result: "SELECT COUNT(DISTINCT *)",
},
{
Expr: teacher.Select(teacher.ALL),
Result: "SELECT `teacher`.*",
},
{
Expr: teacher.Select(teacher.ALL.Count()),
Result: "SELECT COUNT(`teacher`.*)",
},
{
Expr: teacher.Select(teacher.ALL.Distinct().Count()),
Result: "SELECT COUNT(DISTINCT `teacher`.*)",
},
{
Expr: teacher.Select(teacher.ID.As("i"), teacher.Name.As("n")).Distinct(),
Result: "SELECT DISTINCT `teacher`.`id` AS `i`,`teacher`.`name` AS `n`",
Expand Down
56 changes: 56 additions & 0 deletions field/asterisk.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package field

import (
"gorm.io/gorm"
"gorm.io/gorm/clause"
)

// Asterisk a type of xxx.*
type Asterisk struct{ asteriskExpr }

// Count count
func (a Asterisk) Count() Asterisk {
var expr *clause.Expr
switch {
case a.e != nil:
expr = &clause.Expr{
SQL: "COUNT(?)",
Vars: []interface{}{a.e},
}
case a.col.Table == "":
expr = &clause.Expr{SQL: "COUNT(*)"}
default:
expr = &clause.Expr{
SQL: "COUNT(?.*)",
Vars: []interface{}{clause.Table{Name: a.col.Table}},
}
}
return Asterisk{asteriskExpr{expr: a.setE(expr)}}
}

// Distinct distinct
func (a Asterisk) Distinct() Asterisk {
var expr *clause.Expr
if a.col.Table == "" {
expr = &clause.Expr{SQL: "DISTINCT *"}
} else {
expr = &clause.Expr{
SQL: "DISTINCT ?.*",
Vars: []interface{}{clause.Table{Name: a.col.Table}},
}
}
return Asterisk{asteriskExpr{expr: a.setE(expr)}}
}

type asteriskExpr struct{ expr }

func (e asteriskExpr) BuildWithArgs(*gorm.Statement) (query sql, args []interface{}) {
// if e.expr has no expression it must be directly calling for "*" or "xxx.*"
if e.e != nil {
return "?", []interface{}{e.e}
}
if e.col.Table == "" {
return "*", nil
}
return "?.*", []interface{}{clause.Table{Name: e.col.Table}}
}
7 changes: 6 additions & 1 deletion field/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (

var (
// Star a symbol of "*"
Star = NewString("", "*")
Star = NewAsterisk("")
// ALL same with Star
ALL = Star
)
Expand All @@ -32,6 +32,11 @@ func NewField(table, column string, opts ...Option) Field {
return Field{expr: expr{col: toColumn(table, column, opts...)}}
}

// NewAsterisk create new * field
func NewAsterisk(table string, opts ...Option) Asterisk {
return Asterisk{asteriskExpr: asteriskExpr{expr{col: toColumn(table, "*", opts...)}}}
}

// ======================== integer =======================

// NewInt create new Int
Expand Down
16 changes: 16 additions & 0 deletions field/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,22 @@ func TestExpr_Build(t *testing.T) {
Result: "`t1`.`a` + `t2`.`b`+? > `t`.`c`",
ExpectedVars: []interface{}{int(1)},
},
{
Expr: field.ALL.Count(),
Result: "COUNT(*)",
},
{
Expr: field.ALL.Distinct().Count(),
Result: "COUNT(DISTINCT *)",
},
{
Expr: field.NewAsterisk("user").Count(),
Result: "COUNT(`user`.*)",
},
{
Expr: field.NewAsterisk("user").Distinct().Count(),
Result: "COUNT(DISTINCT `user`.*)",
},
// ======================== integer ========================
{
Expr: field.NewUint("", "id"),
Expand Down
6 changes: 6 additions & 0 deletions generator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func (TeacherRaw) TableName() string {
type user struct {
userDo

ALL field.Asterisk
ID field.Uint
Name field.String
Age field.Int
Expand Down Expand Up @@ -254,6 +255,7 @@ func (u userDo) FindByPage(offset int, limit int) (result []*user, count int64,

var u = func() *user {
u := user{
ALL: field.NewAsterisk(""),
ID: field.NewUint("", "id"),
Name: field.NewString("", "name"),
Age: field.NewInt("", "age"),
Expand All @@ -270,6 +272,7 @@ var u = func() *user {
type Student struct {
DO

ALL field.Asterisk
ID field.Int64
Name field.String
Age field.Int
Expand All @@ -278,6 +281,7 @@ type Student struct {

var student = func() *Student {
s := Student{
ALL: field.NewAsterisk("student"),
ID: field.NewInt64("student", "id"),
Name: field.NewString("student", "name"),
Age: field.NewInt("student", "age"),
Expand All @@ -291,12 +295,14 @@ var student = func() *Student {
type Teacher struct {
DO

ALL field.Asterisk
ID field.Int64
Name field.String
}

var teacher = func() Teacher {
t := Teacher{
ALL: field.NewAsterisk("teacher"),
ID: field.NewInt64("teacher", "id"),
Name: field.NewString("teacher", "name"),
}
Expand Down
6 changes: 3 additions & 3 deletions internal/template/struct.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const (
_{{.QueryStructName}}.{{.QueryStructName}}Do.UseModel(&{{.StructInfo.Package}}.{{.StructInfo.Type}}{})
tableName := _{{.QueryStructName}}.{{.QueryStructName}}Do.TableName()
_{{$.QueryStructName}}.ALL = field.NewField(tableName, "*")
_{{$.QueryStructName}}.ALL = field.NewAsterisk(tableName)
{{range .Fields -}}
{{if not .IsRelation -}}
{{- if .ColumnName -}}_{{$.QueryStructName}}.{{.Name}} = field.New{{.GenType}}(tableName, "{{.ColumnName}}"){{- end -}}
Expand All @@ -57,7 +57,7 @@ const (
}
`
fields = `
ALL field.Field
ALL field.Asterisk
{{range .Fields -}}
{{if not .IsRelation -}}
{{- if .ColumnName -}}{{.Name}} field.{{.GenType}}{{- end -}}
Expand All @@ -83,7 +83,7 @@ func ({{.S}} {{.QueryStructName}}) As(alias string) *{{.QueryStructName}} {
`
updateFieldMethod = `
func ({{.S}} *{{.QueryStructName}}) updateTableName(table string) *{{.QueryStructName}} {
{{.S}}.ALL = field.NewField(table, "*")
{{.S}}.ALL = field.NewAsterisk(table)
{{range .Fields -}}
{{if not .IsRelation -}}
{{- if .ColumnName -}}{{$.S}}.{{.Name}} = field.New{{.GenType}}(table, "{{.ColumnName}}"){{- end -}}
Expand Down

0 comments on commit fe07709

Please sign in to comment.