Lets try the model approach again

This commit is contained in:
Hein 2025-11-07 14:18:15 +02:00
parent f1c6b36374
commit c84dd7dc91
3 changed files with 29 additions and 10 deletions

View File

@ -82,6 +82,7 @@ func (b *BunAdapter) RunInTransaction(ctx context.Context, fn func(common.Databa
type BunSelectQuery struct { type BunSelectQuery struct {
query *bun.SelectQuery query *bun.SelectQuery
db bun.IDB // Store DB connection for count queries db bun.IDB // Store DB connection for count queries
hasModel bool // Track if Model() was called
schema string // Separated schema name schema string // Separated schema name
tableName string // Just the table name, without schema tableName string // Just the table name, without schema
tableAlias string tableAlias string
@ -89,6 +90,7 @@ type BunSelectQuery struct {
func (b *BunSelectQuery) Model(model interface{}) common.SelectQuery { func (b *BunSelectQuery) Model(model interface{}) common.SelectQuery {
b.query = b.query.Model(model) b.query = b.query.Model(model)
b.hasModel = true // Mark that we have a model
// Try to get table name from model if it implements TableNameProvider // Try to get table name from model if it implements TableNameProvider
if provider, ok := model.(common.TableNameProvider); ok { if provider, ok := model.(common.TableNameProvider); ok {
@ -232,13 +234,22 @@ func (b *BunSelectQuery) Scan(ctx context.Context, dest interface{}) error {
} }
func (b *BunSelectQuery) Count(ctx context.Context) (int, error) { func (b *BunSelectQuery) Count(ctx context.Context) (int, error) {
// Bun's Count() method works properly and handles column selections automatically // If Model() was set, use bun's native Count() which works properly
// It builds: SELECT COUNT(*) FROM (original query) AS subquery if b.hasModel {
// This works with both Model() and Table() set
count, err := b.query.Count(ctx) count, err := b.query.Count(ctx)
return count, err return count, err
} }
// Otherwise, wrap as subquery to avoid "Model(nil)" error
// This is needed when only Table() is set without a model
var count int
err := b.db.NewSelect().
TableExpr("(?) AS subquery", b.query).
ColumnExpr("COUNT(*)").
Scan(ctx, &count)
return count, err
}
func (b *BunSelectQuery) Exists(ctx context.Context) (bool, error) { func (b *BunSelectQuery) Exists(ctx context.Context) (bool, error) {
return b.query.Exists(ctx) return b.query.Exists(ctx)
} }

View File

@ -172,12 +172,16 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
logger.Info("Reading records from %s.%s", schema, entity) logger.Info("Reading records from %s.%s", schema, entity)
// Create the model pointer for Scan() operations // Create the model pointer for Scan() operations
// We don't set it on the query to avoid table duplication in FROM clause
sliceType := reflect.SliceOf(reflect.PointerTo(modelType)) sliceType := reflect.SliceOf(reflect.PointerTo(modelType))
modelPtr := reflect.New(sliceType).Interface() modelPtr := reflect.New(sliceType).Interface()
// Use only Table() - model will be provided to Scan() directly // Start with Model() to avoid "Model(nil)" errors in Count()
query := h.db.NewSelect().Table(tableName) query := h.db.NewSelect().Model(model)
// Only set Table() if the model doesn't provide a table name
if provider, ok := model.(common.TableNameProvider); !ok || provider.TableName() == "" {
query = query.Table(tableName)
}
// Apply column selection // Apply column selection
if len(options.Columns) > 0 { if len(options.Columns) > 0 {

View File

@ -201,9 +201,13 @@ func (h *Handler) handleRead(ctx context.Context, w common.ResponseWriter, id st
logger.Info("Reading records from %s.%s", schema, entity) logger.Info("Reading records from %s.%s", schema, entity)
// Use Table() with the resolved table name // Start with Model() to avoid "Model(nil)" errors in Count()
// Model will be provided to Scan() directly to avoid table duplication in FROM clause query := h.db.NewSelect().Model(model)
query := h.db.NewSelect().Table(tableName)
// Only set Table() if the model doesn't provide a table name
if provider, ok := model.(common.TableNameProvider); !ok || provider.TableName() == "" {
query = query.Table(tableName)
}
// Apply column selection // Apply column selection
if len(options.Columns) > 0 { if len(options.Columns) > 0 {