Repository: go-gorm/gorm
Pull request #3492 (2020-09-19 04:04:23)

Fix format sql log
<!--
Make sure these boxes checked before submitting your pull request.

For significant changes, please open an issue to make an agreement on an implementation design/plan first before starting it.
-->

- [] Do only one thing
- [] Non breaking API changes
- [] Tested

### What did this pull request do?

<!--
provide a general description of the code changes in your pull request
-->

### User Case Description

<!-- Your use case -->



Patch:
diff --git a/logger/sql.go b/logger/sql.go
index 69a6b10..138a35e 100644
--- a/logger/sql.go
+++ b/logger/sql.go
@@ -52,9 +52,9 @@ func ExplainSQL(sql string, numericPlaceholder *regexp.Regexp, escaper string, a
 			vars[idx] = escaper + strings.Replace(fmt.Sprintf("%v", v), escaper, "\\"+escaper, -1) + escaper
 		case driver.Valuer:
 			reflectValue := reflect.ValueOf(v)
-			if v != nil && reflectValue.IsValid() && (reflectValue.Kind() == reflect.Ptr && !reflectValue.IsNil()) {
+			if v != nil && reflectValue.IsValid() && ((reflectValue.Kind() == reflect.Ptr && !reflectValue.IsNil()) || reflectValue.Kind() != reflect.Ptr) {
 				r, _ := v.Value()
-				vars[idx] = fmt.Sprintf("%v", r)
+				convertParams(r, idx)
 			} else {
 				vars[idx] = "NULL"
 			}


Test patch:
diff --git a/logger/sql_test.go b/logger/sql_test.go
index b78f761..71aa841 100644
--- a/logger/sql_test.go
+++ b/logger/sql_test.go
@@ -1,13 +1,39 @@
 package logger_test
 
 import (
+	"database/sql/driver"
+	"encoding/json"
+	"fmt"
 	"regexp"
+	"strings"
 	"testing"
 
 	"github.com/jinzhu/now"
 	"gorm.io/gorm/logger"
 )
 
+type JSON json.RawMessage
+
+func (j JSON) Value() (driver.Value, error) {
+	if len(j) == 0 {
+		return nil, nil
+	}
+	return json.RawMessage(j).MarshalJSON()
+}
+
+type ExampleStruct struct {
+	Name string
+	Val  string
+}
+
+func (s ExampleStruct) Value() (driver.Value, error) {
+	return json.Marshal(s)
+}
+
+func format(v []byte, escaper string) string {
+	return escaper + strings.Replace(string(v), escaper, "\\"+escaper, -1) + escaper
+}
+
 func TestExplainSQL(t *testing.T) {
 	type role string
 	type password []byte
@@ -15,6 +41,10 @@ func TestExplainSQL(t *testing.T) {
 		tt     = now.MustParse("2020-02-23 11:10:10")
 		myrole = role("admin")
 		pwd    = password([]byte("pass"))
+		jsVal  = []byte(`{"Name":"test","Val":"test"}`)
+		js     = JSON(jsVal)
+		esVal  = []byte(`{"Name":"test","Val":"test"}`)
+		es     = ExampleStruct{Name: "test", Val: "test"}
 	)
 
 	results := []struct {
@@ -53,6 +83,18 @@ func TestExplainSQL(t *testing.T) {
 			Vars:          []interface{}{"jinzhu", 999.99, true, []byte("12345"), tt, &tt, nil, "w@g.com", myrole, pwd, 1},
 			Result:        `create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass) values ("jinzhu", 1, 999.990000, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.com", "admin", "pass")`,
 		},
+		{
+			SQL:           "create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+			NumericRegexp: nil,
+			Vars:          []interface{}{"jinzhu", 1, 999.99, true, []byte("12345"), tt, &tt, nil, "w@g.\"com", myrole, pwd, js, es},
+			Result:        fmt.Sprintf(`create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values ("jinzhu", 1, 999.990000, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.\"com", "admin", "pass", %v, %v)`, format(jsVal, `"`), format(esVal, `"`)),
+		},
+		{
+			SQL:           "create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
+			NumericRegexp: nil,
+			Vars:          []interface{}{"jinzhu", 1, 999.99, true, []byte("12345"), tt, &tt, nil, "w@g.\"com", myrole, pwd, &js, &es},
+			Result:        fmt.Sprintf(`create table users (name, age, height, actived, bytes, create_at, update_at, deleted_at, email, role, pass, json_struct, example_struct) values ("jinzhu", 1, 999.990000, true, "12345", "2020-02-23 11:10:10", "2020-02-23 11:10:10", NULL, "w@g.\"com", "admin", "pass", %v, %v)`, format(jsVal, `"`), format(esVal, `"`)),
+		},
 	}
 
 	for idx, r := range results {