fix: classify duplicate-key Insert as record.IsAlreadyExists - #30
Merged
Merged
Conversation
Bump dal-go/dalgo2sql to v0.11.0 (adds the DbOptions.IsAlreadyExists classifier hook), dal-go/dalgo to v0.66.1 (adds the now-passing unconditional dalgotest conformance check), and dal-go/record to v0.1.3 (adds ErrRecordExists/IsAlreadyExists). Add IsAlreadyExists, this adapter's classifier for modernc.org/sqlite (the pure-Go driver dalgo2sqlite registers): it matches errors.As(err, *sqlite.Error) against the extended result codes SQLITE_CONSTRAINT_PRIMARYKEY (1555) and SQLITE_CONSTRAINT_UNIQUE (2067), never on message text. Both codes are matched deliberately — a duplicate primary key reports 1555, not 2067, and is the commonest case (verified against modernc.org/sqlite@v1.57.0's lib/sqlite.go and by confirming this repo's own conformance suite fails with exactly that code when the wiring below is reverted). The primary result code SQLITE_CONSTRAINT (19) is deliberately not matched: it also covers NOT NULL, CHECK, and FOREIGN KEY violations, none of which are duplicate keys. Wire it into NewDatabaseWithOptions as the default whenever the caller-supplied DbOptions leaves IsAlreadyExists nil, so NewDatabase and every existing caller building their own DbOptions (including this package's own TestConformance) get classification with no extra configuration, while still allowing an explicit override. Exported so a caller assembling a custom DbOptions from scratch can reuse or compose with it directly. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
dal-go/dalgo2sqlto v0.11.0 (adds theDbOptions.IsAlreadyExistsclassifier hook),dal-go/dalgoto v0.66.1 (adds the now-passing unconditionaldalgotestconformance check), anddal-go/recordto v0.1.3 (addsErrRecordExists/IsAlreadyExists).IsAlreadyExists, this adapter's classifier formodernc.org/sqlite(the driver this repo actually uses — confirmed viago.mod, nomattn/go-sqlite3dependency). It matcheserrors.As(err, *sqlite.Error)against the extended result codesSQLITE_CONSTRAINT_PRIMARYKEY(1555) andSQLITE_CONSTRAINT_UNIQUE(2067) — never on message text. Both codes are matched deliberately: a duplicate primary key reports 1555, not 2067, and is the commonest case (this repo's own conformance suite exercises exactly that path). The primary result codeSQLITE_CONSTRAINT(19) is deliberately not matched, since it also covers NOT NULL/CHECK/FOREIGN KEY violations.NewDatabaseWithOptionsas the default whenever the caller-suppliedDbOptions.IsAlreadyExistsis nil, soNewDatabaseand every existing caller (including this package's ownTestConformance) get classification with zero extra configuration, while still allowing an explicit override.dalgo2sqlite.IsAlreadyExists) so a caller assembling a customDbOptionscan reuse or compose with it.Verification
modernc.org/sqlite@v1.57.0'slib/sqlite.go, and confirmed the driver enables extended result codes on every connection it opens (conn.go'sopen()callssqlite3_extended_result_codes(db, 1)unconditionally), so(*sqlite.Error).Code()reports the extended code, not the primary one.NewDatabaseWithOptionsdefault madeTestConformance/rejects_an_Insert_over_an_existing_key_with_record.IsAlreadyExistsfail with the driver reporting exactly extended code 1555.sqlite_classifier_test.godrives a real in-memorymodernc.org/sqlitedatabase (not hand-built error structs, sincesqlite.Error's fields are unexported) to prove: a duplicate primary key is classified, a duplicate unique-index value is classified, and a NOT NULL violation and a CHECK violation are each not classified.go build ./...,go vet ./...,gofmt -l .(clean),golangci-lint run ./...(0 issues), andgo test -race ./...all pass, including the shareddalgotestconformance suite (SQLite is in-process, so it runs for real here — no env-gate, no skip).Test plan
go build ./...go vet ./...gofmt -l .golangci-lint run ./...go test -race ./...(includingTestConformance)🤖 Generated with Claude Code