Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【FIX】Fix the issue where conversion fails when converting from sql.NullXXX types to basic types when selecting deepCopy option. #177

Merged
merged 2 commits into from
May 13, 2023

Conversation

jiang4869
Copy link
Contributor

Problem Description

type User struct {
	Phone sql.NullString `json:"phone"`
}

func main() {
	phone := "12122255555"
	a := struct {
		Phone string `json:"phone"`
	}{
		Phone: phone,
	}
	u := &User{}
	err := copier.CopyWithOption(&u, a, copier.Option{DeepCopy: true, IgnoreEmpty: true})
	fmt.Println(err)
	fmt.Println(a)
	fmt.Println(u)
}

output

<nil>
{12122255555}
&{{ false}} 

The value of a.Phone was not copied to user.Phone, which is obviously not expected.

Solution

After verification, this is because the deepCopy option was added. Because when deepCopy is added, the following code is executed first. Since sql.NullXXX types are structures, the code returns directly. Although custom conversion can be used to solve this problem, it is not very elegant.

		if deepCopy {
			toKind := to.Kind()
			if toKind == reflect.Interface && to.IsNil() {
				if reflect.TypeOf(from.Interface()) != nil {
					to.Set(reflect.New(reflect.TypeOf(from.Interface())).Elem())
					toKind = reflect.TypeOf(to.Interface()).Kind()
				}
			}
			if from.Kind() == reflect.Ptr && from.IsNil() {
				return true
			}
			if toKind == reflect.Struct || toKind == reflect.Map || toKind == reflect.Slice {
				return false
			}
		}

Therefore, when judging whether it is a structure, exclude sql.NullXXX types first.

	if _, ok := to.Addr().Interface().(sql.Scanner); !ok && (toKind == reflect.Struct || toKind == reflect.Map || toKind == reflect.Slice) {
			return false, nil
		}

After the modification, the output of the above code is as follows. I have also added a unit test to ensure the correctness of other types.

<nil>
{12122255555}        
&{{12122255555 true}}

@jiang4869 jiang4869 changed the title 【FIX】修复当选择deepCopy时,从基础类型转到sql.NullXXX类型时,转换失败的问题 【FIX】Fix the issue where conversion fails when converting from basic types to sql.NullXXX types when selecting deepCopy option. Apr 5, 2023
@jiang4869
Copy link
Contributor Author

@jinzhu 能看下这个pr吗?

@jiang4869 jiang4869 changed the title 【FIX】Fix the issue where conversion fails when converting from basic types to sql.NullXXX types when selecting deepCopy option. 【FIX】Fix the issue where conversion fails when converting from sql.NullXXX types to basic types when selecting deepCopy option. Apr 26, 2023
@jinzhu jinzhu merged commit 83982c7 into jinzhu:master May 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants