Skip to content

Commit be4a7dd

Browse files
re-cheidglebarez
authored andcommitted
Feature: Error translator for Dialector
1 parent 1accfe1 commit be4a7dd

File tree

3 files changed

+64
-2
lines changed

3 files changed

+64
-2
lines changed

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ go 1.18
55
require (
66
github.com/glebarez/go-sqlite v1.21.1
77
gorm.io/gorm v1.25.0
8+
modernc.org/sqlite v1.21.1
89
)
910

1011
require (
@@ -18,5 +19,4 @@ require (
1819
modernc.org/libc v1.22.3 // indirect
1920
modernc.org/mathutil v1.5.0 // indirect
2021
modernc.org/memory v1.5.0 // indirect
21-
modernc.org/sqlite v1.21.1 // indirect
2222
)

sqlite.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@ import (
88

99
"gorm.io/gorm/callbacks"
1010

11-
_ "github.com/glebarez/go-sqlite"
11+
gosqlite "github.com/glebarez/go-sqlite"
12+
sqlite3 "modernc.org/sqlite/lib"
1213

1314
"gorm.io/gorm"
1415
"gorm.io/gorm/clause"
@@ -197,6 +198,19 @@ func (dialectopr Dialector) RollbackTo(tx *gorm.DB, name string) error {
197198
return nil
198199
}
199200

201+
func (dialector Dialector) Translate(err error) error {
202+
switch terr := err.(type) {
203+
case *gosqlite.Error:
204+
switch terr.Code() {
205+
case sqlite3.SQLITE_CONSTRAINT_UNIQUE:
206+
return gorm.ErrDuplicatedKey
207+
case sqlite3.SQLITE_CONSTRAINT_PRIMARYKEY:
208+
return gorm.ErrDuplicatedKey
209+
}
210+
}
211+
return err
212+
}
213+
200214
func compareVersion(version1, version2 string) int {
201215
n, m := len(version1), len(version2)
202216
i, j := 0, 0

sqlite_error_translator_test.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package sqlite
2+
3+
import (
4+
"testing"
5+
6+
"gorm.io/gorm"
7+
"gorm.io/gorm/logger"
8+
)
9+
10+
func TestErrorTranslator(t *testing.T) {
11+
// This is the DSN of the in-memory SQLite database for these tests.
12+
const InMemoryDSN = "file:testdatabase?mode=memory&cache=shared"
13+
14+
// This is the example object for testing the unique constraint error
15+
type Article struct {
16+
ArticleNumber string `gorm:"unique"`
17+
}
18+
19+
db, err := gorm.Open(&Dialector{DSN: InMemoryDSN}, &gorm.Config{
20+
Logger: logger.Default.LogMode(logger.Silent),
21+
TranslateError: true})
22+
23+
if err != nil {
24+
t.Errorf("Expected Open to succeed; got error: %v", err)
25+
}
26+
if db == nil {
27+
t.Errorf("Expected db to be non-nil.")
28+
}
29+
30+
err = db.AutoMigrate(&Article{})
31+
if err != nil {
32+
t.Errorf("Expected to migrate database models to succeed: %v", err)
33+
}
34+
35+
err = db.Create(&Article{ArticleNumber: "A00000XX"}).Error
36+
if err != nil {
37+
t.Errorf("Expected first create to succeed: %v", err)
38+
}
39+
40+
err = db.Create(&Article{ArticleNumber: "A00000XX"}).Error
41+
if err == nil {
42+
t.Errorf("Expected second create to fail.")
43+
}
44+
45+
if err != gorm.ErrDuplicatedKey {
46+
t.Errorf("Expected error from second create to be gorm.ErrDuplicatedKey: %v", err)
47+
}
48+
}

0 commit comments

Comments
 (0)