Files
Stephan D 62a6631b9a
All checks were successful
ci/woodpecker/push/db Pipeline was successful
ci/woodpecker/push/nats Pipeline was successful
service backend
2025-11-07 18:35:26 +01:00

4.1 KiB

Indexable Implementation (Refactored)

Overview

This package provides a refactored implementation of the indexable.DB interface that uses mutil.GetObjects for better consistency with the existing codebase. The implementation has been moved to the mongo folder and includes a factory for project indexable in the pkg/db folder.

Structure

1. api/pkg/db/internal/mongo/indexable/indexable.go

  • ReorderTemplate[T]: Generic template function that uses mutil.GetObjects for fetching objects
  • IndexableDB: Base struct for creating concrete implementations
  • Type-safe implementation: Uses Go generics with proper type constraints

2. api/pkg/db/project_indexable.go

  • ProjectIndexableDB: Factory implementation for Project objects
  • NewProjectIndexableDB: Constructor function
  • ReorderTemplate: Duplicate of the mongo version for convenience

Key Changes from Previous Implementation

1. Uses mutil.GetObjects

// Old implementation (manual cursor handling)
err = repo.FindManyByFilter(ctx, filter, func(cursor *mongo.Cursor) error {
    var obj T
    if err := cursor.Decode(&obj); err != nil {
        return err
    }
    objects = append(objects, obj)
    return nil
})

// New implementation (using mutil.GetObjects)
objects, err := mutil.GetObjects[T](
    ctx,
    logger,
    filterFunc().
        And(
            repository.IndexOpFilter(minIdx, builder.Gte),
            repository.IndexOpFilter(maxIdx, builder.Lte),
        ),
    nil, nil, nil, // limit, offset, isArchived
    repo,
)

2. Moved to Mongo Folder

  • Location: api/pkg/db/internal/mongo/indexable/
  • Consistent with other mongo implementations
  • Better organization within the codebase

3. Added Factory in pkg/db

  • Location: api/pkg/db/project_indexable.go
  • Provides easy access to project indexable functionality
  • Includes logger parameter for better error handling

Usage

import "github.com/tech/sendico/pkg/db"

// Create a project indexable DB
projectDB := db.NewProjectIndexableDB(repo, logger, organizationRef)

// Reorder a project
err := projectDB.Reorder(ctx, projectID, newIndex)
if err != nil {
    // Handle error
}

Using the Template Directly

import "github.com/tech/sendico/pkg/db/internal/mongo/indexable"

// Define helper functions
getIndexable := func(p *model.Project) *model.Indexable {
    return &p.Indexable
}

updateIndexable := func(p *model.Project, newIndex int) {
    p.Index = newIndex
}

createEmpty := func() *model.Project {
    return &model.Project{}
}

filterFunc := func() builder.Query {
    return repository.OrgFilter(organizationRef)
}

// Use the template
err := indexable.ReorderTemplate(
    ctx,
    logger,
    repo,
    objectRef,
    newIndex,
    filterFunc,
    getIndexable,
    updateIndexable,
    createEmpty,
)

Benefits of Refactoring

  1. Consistency: Uses mutil.GetObjects like other parts of the codebase
  2. Better Error Handling: Includes logger parameter for proper error logging
  3. Organization: Moved to appropriate folder structure
  4. Factory Pattern: Easy-to-use factory for common use cases
  5. Type Safety: Maintains compile-time type checking
  6. Performance: Leverages existing optimized mutil.GetObjects implementation

Testing

Mongo Implementation Tests

go test ./db/internal/mongo/indexable -v

Factory Tests

go test ./db -v

Integration

The refactored implementation is ready for integration with existing project reordering APIs. The factory pattern makes it easy to add reordering functionality to any service that needs to reorder projects within an organization.

Migration from Old Implementation

If you were using the old implementation:

  1. Update imports: Change from api/pkg/db/internal/indexable to api/pkg/db
  2. Use factory: Replace manual template usage with NewProjectIndexableDB
  3. Add logger: Include a logger parameter in your constructor calls
  4. Update tests: Use the new test structure if needed

The API remains the same, so existing code should work with minimal changes.