forked from lqs/sqlingo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
field.go
109 lines (94 loc) 路 2.72 KB
/
field.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package sqlingo
import "strings"
// Field is the interface of a generated field.
type Field interface {
Expression
GetTable() Table
}
// NumberField is the interface of a generated field of number type.
type NumberField interface {
NumberExpression
GetTable() Table
}
// BooleanField is the interface of a generated field of boolean type.
type BooleanField interface {
BooleanExpression
GetTable() Table
}
// StringField is the interface of a generated field of string type.
type StringField interface {
StringExpression
GetTable() Table
}
type actualField struct {
expression
table Table
}
func (f actualField) GetTable() Table {
return f.table
}
func newField(table Table, fieldName string) actualField {
tableName := table.GetName()
tableNameSqlArray := quoteIdentifier(tableName)
fieldNameSqlArray := quoteIdentifier(fieldName)
var fullFieldNameSqlArray dialectArray
for dialect := dialect(0); dialect < dialectCount; dialect++ {
fullFieldNameSqlArray[dialect] = tableNameSqlArray[dialect] + "." + fieldNameSqlArray[dialect]
}
return actualField{
expression: expression{
builder: func(scope scope) (string, error) {
dialect := dialectUnknown
if scope.Database != nil {
dialect = scope.Database.dialect
}
if len(scope.Tables) != 1 || scope.lastJoin != nil || scope.Tables[0].GetName() != tableName {
return fullFieldNameSqlArray[dialect], nil
}
return fieldNameSqlArray[dialect], nil
},
},
table: table,
}
}
// NewNumberField creates a reference to a number field. It should only be called from generated code.
func NewNumberField(table Table, fieldName string) NumberField {
return newField(table, fieldName)
}
// NewBooleanField creates a reference to a boolean field. It should only be called from generated code.
func NewBooleanField(table Table, fieldName string) BooleanField {
return newField(table, fieldName)
}
// NewStringField creates a reference to a string field. It should only be called from generated code.
func NewStringField(table Table, fieldName string) StringField {
return newField(table, fieldName)
}
type fieldList []Field
func (fields fieldList) GetSQL(scope scope) (string, error) {
isSingleTable := len(scope.Tables) == 1 && scope.lastJoin == nil
var sb strings.Builder
if len(fields) == 0 {
for i, table := range scope.Tables {
if i > 0 {
sb.WriteString(", ")
}
actualTable, ok := table.(actualTable)
if ok {
if isSingleTable {
sb.WriteString(actualTable.GetFieldsSQL())
} else {
sb.WriteString(actualTable.GetFullFieldsSQL())
}
} else {
sb.WriteByte('*')
}
}
} else {
fieldsSql, err := commaFields(scope, fields)
if err != nil {
return "", err
}
sb.WriteString(fieldsSql)
}
return sb.String(), nil
}