Compare commits

..

2 Commits

Author SHA1 Message Date
70bf0a4be1 fix(dbmanager): add nil checks to connection methods 2026-01-03 17:19:43 +02:00
4964d89158 feat(restheadspec): accept bunrouter.Router and bunrouter.Group in SetupBunRouterRoutes
Replaced *router.StandardBunRouterAdapter parameter with BunRouterHandler
interface to support both bunrouter.Router and bunrouter.Group types,
enabling route registration on router groups with path prefixes.

- Added BunRouterHandler interface
- Updated SetupBunRouterRoutes signature
- Updated ExampleBunRouterWithBunDB to use bunrouter.New() directly
- Added ExampleBunRouterWithGroup demonstrating group usage
2026-01-03 16:10:36 +02:00
2 changed files with 60 additions and 9 deletions

View File

@@ -3,6 +3,7 @@ package dbmanager
import ( import (
"context" "context"
"database/sql" "database/sql"
"fmt"
"sync" "sync"
"time" "time"
@@ -159,6 +160,9 @@ func (c *sqlConnection) Close() error {
// HealthCheck verifies the connection is alive // HealthCheck verifies the connection is alive
func (c *sqlConnection) HealthCheck(ctx context.Context) error { func (c *sqlConnection) HealthCheck(ctx context.Context) error {
if c == nil {
return fmt.Errorf("connection is nil")
}
c.mu.Lock() c.mu.Lock()
defer c.mu.Unlock() defer c.mu.Unlock()
@@ -188,6 +192,9 @@ func (c *sqlConnection) Reconnect(ctx context.Context) error {
// Native returns the native *sql.DB connection // Native returns the native *sql.DB connection
func (c *sqlConnection) Native() (*sql.DB, error) { func (c *sqlConnection) Native() (*sql.DB, error) {
if c == nil {
return nil, fmt.Errorf("connection is nil")
}
c.mu.RLock() c.mu.RLock()
if c.nativeDB != nil { if c.nativeDB != nil {
defer c.mu.RUnlock() defer c.mu.RUnlock()
@@ -219,6 +226,9 @@ func (c *sqlConnection) Native() (*sql.DB, error) {
// Bun returns a Bun ORM instance wrapping the native connection // Bun returns a Bun ORM instance wrapping the native connection
func (c *sqlConnection) Bun() (*bun.DB, error) { func (c *sqlConnection) Bun() (*bun.DB, error) {
if c == nil {
return nil, fmt.Errorf("connection is nil")
}
c.mu.RLock() c.mu.RLock()
if c.bunDB != nil { if c.bunDB != nil {
defer c.mu.RUnlock() defer c.mu.RUnlock()
@@ -249,6 +259,9 @@ func (c *sqlConnection) Bun() (*bun.DB, error) {
// GORM returns a GORM instance wrapping the native connection // GORM returns a GORM instance wrapping the native connection
func (c *sqlConnection) GORM() (*gorm.DB, error) { func (c *sqlConnection) GORM() (*gorm.DB, error) {
if c == nil {
return nil, fmt.Errorf("connection is nil")
}
c.mu.RLock() c.mu.RLock()
if c.gormDB != nil { if c.gormDB != nil {
defer c.mu.RUnlock() defer c.mu.RUnlock()
@@ -283,6 +296,9 @@ func (c *sqlConnection) GORM() (*gorm.DB, error) {
// Database returns the common.Database interface using the configured default ORM // Database returns the common.Database interface using the configured default ORM
func (c *sqlConnection) Database() (common.Database, error) { func (c *sqlConnection) Database() (common.Database, error) {
if c == nil {
return nil, fmt.Errorf("connection is nil")
}
c.mu.RLock() c.mu.RLock()
defaultORM := c.config.DefaultORM defaultORM := c.config.DefaultORM
c.mu.RUnlock() c.mu.RUnlock()
@@ -307,6 +323,9 @@ func (c *sqlConnection) MongoDB() (*mongo.Client, error) {
// Stats returns connection statistics // Stats returns connection statistics
func (c *sqlConnection) Stats() *ConnectionStats { func (c *sqlConnection) Stats() *ConnectionStats {
if c == nil {
return nil
}
c.mu.RLock() c.mu.RLock()
defer c.mu.RUnlock() defer c.mu.RUnlock()
@@ -336,6 +355,9 @@ func (c *sqlConnection) Stats() *ConnectionStats {
// getBunAdapter returns or creates the Bun adapter // getBunAdapter returns or creates the Bun adapter
func (c *sqlConnection) getBunAdapter() (common.Database, error) { func (c *sqlConnection) getBunAdapter() (common.Database, error) {
if c == nil {
return nil, fmt.Errorf("connection is nil")
}
c.mu.RLock() c.mu.RLock()
if c.bunAdapter != nil { if c.bunAdapter != nil {
defer c.mu.RUnlock() defer c.mu.RUnlock()
@@ -361,6 +383,9 @@ func (c *sqlConnection) getBunAdapter() (common.Database, error) {
// getGORMAdapter returns or creates the GORM adapter // getGORMAdapter returns or creates the GORM adapter
func (c *sqlConnection) getGORMAdapter() (common.Database, error) { func (c *sqlConnection) getGORMAdapter() (common.Database, error) {
if c == nil {
return nil, fmt.Errorf("connection is nil")
}
c.mu.RLock() c.mu.RLock()
if c.gormAdapter != nil { if c.gormAdapter != nil {
defer c.mu.RUnlock() defer c.mu.RUnlock()
@@ -386,6 +411,9 @@ func (c *sqlConnection) getGORMAdapter() (common.Database, error) {
// getNativeAdapter returns or creates the native adapter // getNativeAdapter returns or creates the native adapter
func (c *sqlConnection) getNativeAdapter() (common.Database, error) { func (c *sqlConnection) getNativeAdapter() (common.Database, error) {
if c == nil {
return nil, fmt.Errorf("connection is nil")
}
c.mu.RLock() c.mu.RLock()
if c.nativeAdapter != nil { if c.nativeAdapter != nil {
defer c.mu.RUnlock() defer c.mu.RUnlock()
@@ -424,6 +452,7 @@ func (c *sqlConnection) getNativeAdapter() (common.Database, error) {
// getBunDialect returns the appropriate Bun dialect for the database type // getBunDialect returns the appropriate Bun dialect for the database type
func (c *sqlConnection) getBunDialect() schema.Dialect { func (c *sqlConnection) getBunDialect() schema.Dialect {
switch c.dbType { switch c.dbType {
case DatabaseTypePostgreSQL: case DatabaseTypePostgreSQL:
return database.GetPostgresDialect() return database.GetPostgresDialect()

View File

@@ -270,9 +270,14 @@ func ExampleWithBun(bunDB *bun.DB) {
SetupMuxRoutes(muxRouter, handler, nil) SetupMuxRoutes(muxRouter, handler, nil)
} }
// BunRouterHandler is an interface that both bunrouter.Router and bunrouter.Group implement
type BunRouterHandler interface {
Handle(method, path string, handler bunrouter.HandlerFunc)
}
// SetupBunRouterRoutes sets up bunrouter routes for the RestHeadSpec API // SetupBunRouterRoutes sets up bunrouter routes for the RestHeadSpec API
func SetupBunRouterRoutes(bunRouter *router.StandardBunRouterAdapter, handler *Handler) { // Accepts bunrouter.Router or bunrouter.Group
r := bunRouter.GetBunRouter() func SetupBunRouterRoutes(r BunRouterHandler, handler *Handler) {
// CORS config // CORS config
corsConfig := common.DefaultCORSConfig() corsConfig := common.DefaultCORSConfig()
@@ -450,17 +455,34 @@ func ExampleBunRouterWithBunDB(bunDB *bun.DB) {
// Create handler // Create handler
handler := NewHandlerWithBun(bunDB) handler := NewHandlerWithBun(bunDB)
// Create BunRouter adapter // Create bunrouter
routerAdapter := NewStandardBunRouter() bunRouter := bunrouter.New()
// Setup routes // Setup routes
SetupBunRouterRoutes(routerAdapter, handler) SetupBunRouterRoutes(bunRouter, handler)
// Get the underlying router for server setup
r := routerAdapter.GetBunRouter()
// Start server // Start server
if err := http.ListenAndServe(":8080", r); err != nil { if err := http.ListenAndServe(":8080", bunRouter); err != nil {
logger.Error("Server failed to start: %v", err)
}
}
// ExampleBunRouterWithGroup shows how to use SetupBunRouterRoutes with a bunrouter.Group
func ExampleBunRouterWithGroup(bunDB *bun.DB) {
// Create handler with Bun adapter
handler := NewHandlerWithBun(bunDB)
// Create bunrouter
bunRouter := bunrouter.New()
// Create a route group with a prefix
apiGroup := bunRouter.NewGroup("/api")
// Setup RestHeadSpec routes on the group - routes will be under /api
SetupBunRouterRoutes(apiGroup, handler)
// Start server
if err := http.ListenAndServe(":8080", bunRouter); err != nil {
logger.Error("Server failed to start: %v", err) logger.Error("Server failed to start: %v", err)
} }
} }