Skip to content

[REFACTOR] Fix query_builder over-allocation - Simple Design compliance #306

Description

@kcenon

Summary

Fix query_builder class that allocates all 3 query builders upfront even though only one is ever used, following Simple Design principle of "Fewest Elements".

Current State

File: /database/query_builder.h (lines 361-366)

class query_builder {
private:
    std::unique_ptr<sql_query_builder> sql_builder_;      // Always allocated
    std::unique_ptr<mongodb_query_builder> mongo_builder_;// Always allocated  
    std::unique_ptr<redis_query_builder> redis_builder_;  // Always allocated
    database_types db_type_;
};

Problem Analysis

Issue Impact
3 builders allocated Memory waste
Only 1 ever used 2 objects unused
Allocation on construction Startup overhead

Proposed Solution: Lazy Initialization

class query_builder {
public:
    explicit query_builder(database_types type) : db_type_(type) {}
    
    // Get appropriate builder lazily
    sql_query_builder& sql() {
        if (!sql_builder_ && is_sql_type(db_type_)) {
            sql_builder_ = std::make_unique<sql_query_builder>();
        }
        return *sql_builder_;
    }
    
    mongodb_query_builder& mongo() {
        if (!mongo_builder_ && db_type_ == database_types::mongodb) {
            mongo_builder_ = std::make_unique<mongodb_query_builder>();
        }
        return *mongo_builder_;
    }
    
    redis_query_builder& redis() {
        if (!redis_builder_ && db_type_ == database_types::redis) {
            redis_builder_ = std::make_unique<redis_query_builder>();
        }
        return *redis_builder_;
    }

private:
    std::unique_ptr<sql_query_builder> sql_builder_;
    std::unique_ptr<mongodb_query_builder> mongo_builder_;
    std::unique_ptr<redis_query_builder> redis_builder_;
    database_types db_type_;
};

Alternative: std::variant

class query_builder {
private:
    std::variant<
        std::unique_ptr<sql_query_builder>,
        std::unique_ptr<mongodb_query_builder>,
        std::unique_ptr<redis_query_builder>
    > builder_;
};

Tasks

  • Implement lazy initialization pattern
  • Update constructor to not pre-allocate
  • Add accessor methods that create on demand
  • Update tests
  • Verify no performance regression

Acceptance Criteria

  • Only used builder is allocated
  • No API changes for consumers
  • Memory footprint reduced
  • All tests pass

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestrefactoringCode refactoring and improvements

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions