0

I tried to written an simple ORM for MySQL, I got a problem, if a defined struct missing some field:

type User struct {
    ID        int64
    Username  string
    Password  string
    Email     string
    Comment   string
}

var u = User{Username: "user_0001", Password: "password"}

Some fields of User didn't given a value, then it's value will be a zeroed value, such as string "", bool false, integer 0 and so on.

So I am using reflect to get field name and value, generate a sql to insert row.

INSERT INTO User (Id, Username, Password, Email, Comment) Values (0, "user_0001", "password", , ,)

You can see there has some zeroed value of string, if I detect empty string "" and skip them, I may skip normal value.

2 Answers 2

2

To handle database columns that may be NULL, you can either use pointers as Friedrich Große suggests, or use the Null...-variants found in the db package, for instance sql.NullString.

To use the Null-variants, the struct would be

type User struct {
    ID        int64
    Username  string
    Password  string
    Email     sql.NullString
    Comment   sql.NullString
}

You can then detect of a value is set by checking NullString.Valid. The downside of using NullString is that you have to add special cases when printing or marshaling them, as they don't implement the Stringer interface, nor MarshalJSON or UnmarshalJSON. You also have to remember to set NullString.Valid manually when setting the value of the string.

For instance, a test like

func TestNullString(t *testing.T) {
    s := sql.NullString{}
    t.Log(s)

    s.String = "Test"
    s.Valid = true
    t.Log(s)
}

Prints

null_string_test.go:21: { false}
null_string_test.go:25: {Test true}

To print a NullString you have to instead do

func TestNullString(t *testing.T) {
    s := sql.NullString{}
    t.Log(s.String)

    s.String = "Test"
    s.Value = true
    t.Log(s.String)
}

Which prints:

null_string_test.go:21: 
null_string_test.go:25: Test
Sign up to request clarification or add additional context in comments.

Comments

1

You can always just insert an empty string into your table column. If it is truly important to know the difference between the zero value or complete absence of a value you would need to use pointers.

type User struct {
    ID        int64
    Username  *string
}

This changes the zero value to be nil so you can distinguish that from "". The downside is that this makes this type less easy to use (nil checks are often forgotten in practice) and you have to dereference that field to get the actual string.

In your specific example I don't see why you need to worry about the empty value at all. Can't you just insert "" into the database and enforce validation (non-emptiness) in your code instead of using database constraints?

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.