Field value wrapper function feature implemented. Now you can wrap field value into user-defined wrapper function(s) with setting it using WRAPPER tag. Wrapper functions are used with INSERT/UPDATE operations to allow you to use DBMS functions when inserting/updating a field value (eg. ST_GeomFromText(?), LOWER(?), EXTRACT(YEAR FROM ?))

This commit is contained in:
Aleksandr Kretov 2018-05-30 21:45:54 +10:00
parent 82eb9f8a5b
commit db9f275317
3 changed files with 14 additions and 4 deletions

View File

@ -65,13 +65,13 @@ func createCallback(scope *Scope) {
scope.InstanceSet("gorm:blank_columns_with_default_value", blankColumnsWithDefaultValue) scope.InstanceSet("gorm:blank_columns_with_default_value", blankColumnsWithDefaultValue)
} else if !field.IsPrimaryKey || !field.IsBlank { } else if !field.IsPrimaryKey || !field.IsBlank {
columns = append(columns, scope.Quote(field.DBName)) columns = append(columns, scope.Quote(field.DBName))
placeholders = append(placeholders, scope.AddToVars(field.Field.Interface())) placeholders = append(placeholders, scope.WrapPlaceholder(field, scope.AddToVars(field.Field.Interface())))
} }
} else if field.Relationship != nil && field.Relationship.Kind == "belongs_to" { } else if field.Relationship != nil && field.Relationship.Kind == "belongs_to" {
for _, foreignKey := range field.Relationship.ForeignDBNames { for _, foreignKey := range field.Relationship.ForeignDBNames {
if foreignField, ok := scope.FieldByName(foreignKey); ok && !scope.changeableField(foreignField) { if foreignField, ok := scope.FieldByName(foreignKey); ok && !scope.changeableField(foreignField) {
columns = append(columns, scope.Quote(foreignField.DBName)) columns = append(columns, scope.Quote(foreignField.DBName))
placeholders = append(placeholders, scope.AddToVars(foreignField.Field.Interface())) placeholders = append(placeholders, scope.WrapPlaceholder(foreignField, scope.AddToVars(foreignField.Field.Interface())))
} }
} }
} }

View File

@ -76,12 +76,12 @@ func updateCallback(scope *Scope) {
for _, field := range scope.Fields() { for _, field := range scope.Fields() {
if scope.changeableField(field) { if scope.changeableField(field) {
if !field.IsPrimaryKey && field.IsNormal { if !field.IsPrimaryKey && field.IsNormal {
sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(field.DBName), scope.AddToVars(field.Field.Interface()))) sqls = append(sqls, fmt.Sprintf("%v = %v", scope.Quote(field.DBName), scope.WrapPlaceholder(field, scope.AddToVars(field.Field.Interface()))))
} else if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" { } else if relationship := field.Relationship; relationship != nil && relationship.Kind == "belongs_to" {
for _, foreignKey := range relationship.ForeignDBNames { for _, foreignKey := range relationship.ForeignDBNames {
if foreignField, ok := scope.FieldByName(foreignKey); ok && !scope.changeableField(foreignField) { if foreignField, ok := scope.FieldByName(foreignKey); ok && !scope.changeableField(foreignField) {
sqls = append(sqls, sqls = append(sqls,
fmt.Sprintf("%v = %v", scope.Quote(foreignField.DBName), scope.AddToVars(foreignField.Field.Interface()))) fmt.Sprintf("%v = %v", scope.Quote(foreignField.DBName), scope.WrapPlaceholder(foreignField, scope.AddToVars(foreignField.Field.Interface()))))
} }
} }
} }

View File

@ -277,6 +277,16 @@ func (scope *Scope) AddToVars(value interface{}) string {
return scope.Dialect().BindVar(len(scope.SQLVars)) return scope.Dialect().BindVar(len(scope.SQLVars))
} }
// WrapPlaceholder returns a field's value placeholder wrapped into wrapper function
func (scope *Scope) WrapPlaceholder(field *Field, placeholder string) string {
if wr, exists := field.TagSettings["WRAPPER"]; !exists || len(wr) == 0 {
return placeholder
} else {
// Wrap a placeholder into wrapper
return strings.Replace(wr, "?", placeholder, 1)
}
}
// SelectAttrs return selected attributes // SelectAttrs return selected attributes
func (scope *Scope) SelectAttrs() []string { func (scope *Scope) SelectAttrs() []string {
if scope.selectAttrs == nil { if scope.selectAttrs == nil {