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

IsZero() and ToNullUUID Helper Functions #113

Open
falsaffa opened this issue Jan 26, 2023 · 3 comments
Open

IsZero() and ToNullUUID Helper Functions #113

falsaffa opened this issue Jan 26, 2023 · 3 comments

Comments

@falsaffa
Copy link

falsaffa commented Jan 26, 2023

Summary

Suggest adding a couple helper functions.

IsZero

IsZero() allows uuid to support the Nullable interface and interface better with existing code. It can be as simple as:

func (u UUID) IsZero() bool {
    return u == Nil
}

This is particularly important when interfacing UUID with the existing ORM libraries. Heck, IsZero() is even used by the reflect package too!

ToNullUUID

Another helper function that is used by this null package (and is quite convenient) are to-null values from the original primitives. So in the case of uuid.UUID and uuuid.NullUUID, adding the following helper function.

func ToNullUUID[T uuid.UUID | uuid.NullUUID](id T) uuid.NullUUID {
	if v, ok := any(id).(uuid.UUID); ok {
		if v == uuid.Nil {
			return uuid.NullUUID{}
		}

		return uuid.NullUUID{v, true}
	} else if v, ok := any(id).(uuid.NullUUID); ok {
		return v
	} else {
		panic("this should not happen")
	}
}

That way we don't have to write the following code:

id := uuid.New()

// If you know that id is not nil
nullVal := uuid.NullUUID{id, true}

// if you don't know whether or not id is nil.
nullVal := uuid.NullUUID{id, id == uuid.Nil}

// And if you want to use named struct fields
nullVal := uuid.NullUUID{UUID: id, Valid: id == uuid.Nil}

// What it looks like with the helper function
nullVal := uuid.ToNullUUID(id)

This is particularly useful when combined with existing libraries such as ORMs. Casting to uuid.NullUUID is common.

@matwachich
Copy link

I had a similar problem in a DB (SQLite), where I have FK to UUIDs

I have a table where the FK can be NULL (not linked to any parent record), and passing a uuid.Nil caused a FK constraint violation.

It seems to me more logic that a uuid.Nil is stored as NULL in a database. But It's only my personal use case... so not sure at all.

@zyrthofar
Copy link

Is there any plan for this feature, specifically the IsZero method?

I'm using upper/db (relevant code here), but I believe this would be similar in other ORMs. Having an IsZero() bool method would allow deferring a PK UUID to be generated at the database where that belongs:

...Insert(Resource{Code: "code"}) // ID is the zero-value of uuid.UUID

while currently, the application always needs to handle the UUID, because otherwise it is set as 00000000-0000-0000-0000-000000000000 in the database, failing the second time because it already exists:

...Insert(Resource{ID: uuid.New(), Code: "code"})

Please tell me if I can help with this, I can make a PR soon if it would be handled by a maintainer.

@joow
Copy link

joow commented Nov 27, 2024

Implementing IsZero() bool would also support the upcoming omitzero option for JSON marshalling to omit zero UUID values : golang/go#45669 (comment)

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

No branches or pull requests

4 participants