Skip to content

Commit 8e83e01

Browse files
committed
Fix db.DB() method access
- Add GetDBConnector() method to duckdbConnPoolWrapper - Implement proper interface to expose underlying *sql.DB - Add DB access test to example application - Fix import path in example to use correct module name This resolves the issue where GORM couldn't access the underlying *sql.DB instance through the db.DB() method.
1 parent 8ffe7a0 commit 8e83e01

File tree

6 files changed

+126
-0
lines changed

6 files changed

+126
-0
lines changed

dialector.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,3 +275,17 @@ func (p *duckdbConnPoolWrapper) QueryRowContext(ctx context.Context, query strin
275275
convertedArgs := convertTimePointers(args)
276276
return p.ConnPool.QueryRowContext(ctx, query, convertedArgs...)
277277
}
278+
279+
// Implement GetDBConnector interface to allow access to underlying *sql.DB
280+
func (p *duckdbConnPoolWrapper) GetDBConnector() (*sql.DB, error) {
281+
if dbConnector, ok := p.ConnPool.(interface{ GetDBConnector() (*sql.DB, error) }); ok {
282+
return dbConnector.GetDBConnector()
283+
}
284+
285+
// If the wrapped ConnPool is directly *sql.DB, return it
286+
if db, ok := p.ConnPool.(*sql.DB); ok {
287+
return db, nil
288+
}
289+
290+
return nil, fmt.Errorf("unable to get underlying *sql.DB from connection pool")
291+
}

example/go.mod

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,7 @@ replace gorm.io/driver/duckdb => ../
1414
require (
1515
github.com/jinzhu/inflection v1.0.0 // indirect
1616
github.com/jinzhu/now v1.1.5 // indirect
17+
github.com/ramya-rao-a/go-outline v0.0.0-20210608161538-9736a4bde949 // indirect
1718
golang.org/x/text v0.26.0 // indirect
19+
golang.org/x/tools v0.33.0 // indirect
1820
)

example/go.sum

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,24 +54,49 @@ github.com/pierrec/lz4/v4 v4.1.22 h1:cKFw6uJDK+/gfw5BcDL0JL5aBsAFdsIT18eRtLj7VIU
5454
github.com/pierrec/lz4/v4 v4.1.22/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
5555
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
5656
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
57+
github.com/ramya-rao-a/go-outline v0.0.0-20210608161538-9736a4bde949 h1:iaD+iVf9xGfajsJp+zYrg9Lrk6gMJ6/hZHO4cYq5D5o=
58+
github.com/ramya-rao-a/go-outline v0.0.0-20210608161538-9736a4bde949/go.mod h1:9V3eNbj9Z53yO7cKB6cSX9f0O7rYdIiuGBhjA1YsQuw=
5759
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
5860
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
61+
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
5962
github.com/zeebo/assert v1.3.0 h1:g7C04CbJuIDKNPFHmsk4hwZDO5O+kntRxzaUoNXj+IQ=
6063
github.com/zeebo/assert v1.3.0/go.mod h1:Pq9JiuJQpG8JLJdtkwrJESF0Foym2/D9XMU5ciN/wJ0=
6164
github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0=
6265
github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA=
66+
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
67+
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
6368
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c h1:KL/ZBHXgKGVmuZBZ01Lt57yE5ws8ZPSkkihmEyq7FXc=
6469
golang.org/x/exp v0.0.0-20250128182459-e0ece0dbea4c/go.mod h1:tujkw807nyEEAamNbDrEGzRav+ilXA7PCRAd6xsmwiU=
70+
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
6571
golang.org/x/mod v0.25.0 h1:n7a+ZbQKQA/Ysbyb0/6IbB1H/X41mKgbhfv7AfG/44w=
6672
golang.org/x/mod v0.25.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww=
73+
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
74+
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
75+
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
76+
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
77+
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
6778
golang.org/x/sync v0.15.0 h1:KWH3jNZsfyT6xfAfKiz6MRNmd46ByHDYaZ7KSkCtdW8=
6879
golang.org/x/sync v0.15.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
80+
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
81+
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
82+
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
83+
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
84+
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
6985
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
7086
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
87+
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
88+
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
89+
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
7190
golang.org/x/text v0.26.0 h1:P42AVeLghgTYr4+xUnTRKDMqpar+PtX7KWuNQL21L8M=
7291
golang.org/x/text v0.26.0/go.mod h1:QK15LZJUUQVJxhz7wXgxSy/CJaTFjd0G+YLonydOVQA=
92+
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
93+
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
94+
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
7395
golang.org/x/tools v0.33.0 h1:4qz2S3zmRxbGIhDIAgjxvFutSvH5EfnsYrRBj0UI0bc=
7496
golang.org/x/tools v0.33.0/go.mod h1:CIJMaWEY88juyUfo7UbgPqbC8rU2OqfAV1h2Qp0oMYI=
97+
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
98+
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
99+
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
75100
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY=
76101
golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90=
77102
gonum.org/v1/gonum v0.15.1 h1:FNy7N6OUZVUaWG9pTiD+jlhdQ3lMP+/LcTpJ6+a8sQ0=

example/main

52.2 MB
Binary file not shown.

example/main.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,5 +213,29 @@ func main() {
213213
columnTypes, _ := db.Migrator().ColumnTypes(&User{})
214214
fmt.Printf("User table has %d columns\n", len(columnTypes))
215215

216+
// Test access to underlying *sql.DB
217+
fmt.Println("\n=== Testing *sql.DB Access ===")
218+
sqlDB, err := db.DB()
219+
if err != nil {
220+
log.Fatal("Failed to get *sql.DB:", err)
221+
}
222+
223+
// Test ping
224+
if err := sqlDB.Ping(); err != nil {
225+
log.Fatal("Failed to ping database:", err)
226+
}
227+
228+
// Set connection pool settings
229+
sqlDB.SetMaxIdleConns(10)
230+
sqlDB.SetMaxOpenConns(100)
231+
232+
// Get stats
233+
stats := sqlDB.Stats()
234+
fmt.Printf("✅ Successfully accessed *sql.DB!\n")
235+
fmt.Printf(" - Max open connections: %d\n", stats.MaxOpenConnections)
236+
fmt.Printf(" - Open connections: %d\n", stats.OpenConnections)
237+
fmt.Printf(" - In use: %d\n", stats.InUse)
238+
fmt.Printf(" - Idle: %d\n", stats.Idle)
239+
216240
fmt.Println("\n🎉 DuckDB GORM Driver Demo Complete!")
217241
}

test/db_access_test.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"log"
6+
7+
"github.com/greysquirr3l/gorm-duckdb-driver"
8+
"gorm.io/driver/duckdb"
9+
"gorm.io/gorm"
10+
)
11+
12+
func main() {
13+
// Test the db.DB() method access
14+
db, err := gorm.Open(duckdb.Open(":memory:"), &gorm.Config{})
15+
if err != nil {
16+
log.Fatal("Failed to connect to database:", err)
17+
}
18+
19+
// Test accessing the underlying *sql.DB
20+
sqlDB, err := db.DB()
21+
if err != nil {
22+
log.Fatal("Failed to get *sql.DB:", err)
23+
}
24+
25+
// Test that we can use the sql.DB methods
26+
if err := sqlDB.Ping(); err != nil {
27+
log.Fatal("Failed to ping database:", err)
28+
}
29+
30+
// Set connection pool settings
31+
sqlDB.SetMaxIdleConns(10)
32+
sqlDB.SetMaxOpenConns(100)
33+
34+
// Get stats to verify it works
35+
stats := sqlDB.Stats()
36+
fmt.Printf("✅ Successfully accessed *sql.DB!\n")
37+
fmt.Printf(" - Max open connections: %d\n", stats.MaxOpenConnections)
38+
fmt.Printf(" - Open connections: %d\n", stats.OpenConnections)
39+
fmt.Printf(" - In use: %d\n", stats.InUse)
40+
fmt.Printf(" - Idle: %d\n", stats.Idle)
41+
42+
// Test that we can still use GORM normally
43+
type User struct {
44+
ID uint `gorm:"primaryKey"`
45+
Name string `gorm:"size:100"`
46+
}
47+
48+
if err := db.AutoMigrate(&User{}); err != nil {
49+
log.Fatal("Failed to migrate:", err)
50+
}
51+
52+
user := User{Name: "Test User"}
53+
if err := db.Create(&user).Error; err != nil {
54+
log.Fatal("Failed to create user:", err)
55+
}
56+
57+
fmt.Printf("✅ GORM operations work correctly!\n")
58+
fmt.Printf(" - Created user with ID: %d\n", user.ID)
59+
60+
fmt.Println("✅ All tests passed! The db.DB() method works correctly.")
61+
}

0 commit comments

Comments
 (0)