1. 实现配置文件解析
2. 实现数据库连接
This commit is contained in:
89
vendor/gorm.io/gorm/clause/clause.go
generated
vendored
Normal file
89
vendor/gorm.io/gorm/clause/clause.go
generated
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
package clause
|
||||
|
||||
// Interface clause interface
|
||||
type Interface interface {
|
||||
Name() string
|
||||
Build(Builder)
|
||||
MergeClause(*Clause)
|
||||
}
|
||||
|
||||
// ClauseBuilder clause builder, allows to customize how to build clause
|
||||
type ClauseBuilder func(Clause, Builder)
|
||||
|
||||
type Writer interface {
|
||||
WriteByte(byte) error
|
||||
WriteString(string) (int, error)
|
||||
}
|
||||
|
||||
// Builder builder interface
|
||||
type Builder interface {
|
||||
Writer
|
||||
WriteQuoted(field interface{})
|
||||
AddVar(Writer, ...interface{})
|
||||
AddError(error) error
|
||||
}
|
||||
|
||||
// Clause
|
||||
type Clause struct {
|
||||
Name string // WHERE
|
||||
BeforeExpression Expression
|
||||
AfterNameExpression Expression
|
||||
AfterExpression Expression
|
||||
Expression Expression
|
||||
Builder ClauseBuilder
|
||||
}
|
||||
|
||||
// Build build clause
|
||||
func (c Clause) Build(builder Builder) {
|
||||
if c.Builder != nil {
|
||||
c.Builder(c, builder)
|
||||
} else if c.Expression != nil {
|
||||
if c.BeforeExpression != nil {
|
||||
c.BeforeExpression.Build(builder)
|
||||
builder.WriteByte(' ')
|
||||
}
|
||||
|
||||
if c.Name != "" {
|
||||
builder.WriteString(c.Name)
|
||||
builder.WriteByte(' ')
|
||||
}
|
||||
|
||||
if c.AfterNameExpression != nil {
|
||||
c.AfterNameExpression.Build(builder)
|
||||
builder.WriteByte(' ')
|
||||
}
|
||||
|
||||
c.Expression.Build(builder)
|
||||
|
||||
if c.AfterExpression != nil {
|
||||
builder.WriteByte(' ')
|
||||
c.AfterExpression.Build(builder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
PrimaryKey string = "~~~py~~~" // primary key
|
||||
CurrentTable string = "~~~ct~~~" // current table
|
||||
Associations string = "~~~as~~~" // associations
|
||||
)
|
||||
|
||||
var (
|
||||
currentTable = Table{Name: CurrentTable}
|
||||
PrimaryColumn = Column{Table: CurrentTable, Name: PrimaryKey}
|
||||
)
|
||||
|
||||
// Column quote with name
|
||||
type Column struct {
|
||||
Table string
|
||||
Name string
|
||||
Alias string
|
||||
Raw bool
|
||||
}
|
||||
|
||||
// Table quote with name
|
||||
type Table struct {
|
||||
Name string
|
||||
Alias string
|
||||
Raw bool
|
||||
}
|
||||
23
vendor/gorm.io/gorm/clause/delete.go
generated
vendored
Normal file
23
vendor/gorm.io/gorm/clause/delete.go
generated
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
package clause
|
||||
|
||||
type Delete struct {
|
||||
Modifier string
|
||||
}
|
||||
|
||||
func (d Delete) Name() string {
|
||||
return "DELETE"
|
||||
}
|
||||
|
||||
func (d Delete) Build(builder Builder) {
|
||||
builder.WriteString("DELETE")
|
||||
|
||||
if d.Modifier != "" {
|
||||
builder.WriteByte(' ')
|
||||
builder.WriteString(d.Modifier)
|
||||
}
|
||||
}
|
||||
|
||||
func (d Delete) MergeClause(clause *Clause) {
|
||||
clause.Name = ""
|
||||
clause.Expression = d
|
||||
}
|
||||
385
vendor/gorm.io/gorm/clause/expression.go
generated
vendored
Normal file
385
vendor/gorm.io/gorm/clause/expression.go
generated
vendored
Normal file
@@ -0,0 +1,385 @@
|
||||
package clause
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"database/sql/driver"
|
||||
"go/ast"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Expression expression interface
|
||||
type Expression interface {
|
||||
Build(builder Builder)
|
||||
}
|
||||
|
||||
// NegationExpressionBuilder negation expression builder
|
||||
type NegationExpressionBuilder interface {
|
||||
NegationBuild(builder Builder)
|
||||
}
|
||||
|
||||
// Expr raw expression
|
||||
type Expr struct {
|
||||
SQL string
|
||||
Vars []interface{}
|
||||
WithoutParentheses bool
|
||||
}
|
||||
|
||||
// Build build raw expression
|
||||
func (expr Expr) Build(builder Builder) {
|
||||
var (
|
||||
afterParenthesis bool
|
||||
idx int
|
||||
)
|
||||
|
||||
for _, v := range []byte(expr.SQL) {
|
||||
if v == '?' && len(expr.Vars) > idx {
|
||||
if afterParenthesis || expr.WithoutParentheses {
|
||||
if _, ok := expr.Vars[idx].(driver.Valuer); ok {
|
||||
builder.AddVar(builder, expr.Vars[idx])
|
||||
} else {
|
||||
switch rv := reflect.ValueOf(expr.Vars[idx]); rv.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
if rv.Len() == 0 {
|
||||
builder.AddVar(builder, nil)
|
||||
} else {
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
if i > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
builder.AddVar(builder, rv.Index(i).Interface())
|
||||
}
|
||||
}
|
||||
default:
|
||||
builder.AddVar(builder, expr.Vars[idx])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
builder.AddVar(builder, expr.Vars[idx])
|
||||
}
|
||||
|
||||
idx++
|
||||
} else {
|
||||
if v == '(' {
|
||||
afterParenthesis = true
|
||||
} else {
|
||||
afterParenthesis = false
|
||||
}
|
||||
builder.WriteByte(v)
|
||||
}
|
||||
}
|
||||
|
||||
if idx < len(expr.Vars) {
|
||||
for _, v := range expr.Vars[idx:] {
|
||||
builder.AddVar(builder, sql.NamedArg{Value: v})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NamedExpr raw expression for named expr
|
||||
type NamedExpr struct {
|
||||
SQL string
|
||||
Vars []interface{}
|
||||
}
|
||||
|
||||
// Build build raw expression
|
||||
func (expr NamedExpr) Build(builder Builder) {
|
||||
var (
|
||||
idx int
|
||||
inName bool
|
||||
afterParenthesis bool
|
||||
namedMap = make(map[string]interface{}, len(expr.Vars))
|
||||
)
|
||||
|
||||
for _, v := range expr.Vars {
|
||||
switch value := v.(type) {
|
||||
case sql.NamedArg:
|
||||
namedMap[value.Name] = value.Value
|
||||
case map[string]interface{}:
|
||||
for k, v := range value {
|
||||
namedMap[k] = v
|
||||
}
|
||||
default:
|
||||
var appendFieldsToMap func(reflect.Value)
|
||||
appendFieldsToMap = func(reflectValue reflect.Value) {
|
||||
reflectValue = reflect.Indirect(reflectValue)
|
||||
switch reflectValue.Kind() {
|
||||
case reflect.Struct:
|
||||
modelType := reflectValue.Type()
|
||||
for i := 0; i < modelType.NumField(); i++ {
|
||||
if fieldStruct := modelType.Field(i); ast.IsExported(fieldStruct.Name) {
|
||||
namedMap[fieldStruct.Name] = reflectValue.Field(i).Interface()
|
||||
|
||||
if fieldStruct.Anonymous {
|
||||
appendFieldsToMap(reflectValue.Field(i))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
appendFieldsToMap(reflect.ValueOf(value))
|
||||
}
|
||||
}
|
||||
|
||||
name := make([]byte, 0, 10)
|
||||
|
||||
for _, v := range []byte(expr.SQL) {
|
||||
if v == '@' && !inName {
|
||||
inName = true
|
||||
name = name[:0]
|
||||
} else if v == ' ' || v == ',' || v == ')' || v == '"' || v == '\'' || v == '`' || v == '\r' || v == '\n' || v == ';' {
|
||||
if inName {
|
||||
if nv, ok := namedMap[string(name)]; ok {
|
||||
builder.AddVar(builder, nv)
|
||||
} else {
|
||||
builder.WriteByte('@')
|
||||
builder.WriteString(string(name))
|
||||
}
|
||||
inName = false
|
||||
}
|
||||
|
||||
afterParenthesis = false
|
||||
builder.WriteByte(v)
|
||||
} else if v == '?' && len(expr.Vars) > idx {
|
||||
if afterParenthesis {
|
||||
if _, ok := expr.Vars[idx].(driver.Valuer); ok {
|
||||
builder.AddVar(builder, expr.Vars[idx])
|
||||
} else {
|
||||
switch rv := reflect.ValueOf(expr.Vars[idx]); rv.Kind() {
|
||||
case reflect.Slice, reflect.Array:
|
||||
if rv.Len() == 0 {
|
||||
builder.AddVar(builder, nil)
|
||||
} else {
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
if i > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
builder.AddVar(builder, rv.Index(i).Interface())
|
||||
}
|
||||
}
|
||||
default:
|
||||
builder.AddVar(builder, expr.Vars[idx])
|
||||
}
|
||||
}
|
||||
} else {
|
||||
builder.AddVar(builder, expr.Vars[idx])
|
||||
}
|
||||
|
||||
idx++
|
||||
} else if inName {
|
||||
name = append(name, v)
|
||||
} else {
|
||||
if v == '(' {
|
||||
afterParenthesis = true
|
||||
} else {
|
||||
afterParenthesis = false
|
||||
}
|
||||
builder.WriteByte(v)
|
||||
}
|
||||
}
|
||||
|
||||
if inName {
|
||||
if nv, ok := namedMap[string(name)]; ok {
|
||||
builder.AddVar(builder, nv)
|
||||
} else {
|
||||
builder.WriteByte('@')
|
||||
builder.WriteString(string(name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// IN Whether a value is within a set of values
|
||||
type IN struct {
|
||||
Column interface{}
|
||||
Values []interface{}
|
||||
}
|
||||
|
||||
func (in IN) Build(builder Builder) {
|
||||
builder.WriteQuoted(in.Column)
|
||||
|
||||
switch len(in.Values) {
|
||||
case 0:
|
||||
builder.WriteString(" IN (NULL)")
|
||||
case 1:
|
||||
if _, ok := in.Values[0].([]interface{}); !ok {
|
||||
builder.WriteString(" = ")
|
||||
builder.AddVar(builder, in.Values[0])
|
||||
break
|
||||
}
|
||||
|
||||
fallthrough
|
||||
default:
|
||||
builder.WriteString(" IN (")
|
||||
builder.AddVar(builder, in.Values...)
|
||||
builder.WriteByte(')')
|
||||
}
|
||||
}
|
||||
|
||||
func (in IN) NegationBuild(builder Builder) {
|
||||
builder.WriteQuoted(in.Column)
|
||||
switch len(in.Values) {
|
||||
case 0:
|
||||
builder.WriteString(" IS NOT NULL")
|
||||
case 1:
|
||||
if _, ok := in.Values[0].([]interface{}); !ok {
|
||||
builder.WriteString(" <> ")
|
||||
builder.AddVar(builder, in.Values[0])
|
||||
break
|
||||
}
|
||||
|
||||
fallthrough
|
||||
default:
|
||||
builder.WriteString(" NOT IN (")
|
||||
builder.AddVar(builder, in.Values...)
|
||||
builder.WriteByte(')')
|
||||
}
|
||||
}
|
||||
|
||||
// Eq equal to for where
|
||||
type Eq struct {
|
||||
Column interface{}
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (eq Eq) Build(builder Builder) {
|
||||
builder.WriteQuoted(eq.Column)
|
||||
|
||||
switch eq.Value.(type) {
|
||||
case []string, []int, []int32, []int64, []uint, []uint32, []uint64, []interface{}:
|
||||
rv := reflect.ValueOf(eq.Value)
|
||||
if rv.Len() == 0 {
|
||||
builder.WriteString(" IN (NULL)")
|
||||
} else {
|
||||
builder.WriteString(" IN (")
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
if i > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
builder.AddVar(builder, rv.Index(i).Interface())
|
||||
}
|
||||
builder.WriteByte(')')
|
||||
}
|
||||
default:
|
||||
if eqNil(eq.Value) {
|
||||
builder.WriteString(" IS NULL")
|
||||
} else {
|
||||
builder.WriteString(" = ")
|
||||
builder.AddVar(builder, eq.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (eq Eq) NegationBuild(builder Builder) {
|
||||
Neq(eq).Build(builder)
|
||||
}
|
||||
|
||||
// Neq not equal to for where
|
||||
type Neq Eq
|
||||
|
||||
func (neq Neq) Build(builder Builder) {
|
||||
builder.WriteQuoted(neq.Column)
|
||||
|
||||
switch neq.Value.(type) {
|
||||
case []string, []int, []int32, []int64, []uint, []uint32, []uint64, []interface{}:
|
||||
builder.WriteString(" NOT IN (")
|
||||
rv := reflect.ValueOf(neq.Value)
|
||||
for i := 0; i < rv.Len(); i++ {
|
||||
if i > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
builder.AddVar(builder, rv.Index(i).Interface())
|
||||
}
|
||||
builder.WriteByte(')')
|
||||
default:
|
||||
if eqNil(neq.Value) {
|
||||
builder.WriteString(" IS NOT NULL")
|
||||
} else {
|
||||
builder.WriteString(" <> ")
|
||||
builder.AddVar(builder, neq.Value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (neq Neq) NegationBuild(builder Builder) {
|
||||
Eq(neq).Build(builder)
|
||||
}
|
||||
|
||||
// Gt greater than for where
|
||||
type Gt Eq
|
||||
|
||||
func (gt Gt) Build(builder Builder) {
|
||||
builder.WriteQuoted(gt.Column)
|
||||
builder.WriteString(" > ")
|
||||
builder.AddVar(builder, gt.Value)
|
||||
}
|
||||
|
||||
func (gt Gt) NegationBuild(builder Builder) {
|
||||
Lte(gt).Build(builder)
|
||||
}
|
||||
|
||||
// Gte greater than or equal to for where
|
||||
type Gte Eq
|
||||
|
||||
func (gte Gte) Build(builder Builder) {
|
||||
builder.WriteQuoted(gte.Column)
|
||||
builder.WriteString(" >= ")
|
||||
builder.AddVar(builder, gte.Value)
|
||||
}
|
||||
|
||||
func (gte Gte) NegationBuild(builder Builder) {
|
||||
Lt(gte).Build(builder)
|
||||
}
|
||||
|
||||
// Lt less than for where
|
||||
type Lt Eq
|
||||
|
||||
func (lt Lt) Build(builder Builder) {
|
||||
builder.WriteQuoted(lt.Column)
|
||||
builder.WriteString(" < ")
|
||||
builder.AddVar(builder, lt.Value)
|
||||
}
|
||||
|
||||
func (lt Lt) NegationBuild(builder Builder) {
|
||||
Gte(lt).Build(builder)
|
||||
}
|
||||
|
||||
// Lte less than or equal to for where
|
||||
type Lte Eq
|
||||
|
||||
func (lte Lte) Build(builder Builder) {
|
||||
builder.WriteQuoted(lte.Column)
|
||||
builder.WriteString(" <= ")
|
||||
builder.AddVar(builder, lte.Value)
|
||||
}
|
||||
|
||||
func (lte Lte) NegationBuild(builder Builder) {
|
||||
Gt(lte).Build(builder)
|
||||
}
|
||||
|
||||
// Like whether string matches regular expression
|
||||
type Like Eq
|
||||
|
||||
func (like Like) Build(builder Builder) {
|
||||
builder.WriteQuoted(like.Column)
|
||||
builder.WriteString(" LIKE ")
|
||||
builder.AddVar(builder, like.Value)
|
||||
}
|
||||
|
||||
func (like Like) NegationBuild(builder Builder) {
|
||||
builder.WriteQuoted(like.Column)
|
||||
builder.WriteString(" NOT LIKE ")
|
||||
builder.AddVar(builder, like.Value)
|
||||
}
|
||||
|
||||
func eqNil(value interface{}) bool {
|
||||
if valuer, ok := value.(driver.Valuer); ok && !eqNilReflect(valuer) {
|
||||
value, _ = valuer.Value()
|
||||
}
|
||||
|
||||
return value == nil || eqNilReflect(value)
|
||||
}
|
||||
|
||||
func eqNilReflect(value interface{}) bool {
|
||||
reflectValue := reflect.ValueOf(value)
|
||||
return reflectValue.Kind() == reflect.Ptr && reflectValue.IsNil()
|
||||
}
|
||||
37
vendor/gorm.io/gorm/clause/from.go
generated
vendored
Normal file
37
vendor/gorm.io/gorm/clause/from.go
generated
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
package clause
|
||||
|
||||
// From from clause
|
||||
type From struct {
|
||||
Tables []Table
|
||||
Joins []Join
|
||||
}
|
||||
|
||||
// Name from clause name
|
||||
func (from From) Name() string {
|
||||
return "FROM"
|
||||
}
|
||||
|
||||
// Build build from clause
|
||||
func (from From) Build(builder Builder) {
|
||||
if len(from.Tables) > 0 {
|
||||
for idx, table := range from.Tables {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
|
||||
builder.WriteQuoted(table)
|
||||
}
|
||||
} else {
|
||||
builder.WriteQuoted(currentTable)
|
||||
}
|
||||
|
||||
for _, join := range from.Joins {
|
||||
builder.WriteByte(' ')
|
||||
join.Build(builder)
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge from clause
|
||||
func (from From) MergeClause(clause *Clause) {
|
||||
clause.Expression = from
|
||||
}
|
||||
48
vendor/gorm.io/gorm/clause/group_by.go
generated
vendored
Normal file
48
vendor/gorm.io/gorm/clause/group_by.go
generated
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
package clause
|
||||
|
||||
// GroupBy group by clause
|
||||
type GroupBy struct {
|
||||
Columns []Column
|
||||
Having []Expression
|
||||
}
|
||||
|
||||
// Name from clause name
|
||||
func (groupBy GroupBy) Name() string {
|
||||
return "GROUP BY"
|
||||
}
|
||||
|
||||
// Build build group by clause
|
||||
func (groupBy GroupBy) Build(builder Builder) {
|
||||
for idx, column := range groupBy.Columns {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
|
||||
builder.WriteQuoted(column)
|
||||
}
|
||||
|
||||
if len(groupBy.Having) > 0 {
|
||||
builder.WriteString(" HAVING ")
|
||||
Where{Exprs: groupBy.Having}.Build(builder)
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge group by clause
|
||||
func (groupBy GroupBy) MergeClause(clause *Clause) {
|
||||
if v, ok := clause.Expression.(GroupBy); ok {
|
||||
copiedColumns := make([]Column, len(v.Columns))
|
||||
copy(copiedColumns, v.Columns)
|
||||
groupBy.Columns = append(copiedColumns, groupBy.Columns...)
|
||||
|
||||
copiedHaving := make([]Expression, len(v.Having))
|
||||
copy(copiedHaving, v.Having)
|
||||
groupBy.Having = append(copiedHaving, groupBy.Having...)
|
||||
}
|
||||
clause.Expression = groupBy
|
||||
|
||||
if len(groupBy.Columns) == 0 {
|
||||
clause.Name = ""
|
||||
} else {
|
||||
clause.Name = groupBy.Name()
|
||||
}
|
||||
}
|
||||
39
vendor/gorm.io/gorm/clause/insert.go
generated
vendored
Normal file
39
vendor/gorm.io/gorm/clause/insert.go
generated
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
package clause
|
||||
|
||||
type Insert struct {
|
||||
Table Table
|
||||
Modifier string
|
||||
}
|
||||
|
||||
// Name insert clause name
|
||||
func (insert Insert) Name() string {
|
||||
return "INSERT"
|
||||
}
|
||||
|
||||
// Build build insert clause
|
||||
func (insert Insert) Build(builder Builder) {
|
||||
if insert.Modifier != "" {
|
||||
builder.WriteString(insert.Modifier)
|
||||
builder.WriteByte(' ')
|
||||
}
|
||||
|
||||
builder.WriteString("INTO ")
|
||||
if insert.Table.Name == "" {
|
||||
builder.WriteQuoted(currentTable)
|
||||
} else {
|
||||
builder.WriteQuoted(insert.Table)
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge insert clause
|
||||
func (insert Insert) MergeClause(clause *Clause) {
|
||||
if v, ok := clause.Expression.(Insert); ok {
|
||||
if insert.Modifier == "" {
|
||||
insert.Modifier = v.Modifier
|
||||
}
|
||||
if insert.Table.Name == "" {
|
||||
insert.Table = v.Table
|
||||
}
|
||||
}
|
||||
clause.Expression = insert
|
||||
}
|
||||
47
vendor/gorm.io/gorm/clause/joins.go
generated
vendored
Normal file
47
vendor/gorm.io/gorm/clause/joins.go
generated
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
package clause
|
||||
|
||||
type JoinType string
|
||||
|
||||
const (
|
||||
CrossJoin JoinType = "CROSS"
|
||||
InnerJoin JoinType = "INNER"
|
||||
LeftJoin JoinType = "LEFT"
|
||||
RightJoin JoinType = "RIGHT"
|
||||
)
|
||||
|
||||
// Join clause for from
|
||||
type Join struct {
|
||||
Type JoinType
|
||||
Table Table
|
||||
ON Where
|
||||
Using []string
|
||||
Expression Expression
|
||||
}
|
||||
|
||||
func (join Join) Build(builder Builder) {
|
||||
if join.Expression != nil {
|
||||
join.Expression.Build(builder)
|
||||
} else {
|
||||
if join.Type != "" {
|
||||
builder.WriteString(string(join.Type))
|
||||
builder.WriteByte(' ')
|
||||
}
|
||||
|
||||
builder.WriteString("JOIN ")
|
||||
builder.WriteQuoted(join.Table)
|
||||
|
||||
if len(join.ON.Exprs) > 0 {
|
||||
builder.WriteString(" ON ")
|
||||
join.ON.Build(builder)
|
||||
} else if len(join.Using) > 0 {
|
||||
builder.WriteString(" USING (")
|
||||
for idx, c := range join.Using {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
builder.WriteQuoted(c)
|
||||
}
|
||||
builder.WriteByte(')')
|
||||
}
|
||||
}
|
||||
}
|
||||
46
vendor/gorm.io/gorm/clause/limit.go
generated
vendored
Normal file
46
vendor/gorm.io/gorm/clause/limit.go
generated
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
package clause
|
||||
|
||||
// Limit limit clause
|
||||
type Limit struct {
|
||||
Limit *int
|
||||
Offset int
|
||||
}
|
||||
|
||||
// Name where clause name
|
||||
func (limit Limit) Name() string {
|
||||
return "LIMIT"
|
||||
}
|
||||
|
||||
// Build build where clause
|
||||
func (limit Limit) Build(builder Builder) {
|
||||
if limit.Limit != nil && *limit.Limit >= 0 {
|
||||
builder.WriteString("LIMIT ")
|
||||
builder.AddVar(builder, *limit.Limit)
|
||||
}
|
||||
if limit.Offset > 0 {
|
||||
if limit.Limit != nil && *limit.Limit >= 0 {
|
||||
builder.WriteByte(' ')
|
||||
}
|
||||
builder.WriteString("OFFSET ")
|
||||
builder.AddVar(builder, limit.Offset)
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge order by clauses
|
||||
func (limit Limit) MergeClause(clause *Clause) {
|
||||
clause.Name = ""
|
||||
|
||||
if v, ok := clause.Expression.(Limit); ok {
|
||||
if (limit.Limit == nil || *limit.Limit == 0) && v.Limit != nil {
|
||||
limit.Limit = v.Limit
|
||||
}
|
||||
|
||||
if limit.Offset == 0 && v.Offset > 0 {
|
||||
limit.Offset = v.Offset
|
||||
} else if limit.Offset < 0 {
|
||||
limit.Offset = 0
|
||||
}
|
||||
}
|
||||
|
||||
clause.Expression = limit
|
||||
}
|
||||
38
vendor/gorm.io/gorm/clause/locking.go
generated
vendored
Normal file
38
vendor/gorm.io/gorm/clause/locking.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
package clause
|
||||
|
||||
const (
|
||||
LockingStrengthUpdate = "UPDATE"
|
||||
LockingStrengthShare = "SHARE"
|
||||
LockingOptionsSkipLocked = "SKIP LOCKED"
|
||||
LockingOptionsNoWait = "NOWAIT"
|
||||
)
|
||||
|
||||
type Locking struct {
|
||||
Strength string
|
||||
Table Table
|
||||
Options string
|
||||
}
|
||||
|
||||
// Name where clause name
|
||||
func (locking Locking) Name() string {
|
||||
return "FOR"
|
||||
}
|
||||
|
||||
// Build build where clause
|
||||
func (locking Locking) Build(builder Builder) {
|
||||
builder.WriteString(locking.Strength)
|
||||
if locking.Table.Name != "" {
|
||||
builder.WriteString(" OF ")
|
||||
builder.WriteQuoted(locking.Table)
|
||||
}
|
||||
|
||||
if locking.Options != "" {
|
||||
builder.WriteByte(' ')
|
||||
builder.WriteString(locking.Options)
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge order by clauses
|
||||
func (locking Locking) MergeClause(clause *Clause) {
|
||||
clause.Expression = locking
|
||||
}
|
||||
59
vendor/gorm.io/gorm/clause/on_conflict.go
generated
vendored
Normal file
59
vendor/gorm.io/gorm/clause/on_conflict.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package clause
|
||||
|
||||
type OnConflict struct {
|
||||
Columns []Column
|
||||
Where Where
|
||||
TargetWhere Where
|
||||
OnConstraint string
|
||||
DoNothing bool
|
||||
DoUpdates Set
|
||||
UpdateAll bool
|
||||
}
|
||||
|
||||
func (OnConflict) Name() string {
|
||||
return "ON CONFLICT"
|
||||
}
|
||||
|
||||
// Build build onConflict clause
|
||||
func (onConflict OnConflict) Build(builder Builder) {
|
||||
if onConflict.OnConstraint != "" {
|
||||
builder.WriteString("ON CONSTRAINT ")
|
||||
builder.WriteString(onConflict.OnConstraint)
|
||||
builder.WriteByte(' ')
|
||||
} else {
|
||||
if len(onConflict.Columns) > 0 {
|
||||
builder.WriteByte('(')
|
||||
for idx, column := range onConflict.Columns {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
builder.WriteQuoted(column)
|
||||
}
|
||||
builder.WriteString(`) `)
|
||||
}
|
||||
|
||||
if len(onConflict.TargetWhere.Exprs) > 0 {
|
||||
builder.WriteString(" WHERE ")
|
||||
onConflict.TargetWhere.Build(builder)
|
||||
builder.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
|
||||
if onConflict.DoNothing {
|
||||
builder.WriteString("DO NOTHING")
|
||||
} else {
|
||||
builder.WriteString("DO UPDATE SET ")
|
||||
onConflict.DoUpdates.Build(builder)
|
||||
}
|
||||
|
||||
if len(onConflict.Where.Exprs) > 0 {
|
||||
builder.WriteString(" WHERE ")
|
||||
onConflict.Where.Build(builder)
|
||||
builder.WriteByte(' ')
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge onConflict clauses
|
||||
func (onConflict OnConflict) MergeClause(clause *Clause) {
|
||||
clause.Expression = onConflict
|
||||
}
|
||||
54
vendor/gorm.io/gorm/clause/order_by.go
generated
vendored
Normal file
54
vendor/gorm.io/gorm/clause/order_by.go
generated
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
package clause
|
||||
|
||||
type OrderByColumn struct {
|
||||
Column Column
|
||||
Desc bool
|
||||
Reorder bool
|
||||
}
|
||||
|
||||
type OrderBy struct {
|
||||
Columns []OrderByColumn
|
||||
Expression Expression
|
||||
}
|
||||
|
||||
// Name where clause name
|
||||
func (orderBy OrderBy) Name() string {
|
||||
return "ORDER BY"
|
||||
}
|
||||
|
||||
// Build build where clause
|
||||
func (orderBy OrderBy) Build(builder Builder) {
|
||||
if orderBy.Expression != nil {
|
||||
orderBy.Expression.Build(builder)
|
||||
} else {
|
||||
for idx, column := range orderBy.Columns {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
|
||||
builder.WriteQuoted(column.Column)
|
||||
if column.Desc {
|
||||
builder.WriteString(" DESC")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge order by clauses
|
||||
func (orderBy OrderBy) MergeClause(clause *Clause) {
|
||||
if v, ok := clause.Expression.(OrderBy); ok {
|
||||
for i := len(orderBy.Columns) - 1; i >= 0; i-- {
|
||||
if orderBy.Columns[i].Reorder {
|
||||
orderBy.Columns = orderBy.Columns[i:]
|
||||
clause.Expression = orderBy
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
copiedColumns := make([]OrderByColumn, len(v.Columns))
|
||||
copy(copiedColumns, v.Columns)
|
||||
orderBy.Columns = append(copiedColumns, orderBy.Columns...)
|
||||
}
|
||||
|
||||
clause.Expression = orderBy
|
||||
}
|
||||
34
vendor/gorm.io/gorm/clause/returning.go
generated
vendored
Normal file
34
vendor/gorm.io/gorm/clause/returning.go
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
package clause
|
||||
|
||||
type Returning struct {
|
||||
Columns []Column
|
||||
}
|
||||
|
||||
// Name where clause name
|
||||
func (returning Returning) Name() string {
|
||||
return "RETURNING"
|
||||
}
|
||||
|
||||
// Build build where clause
|
||||
func (returning Returning) Build(builder Builder) {
|
||||
if len(returning.Columns) > 0 {
|
||||
for idx, column := range returning.Columns {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
|
||||
builder.WriteQuoted(column)
|
||||
}
|
||||
} else {
|
||||
builder.WriteByte('*')
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge order by clauses
|
||||
func (returning Returning) MergeClause(clause *Clause) {
|
||||
if v, ok := clause.Expression.(Returning); ok {
|
||||
returning.Columns = append(v.Columns, returning.Columns...)
|
||||
}
|
||||
|
||||
clause.Expression = returning
|
||||
}
|
||||
59
vendor/gorm.io/gorm/clause/select.go
generated
vendored
Normal file
59
vendor/gorm.io/gorm/clause/select.go
generated
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
package clause
|
||||
|
||||
// Select select attrs when querying, updating, creating
|
||||
type Select struct {
|
||||
Distinct bool
|
||||
Columns []Column
|
||||
Expression Expression
|
||||
}
|
||||
|
||||
func (s Select) Name() string {
|
||||
return "SELECT"
|
||||
}
|
||||
|
||||
func (s Select) Build(builder Builder) {
|
||||
if len(s.Columns) > 0 {
|
||||
if s.Distinct {
|
||||
builder.WriteString("DISTINCT ")
|
||||
}
|
||||
|
||||
for idx, column := range s.Columns {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
builder.WriteQuoted(column)
|
||||
}
|
||||
} else {
|
||||
builder.WriteByte('*')
|
||||
}
|
||||
}
|
||||
|
||||
func (s Select) MergeClause(clause *Clause) {
|
||||
if s.Expression != nil {
|
||||
if s.Distinct {
|
||||
if expr, ok := s.Expression.(Expr); ok {
|
||||
expr.SQL = "DISTINCT " + expr.SQL
|
||||
clause.Expression = expr
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
clause.Expression = s.Expression
|
||||
} else {
|
||||
clause.Expression = s
|
||||
}
|
||||
}
|
||||
|
||||
// CommaExpression represents a group of expressions separated by commas.
|
||||
type CommaExpression struct {
|
||||
Exprs []Expression
|
||||
}
|
||||
|
||||
func (comma CommaExpression) Build(builder Builder) {
|
||||
for idx, expr := range comma.Exprs {
|
||||
if idx > 0 {
|
||||
_, _ = builder.WriteString(", ")
|
||||
}
|
||||
expr.Build(builder)
|
||||
}
|
||||
}
|
||||
60
vendor/gorm.io/gorm/clause/set.go
generated
vendored
Normal file
60
vendor/gorm.io/gorm/clause/set.go
generated
vendored
Normal file
@@ -0,0 +1,60 @@
|
||||
package clause
|
||||
|
||||
import "sort"
|
||||
|
||||
type Set []Assignment
|
||||
|
||||
type Assignment struct {
|
||||
Column Column
|
||||
Value interface{}
|
||||
}
|
||||
|
||||
func (set Set) Name() string {
|
||||
return "SET"
|
||||
}
|
||||
|
||||
func (set Set) Build(builder Builder) {
|
||||
if len(set) > 0 {
|
||||
for idx, assignment := range set {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
builder.WriteQuoted(assignment.Column)
|
||||
builder.WriteByte('=')
|
||||
builder.AddVar(builder, assignment.Value)
|
||||
}
|
||||
} else {
|
||||
builder.WriteQuoted(Column{Name: PrimaryKey})
|
||||
builder.WriteByte('=')
|
||||
builder.WriteQuoted(Column{Name: PrimaryKey})
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge assignments clauses
|
||||
func (set Set) MergeClause(clause *Clause) {
|
||||
copiedAssignments := make([]Assignment, len(set))
|
||||
copy(copiedAssignments, set)
|
||||
clause.Expression = Set(copiedAssignments)
|
||||
}
|
||||
|
||||
func Assignments(values map[string]interface{}) Set {
|
||||
keys := make([]string, 0, len(values))
|
||||
for key := range values {
|
||||
keys = append(keys, key)
|
||||
}
|
||||
sort.Strings(keys)
|
||||
|
||||
assignments := make([]Assignment, len(keys))
|
||||
for idx, key := range keys {
|
||||
assignments[idx] = Assignment{Column: Column{Name: key}, Value: values[key]}
|
||||
}
|
||||
return assignments
|
||||
}
|
||||
|
||||
func AssignmentColumns(values []string) Set {
|
||||
assignments := make([]Assignment, len(values))
|
||||
for idx, value := range values {
|
||||
assignments[idx] = Assignment{Column: Column{Name: value}, Value: Column{Table: "excluded", Name: value}}
|
||||
}
|
||||
return assignments
|
||||
}
|
||||
38
vendor/gorm.io/gorm/clause/update.go
generated
vendored
Normal file
38
vendor/gorm.io/gorm/clause/update.go
generated
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
package clause
|
||||
|
||||
type Update struct {
|
||||
Modifier string
|
||||
Table Table
|
||||
}
|
||||
|
||||
// Name update clause name
|
||||
func (update Update) Name() string {
|
||||
return "UPDATE"
|
||||
}
|
||||
|
||||
// Build build update clause
|
||||
func (update Update) Build(builder Builder) {
|
||||
if update.Modifier != "" {
|
||||
builder.WriteString(update.Modifier)
|
||||
builder.WriteByte(' ')
|
||||
}
|
||||
|
||||
if update.Table.Name == "" {
|
||||
builder.WriteQuoted(currentTable)
|
||||
} else {
|
||||
builder.WriteQuoted(update.Table)
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge update clause
|
||||
func (update Update) MergeClause(clause *Clause) {
|
||||
if v, ok := clause.Expression.(Update); ok {
|
||||
if update.Modifier == "" {
|
||||
update.Modifier = v.Modifier
|
||||
}
|
||||
if update.Table.Name == "" {
|
||||
update.Table = v.Table
|
||||
}
|
||||
}
|
||||
clause.Expression = update
|
||||
}
|
||||
45
vendor/gorm.io/gorm/clause/values.go
generated
vendored
Normal file
45
vendor/gorm.io/gorm/clause/values.go
generated
vendored
Normal file
@@ -0,0 +1,45 @@
|
||||
package clause
|
||||
|
||||
type Values struct {
|
||||
Columns []Column
|
||||
Values [][]interface{}
|
||||
}
|
||||
|
||||
// Name from clause name
|
||||
func (Values) Name() string {
|
||||
return "VALUES"
|
||||
}
|
||||
|
||||
// Build build from clause
|
||||
func (values Values) Build(builder Builder) {
|
||||
if len(values.Columns) > 0 {
|
||||
builder.WriteByte('(')
|
||||
for idx, column := range values.Columns {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
builder.WriteQuoted(column)
|
||||
}
|
||||
builder.WriteByte(')')
|
||||
|
||||
builder.WriteString(" VALUES ")
|
||||
|
||||
for idx, value := range values.Values {
|
||||
if idx > 0 {
|
||||
builder.WriteByte(',')
|
||||
}
|
||||
|
||||
builder.WriteByte('(')
|
||||
builder.AddVar(builder, value...)
|
||||
builder.WriteByte(')')
|
||||
}
|
||||
} else {
|
||||
builder.WriteString("DEFAULT VALUES")
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge values clauses
|
||||
func (values Values) MergeClause(clause *Clause) {
|
||||
clause.Name = ""
|
||||
clause.Expression = values
|
||||
}
|
||||
201
vendor/gorm.io/gorm/clause/where.go
generated
vendored
Normal file
201
vendor/gorm.io/gorm/clause/where.go
generated
vendored
Normal file
@@ -0,0 +1,201 @@
|
||||
package clause
|
||||
|
||||
import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
AndWithSpace = " AND "
|
||||
OrWithSpace = " OR "
|
||||
)
|
||||
|
||||
// Where where clause
|
||||
type Where struct {
|
||||
Exprs []Expression
|
||||
}
|
||||
|
||||
// Name where clause name
|
||||
func (where Where) Name() string {
|
||||
return "WHERE"
|
||||
}
|
||||
|
||||
// Build build where clause
|
||||
func (where Where) Build(builder Builder) {
|
||||
if len(where.Exprs) == 1 {
|
||||
if andCondition, ok := where.Exprs[0].(AndConditions); ok {
|
||||
where.Exprs = andCondition.Exprs
|
||||
}
|
||||
}
|
||||
|
||||
// Switch position if the first query expression is a single Or condition
|
||||
for idx, expr := range where.Exprs {
|
||||
if v, ok := expr.(OrConditions); !ok || len(v.Exprs) > 1 {
|
||||
if idx != 0 {
|
||||
where.Exprs[0], where.Exprs[idx] = where.Exprs[idx], where.Exprs[0]
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
buildExprs(where.Exprs, builder, AndWithSpace)
|
||||
}
|
||||
|
||||
func buildExprs(exprs []Expression, builder Builder, joinCond string) {
|
||||
wrapInParentheses := false
|
||||
|
||||
for idx, expr := range exprs {
|
||||
if idx > 0 {
|
||||
if v, ok := expr.(OrConditions); ok && len(v.Exprs) == 1 {
|
||||
builder.WriteString(OrWithSpace)
|
||||
} else {
|
||||
builder.WriteString(joinCond)
|
||||
}
|
||||
}
|
||||
|
||||
if len(exprs) > 1 {
|
||||
switch v := expr.(type) {
|
||||
case OrConditions:
|
||||
if len(v.Exprs) == 1 {
|
||||
if e, ok := v.Exprs[0].(Expr); ok {
|
||||
sql := strings.ToUpper(e.SQL)
|
||||
wrapInParentheses = strings.Contains(sql, AndWithSpace) || strings.Contains(sql, OrWithSpace)
|
||||
}
|
||||
}
|
||||
case AndConditions:
|
||||
if len(v.Exprs) == 1 {
|
||||
if e, ok := v.Exprs[0].(Expr); ok {
|
||||
sql := strings.ToUpper(e.SQL)
|
||||
wrapInParentheses = strings.Contains(sql, AndWithSpace) || strings.Contains(sql, OrWithSpace)
|
||||
}
|
||||
}
|
||||
case Expr:
|
||||
sql := strings.ToUpper(v.SQL)
|
||||
wrapInParentheses = strings.Contains(sql, AndWithSpace) || strings.Contains(sql, OrWithSpace)
|
||||
case NamedExpr:
|
||||
sql := strings.ToUpper(v.SQL)
|
||||
wrapInParentheses = strings.Contains(sql, AndWithSpace) || strings.Contains(sql, OrWithSpace)
|
||||
}
|
||||
}
|
||||
|
||||
if wrapInParentheses {
|
||||
builder.WriteByte('(')
|
||||
expr.Build(builder)
|
||||
builder.WriteByte(')')
|
||||
wrapInParentheses = false
|
||||
} else {
|
||||
expr.Build(builder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MergeClause merge where clauses
|
||||
func (where Where) MergeClause(clause *Clause) {
|
||||
if w, ok := clause.Expression.(Where); ok {
|
||||
exprs := make([]Expression, len(w.Exprs)+len(where.Exprs))
|
||||
copy(exprs, w.Exprs)
|
||||
copy(exprs[len(w.Exprs):], where.Exprs)
|
||||
where.Exprs = exprs
|
||||
}
|
||||
|
||||
clause.Expression = where
|
||||
}
|
||||
|
||||
func And(exprs ...Expression) Expression {
|
||||
if len(exprs) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(exprs) == 1 {
|
||||
if _, ok := exprs[0].(OrConditions); !ok {
|
||||
return exprs[0]
|
||||
}
|
||||
}
|
||||
|
||||
return AndConditions{Exprs: exprs}
|
||||
}
|
||||
|
||||
type AndConditions struct {
|
||||
Exprs []Expression
|
||||
}
|
||||
|
||||
func (and AndConditions) Build(builder Builder) {
|
||||
if len(and.Exprs) > 1 {
|
||||
builder.WriteByte('(')
|
||||
buildExprs(and.Exprs, builder, AndWithSpace)
|
||||
builder.WriteByte(')')
|
||||
} else {
|
||||
buildExprs(and.Exprs, builder, AndWithSpace)
|
||||
}
|
||||
}
|
||||
|
||||
func Or(exprs ...Expression) Expression {
|
||||
if len(exprs) == 0 {
|
||||
return nil
|
||||
}
|
||||
return OrConditions{Exprs: exprs}
|
||||
}
|
||||
|
||||
type OrConditions struct {
|
||||
Exprs []Expression
|
||||
}
|
||||
|
||||
func (or OrConditions) Build(builder Builder) {
|
||||
if len(or.Exprs) > 1 {
|
||||
builder.WriteByte('(')
|
||||
buildExprs(or.Exprs, builder, OrWithSpace)
|
||||
builder.WriteByte(')')
|
||||
} else {
|
||||
buildExprs(or.Exprs, builder, OrWithSpace)
|
||||
}
|
||||
}
|
||||
|
||||
func Not(exprs ...Expression) Expression {
|
||||
if len(exprs) == 0 {
|
||||
return nil
|
||||
}
|
||||
if len(exprs) == 1 {
|
||||
if andCondition, ok := exprs[0].(AndConditions); ok {
|
||||
exprs = andCondition.Exprs
|
||||
}
|
||||
}
|
||||
return NotConditions{Exprs: exprs}
|
||||
}
|
||||
|
||||
type NotConditions struct {
|
||||
Exprs []Expression
|
||||
}
|
||||
|
||||
func (not NotConditions) Build(builder Builder) {
|
||||
if len(not.Exprs) > 1 {
|
||||
builder.WriteByte('(')
|
||||
}
|
||||
|
||||
for idx, c := range not.Exprs {
|
||||
if idx > 0 {
|
||||
builder.WriteString(AndWithSpace)
|
||||
}
|
||||
|
||||
if negationBuilder, ok := c.(NegationExpressionBuilder); ok {
|
||||
negationBuilder.NegationBuild(builder)
|
||||
} else {
|
||||
builder.WriteString("NOT ")
|
||||
e, wrapInParentheses := c.(Expr)
|
||||
if wrapInParentheses {
|
||||
sql := strings.ToUpper(e.SQL)
|
||||
if wrapInParentheses = strings.Contains(sql, AndWithSpace) || strings.Contains(sql, OrWithSpace); wrapInParentheses {
|
||||
builder.WriteByte('(')
|
||||
}
|
||||
}
|
||||
|
||||
c.Build(builder)
|
||||
|
||||
if wrapInParentheses {
|
||||
builder.WriteByte(')')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(not.Exprs) > 1 {
|
||||
builder.WriteByte(')')
|
||||
}
|
||||
}
|
||||
3
vendor/gorm.io/gorm/clause/with.go
generated
vendored
Normal file
3
vendor/gorm.io/gorm/clause/with.go
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
package clause
|
||||
|
||||
type With struct{}
|
||||
Reference in New Issue
Block a user