2019-06-21 13:56:57 +02:00
|
|
|
package jet
|
2019-04-14 17:55:10 +02:00
|
|
|
|
2019-04-20 19:49:29 +02:00
|
|
|
import (
|
2020-06-27 18:48:19 +02:00
|
|
|
"github.com/go-jet/jet/v2/internal/utils"
|
2019-06-05 17:15:20 +02:00
|
|
|
"reflect"
|
2022-01-05 18:00:20 +01:00
|
|
|
"strings"
|
2019-04-20 19:49:29 +02:00
|
|
|
)
|
2019-04-14 17:55:10 +02:00
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// SerializeClauseList func
|
|
|
|
|
func SerializeClauseList(statement StatementType, clauses []Serializer, out *SQLBuilder) {
|
2019-05-07 19:06:21 +02:00
|
|
|
|
|
|
|
|
for i, c := range clauses {
|
|
|
|
|
if i > 0 {
|
2019-08-03 14:10:47 +02:00
|
|
|
out.WriteString(", ")
|
2019-05-07 19:06:21 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if c == nil {
|
2019-08-13 13:57:26 +02:00
|
|
|
panic("jet: nil clause")
|
2019-05-07 19:06:21 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-13 13:57:26 +02:00
|
|
|
c.serialize(statement, out)
|
2019-05-07 19:06:21 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-10-21 13:35:37 +02:00
|
|
|
func serializeExpressionList(
|
|
|
|
|
statement StatementType,
|
|
|
|
|
expressions []Expression,
|
|
|
|
|
separator string,
|
|
|
|
|
out *SQLBuilder,
|
|
|
|
|
options ...SerializeOption) {
|
|
|
|
|
|
|
|
|
|
for i, expression := range expressions {
|
2019-04-29 14:39:48 +02:00
|
|
|
if i > 0 {
|
2019-08-03 14:10:47 +02:00
|
|
|
out.WriteString(separator)
|
2019-04-29 14:39:48 +02:00
|
|
|
}
|
|
|
|
|
|
2021-12-07 14:07:44 +01:00
|
|
|
if expression != nil {
|
|
|
|
|
expression.serialize(statement, out, options...)
|
|
|
|
|
}
|
2019-04-14 17:55:10 +02:00
|
|
|
}
|
|
|
|
|
}
|
2019-04-20 19:49:29 +02:00
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// SerializeProjectionList func
|
|
|
|
|
func SerializeProjectionList(statement StatementType, projections []Projection, out *SQLBuilder) {
|
2019-04-29 14:39:48 +02:00
|
|
|
for i, col := range projections {
|
|
|
|
|
if i > 0 {
|
2019-08-03 14:10:47 +02:00
|
|
|
out.WriteString(",")
|
2019-08-11 12:13:59 +02:00
|
|
|
out.NewLine()
|
2019-04-29 14:39:48 +02:00
|
|
|
}
|
2019-05-12 18:15:23 +02:00
|
|
|
|
2019-04-29 14:39:48 +02:00
|
|
|
if col == nil {
|
2019-08-13 13:57:26 +02:00
|
|
|
panic("jet: Projection is nil")
|
2019-04-29 14:39:48 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-13 13:57:26 +02:00
|
|
|
col.serializeForProjection(statement, out)
|
2019-04-29 14:39:48 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// SerializeColumnNames func
|
|
|
|
|
func SerializeColumnNames(columns []Column, out *SQLBuilder) {
|
2019-04-29 14:39:48 +02:00
|
|
|
for i, col := range columns {
|
|
|
|
|
if i > 0 {
|
2019-08-03 14:10:47 +02:00
|
|
|
out.WriteString(", ")
|
2019-04-29 14:39:48 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if col == nil {
|
2019-08-13 13:57:26 +02:00
|
|
|
panic("jet: nil column in columns list")
|
2019-04-29 14:39:48 +02:00
|
|
|
}
|
|
|
|
|
|
2020-05-02 22:15:38 +02:00
|
|
|
out.WriteIdentifier(col.Name())
|
2019-04-29 14:39:48 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-29 19:07:59 +01:00
|
|
|
// SerializeColumnExpressions func
|
|
|
|
|
func SerializeColumnExpressions(columns []ColumnExpression, statementType StatementType,
|
2020-04-12 18:53:57 +02:00
|
|
|
out *SQLBuilder, options ...SerializeOption) {
|
|
|
|
|
for i, col := range columns {
|
|
|
|
|
if i > 0 {
|
|
|
|
|
out.WriteString(", ")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if col == nil {
|
|
|
|
|
panic("jet: nil column in columns list")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
col.serialize(statementType, out, options...)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2021-12-29 19:07:59 +01:00
|
|
|
// SerializeColumnExpressionNames func
|
|
|
|
|
func SerializeColumnExpressionNames(columns []ColumnExpression, out *SQLBuilder) {
|
|
|
|
|
for i, col := range columns {
|
|
|
|
|
if i > 0 {
|
|
|
|
|
out.WriteString(", ")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if col == nil {
|
|
|
|
|
panic("jet: nil column in columns list")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out.WriteIdentifier(col.Name())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-12-08 11:07:49 +01:00
|
|
|
// ExpressionListToSerializerList converts list of expressions to list of serializers
|
2019-12-01 18:25:30 +01:00
|
|
|
func ExpressionListToSerializerList(expressions []Expression) []Serializer {
|
|
|
|
|
var ret []Serializer
|
|
|
|
|
|
|
|
|
|
for _, expr := range expressions {
|
|
|
|
|
ret = append(ret, expr)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// ColumnListToProjectionList func
|
2019-08-11 14:29:03 +02:00
|
|
|
func ColumnListToProjectionList(columns []ColumnExpression) []Projection {
|
2019-08-03 14:10:47 +02:00
|
|
|
var ret []Projection
|
2019-06-15 13:58:45 +02:00
|
|
|
|
|
|
|
|
for _, column := range columns {
|
|
|
|
|
ret = append(ret, column)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-12 18:53:57 +02:00
|
|
|
// ToSerializerValue creates Serializer type from the value
|
|
|
|
|
func ToSerializerValue(value interface{}) Serializer {
|
2019-08-11 09:52:02 +02:00
|
|
|
if clause, ok := value.(Serializer); ok {
|
2019-06-14 14:35:50 +02:00
|
|
|
return clause
|
|
|
|
|
}
|
2019-07-18 17:43:11 +02:00
|
|
|
|
|
|
|
|
return literal(value)
|
2019-06-14 14:35:50 +02:00
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// UnwindRowFromModel func
|
2019-08-11 14:29:03 +02:00
|
|
|
func UnwindRowFromModel(columns []Column, data interface{}) []Serializer {
|
2019-06-14 14:35:50 +02:00
|
|
|
structValue := reflect.Indirect(reflect.ValueOf(data))
|
|
|
|
|
|
2019-08-11 09:52:02 +02:00
|
|
|
row := []Serializer{}
|
2019-06-14 14:35:50 +02:00
|
|
|
|
2019-08-13 13:57:26 +02:00
|
|
|
utils.ValueMustBe(structValue, reflect.Struct, "jet: data has to be a struct")
|
2019-06-14 14:35:50 +02:00
|
|
|
|
|
|
|
|
for _, column := range columns {
|
|
|
|
|
columnName := column.Name()
|
2019-07-04 17:54:15 +02:00
|
|
|
structFieldName := utils.ToGoIdentifier(columnName)
|
2019-06-14 14:35:50 +02:00
|
|
|
|
|
|
|
|
structField := structValue.FieldByName(structFieldName)
|
|
|
|
|
|
|
|
|
|
if !structField.IsValid() {
|
2019-08-12 11:33:46 +02:00
|
|
|
panic("missing struct field for column : " + columnName)
|
2019-06-14 14:35:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var field interface{}
|
|
|
|
|
|
|
|
|
|
if structField.Kind() == reflect.Ptr && structField.IsNil() {
|
|
|
|
|
field = nil
|
|
|
|
|
} else {
|
|
|
|
|
field = reflect.Indirect(structField).Interface()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
row = append(row, literal(field))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return row
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// UnwindRowsFromModels func
|
2019-08-11 14:29:03 +02:00
|
|
|
func UnwindRowsFromModels(columns []Column, data interface{}) [][]Serializer {
|
2019-06-30 11:53:35 +02:00
|
|
|
sliceValue := reflect.Indirect(reflect.ValueOf(data))
|
2019-08-13 13:57:26 +02:00
|
|
|
utils.ValueMustBe(sliceValue, reflect.Slice, "jet: data has to be a slice.")
|
2019-06-30 11:53:35 +02:00
|
|
|
|
2019-08-11 09:52:02 +02:00
|
|
|
rows := [][]Serializer{}
|
2019-06-30 11:53:35 +02:00
|
|
|
|
|
|
|
|
for i := 0; i < sliceValue.Len(); i++ {
|
|
|
|
|
structValue := sliceValue.Index(i)
|
|
|
|
|
|
2019-08-11 09:52:02 +02:00
|
|
|
rows = append(rows, UnwindRowFromModel(columns, structValue.Interface()))
|
2019-06-30 11:53:35 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return rows
|
|
|
|
|
}
|
|
|
|
|
|
2019-08-17 18:32:01 +02:00
|
|
|
// UnwindRowFromValues func
|
2019-08-11 09:52:02 +02:00
|
|
|
func UnwindRowFromValues(value interface{}, values []interface{}) []Serializer {
|
|
|
|
|
row := []Serializer{}
|
2019-06-14 14:35:50 +02:00
|
|
|
|
|
|
|
|
allValues := append([]interface{}{value}, values...)
|
|
|
|
|
|
|
|
|
|
for _, val := range allValues {
|
2020-04-12 18:53:57 +02:00
|
|
|
row = append(row, ToSerializerValue(val))
|
2019-06-14 14:35:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return row
|
|
|
|
|
}
|
2019-08-17 18:32:01 +02:00
|
|
|
|
|
|
|
|
// UnwindColumns func
|
|
|
|
|
func UnwindColumns(column1 Column, columns ...Column) []Column {
|
|
|
|
|
columnList := []Column{}
|
|
|
|
|
|
2019-09-26 12:31:03 +02:00
|
|
|
if val, ok := column1.(ColumnList); ok {
|
|
|
|
|
for _, col := range val {
|
2019-08-17 18:32:01 +02:00
|
|
|
columnList = append(columnList, col)
|
|
|
|
|
}
|
|
|
|
|
columnList = append(columnList, columns...)
|
|
|
|
|
} else {
|
|
|
|
|
columnList = append(columnList, column1)
|
|
|
|
|
columnList = append(columnList, columns...)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return columnList
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// UnwidColumnList func
|
|
|
|
|
func UnwidColumnList(columns []Column) []Column {
|
|
|
|
|
ret := []Column{}
|
|
|
|
|
|
|
|
|
|
for _, col := range columns {
|
2019-09-26 12:31:03 +02:00
|
|
|
if columnList, ok := col.(ColumnList); ok {
|
|
|
|
|
for _, c := range columnList {
|
2019-08-17 18:32:01 +02:00
|
|
|
ret = append(ret, c)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
ret = append(ret, col)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return ret
|
|
|
|
|
}
|
2020-02-09 18:37:48 +01:00
|
|
|
|
|
|
|
|
// OptionalOrDefaultString will return first value from variable argument list str or
|
|
|
|
|
// defaultStr if variable argument list is empty
|
|
|
|
|
func OptionalOrDefaultString(defaultStr string, str ...string) string {
|
|
|
|
|
if len(str) > 0 {
|
|
|
|
|
return str[0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return defaultStr
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OptionalOrDefaultExpression will return first value from variable argument list expression or
|
|
|
|
|
// defaultExpression if variable argument list is empty
|
|
|
|
|
func OptionalOrDefaultExpression(defaultExpression Expression, expression ...Expression) Expression {
|
|
|
|
|
if len(expression) > 0 {
|
|
|
|
|
return expression[0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return defaultExpression
|
|
|
|
|
}
|
2022-01-05 18:00:20 +01:00
|
|
|
|
|
|
|
|
func extractTableAndColumnName(alias string) (tableName string, columnName string) {
|
|
|
|
|
parts := strings.Split(alias, ".")
|
|
|
|
|
|
|
|
|
|
if len(parts) >= 2 {
|
|
|
|
|
tableName = parts[0]
|
|
|
|
|
columnName = parts[1]
|
|
|
|
|
} else {
|
|
|
|
|
columnName = parts[0]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func serializeToDefaultDebugString(expr Serializer) string {
|
|
|
|
|
out := SQLBuilder{Dialect: defaultDialect, Debug: true}
|
|
|
|
|
expr.serialize(SelectStatementType, &out)
|
|
|
|
|
return out.Buff.String()
|
|
|
|
|
}
|