Skip to content

refactor: use Go 1.27 standard library uuid instead of satori/go.uuid - #278

Open
whywaita wants to merge 6 commits into
masterfrom
refactor/use-std-uuid
Open

whywaita wants to merge 6 commits into
masterfrom
refactor/use-std-uuid

Conversation

@whywaita

@whywaita whywaita commented Aug 20, 2026

Copy link
Copy Markdown
Owner

Summary

Migrate the internal UUID implementation from the third-party github.com/satori/go.uuid package to the standard library uuid package introduced in Go 1.27.

Changes

UUID migration (API mapping)

  • uuid.FromString(...)uuid.Parse(...)
  • uuid.FromStringOrNil(...)uuid.MustParse(...) (test-only, fixed UUID strings)
  • uuid.Equal(a, b)a == b (std uuid.UUID is a comparable [16]byte)
  • uuid.NewV4() / uuid.UUID / uuid.UUID{} / .String() are API-compatible
  • go.mod: go 1.25go 1.27, drop the satori/go.uuid dependency

DB layer (mysql)
std uuid.UUID does not implement driver.Valuer / sql.Scanner (unlike satori). UUID columns are VARCHAR(36), so DB I/O is handled as strings:

  • INSERT/WHERE: bind uuid.UUID.String() (CreateTarget, EnqueueJob)
  • SELECT: scan into shadow structs whose UUID columns are strings, then parse back into datastore entities with uuid.Parse
  • The domain type stays std uuid.UUID (no ripple into memory/web/runner/starter); DB conversion is confined to the mysql package

CI

  • staticcheck@latest (v0.7.0) cannot decode Go 1.27 export data (version 4), so pin staticcheck to v0.8.0-rc.1
  • Bump the Dockerfile builder image golang:1.25golang:1.27

Verification

  • go build ./... / go vet ./... OK
  • Full test suite (mysql/web incl.) passes in CI
  • docker-build-test / docker-build-sha pass
  • staticcheck / lint pass

Replace github.com/satori/go.uuid with the standard library uuid package
added in Go 1.27.

- uuid.FromString -> uuid.Parse
- uuid.FromStringOrNil -> uuid.MustParse
- uuid.Equal(a, b) -> a == b (UUID is a comparable [16]byte)
- uuid.NewV4 / uuid.UUID / uuid.UUID{} map 1:1

Bump go directive 1.25 -> 1.27 and drop the satori/go.uuid module.
go.mod now requires Go >= 1.27 (standard library uuid), and the
Dockerfile uses GOTOOLCHAIN=local, so the builder image must be 1.27.
staticcheck@latest resolves to v0.7.0 (2026.1), whose bundled x/tools
cannot decode Go 1.27's export data (version 4) and fails with an internal
error. v0.8.0-rc.1 (2026.2rc1) supports Go 1.27 and passes cleanly on the
module.
The standard library uuid.UUID is a [16]byte with no driver.Valuer or
sql.Scanner, unlike satori/go.uuid. UUID columns are VARCHAR(36), so:

- Writes: pass uuid.UUID.String() when binding (CreateTarget, EnqueueJob).
- Reads: scan rows into shadow structs whose UUID columns are strings, then
  parse back into datastore entities with uuid.Parse.

Keeps the domain type as std uuid.UUID (no ripple into memory/web/runner/
starter) and confines DB conversion to the mysql package.
The sql.*FromSQL test helpers bound uuid.UUID directly to prepared
statements, which fails with std uuid (no driver.Valuer/Scanner). Bind
uuid.String() and scan into local shadow rows (UUID columns as strings)
then parse back into datastore entities.
Comment thread pkg/datastore/mysql/job.go Outdated
UpdatedAt time.Time `db:"updated_at"`
}

func (r rowJob) job() (datastore.Job, error) {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Be Go.

Suggested change
func (r rowJob) job() (datastore.Job, error) {
func (r rowJob) job() (*datastore.Job, error) {

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed — this approach was replaced entirely. Instead of the shadow rowJob struct, I introduced datastore.UUID, which wraps std uuid.UUID and implements driver.Valuer + sql.Scanner. The datastore entity structs now use it, so sqlx binds/scans UUID columns directly and the mysql layer goes back to plain queries (no rowJob/rowRunner/rowTarget + string conversion). This makes the code cleaner and removes the need for this helper function altogether.

Implement a datastore.UUID type wrapping std uuid.UUID that implements
driver.Valuer and sql.Scanner, and use it for the datastore entity structs
and interface. This lets sqlx bind and scan UUID columns directly, so the
mysql layer no longer needs shadow structs + string conversion.

- New pkg/datastore/uuid.go: datastore.UUID (Valuer + Scanner)
- datastore entity structs and Datastore interface use datastore.UUID
- mysql: revert to direct queries (CreateTarget/EnqueueJob bind fields as-is)
- memory/web/runner/starter/metric: adapted to datastore.UUID
- tests updated accordingly

Responds to the review comment on PR #278.
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.

1 participant