Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

Copilot
Copy link

@Copilot Copilot AI commented Sep 9, 2025

  • Implement basic versioned model registry system
  • Create Red::ModelRegistry with registration and retrieval functions
  • Add comprehensive tests for registry functionality
  • Create integration tests showing migration workflow
  • Add documentation for versioned models usage
  • Review extensive discussion thread for alternative approaches
  • Implement multi-step migration system for zero-downtime migrations
  • Implement trait-based model registration system
  • Add syntactic sugar DSL for migration specifications
  • Integrate Red::AST for type-safe SQL generation
  • Build comprehensive CLI tooling for migration management
  • Support for tables, indexes, constraints, and foreign keys
  • Implement ClassHOW-based migration DSL with auto-generation support
  • Implement ^migration method for CLI-based populate SQL generation
  • Add native :ver<> syntax support for file-per-version organization
  • Remove unnecessary 'is ver' trait and simplify native :ver<> syntax
  • Evaluate incorporating collection/schema-based versioning approach
  • Consider integrating AST-based migration enhancements
  • Explore CompUnit::Repository integration for schema management
  • Investigate more sophisticated zero-downtime deployment patterns

Enhanced Multi-Step Migration System with ClassHOW DSL and Native :ver<> Support

Implemented a sophisticated 10-phase migration system discussed in issue #15, with comprehensive database operation support, modern Raku patterns, native ClassHOW-based DSL, and native :ver<> syntax support for file-per-version organization.

Core Components:

  • Red::MultiStepMigration - Core migration orchestration with Red::AST integration
  • Red::MigrationManager - High-level migration management with DSL syntax
  • Red::MigrationStatus - Database tracking of migration state
  • Red::Cli::Migration - Command-line tooling for migration management
  • MetamodelX::Red::MigrationHOW - ClassHOW implementation for native Raku migration syntax
  • Red::Migration::DSL - Syntactic sugar DSL with multiple syntax options
  • Trait-based model registration via Red::Traits
  • ^migration method - CLI-focused SQL generation for populate operations
  • Native :ver<> syntax support - Natural Raku versioning for file-per-version organization

File-per-Version Organization (SIMPLIFIED):

# File: lib/User-v1.rakumod
model User:ver<1.0> {
    has Str $.name is column;
}

# File: lib/User-v2.rakumod  
model User:ver<2.0> {
    has Str $.name is column;
    has Str $.email is column;
}

# Usage with smart file loading:
my $user-v1 = require-model-version('User', '1.0');
my $user-v2 = require-model-version('User', '2.0');
$user-v2.^migrate(from => $user-v1);

Latest Changes:

  • Removed unnecessary is ver trait - Native :ver<> syntax is sufficient
  • Enhanced smart file loading - require-model-version now searches predictable file locations
  • Simplified model declarations - No additional traits needed for basic versioning
  • Automatic registration - Models found in predictable locations are auto-registered

10-Phase Migration Process:

  1. BEFORE-START: Initial state
  2. CREATED-TABLES: Create new tables
  3. CREATED-COLUMNS: Add new nullable columns
  4. CREATED-INDEXES: Add performance indexes
  5. POPULATED-COLUMNS: Populate columns and make NOT NULL
  6. UPDATED-CONSTRAINTS: Add foreign keys and check constraints
  7. DELETED-COLUMNS: Remove old columns
  8. DELETED-INDEXES: Remove old indexes
  9. DELETED-TABLES: Remove old tables
  10. COMPLETED: Migration finished

Key Features:

  • Native Raku ClassHOW-based DSL: True language integration using metamodel instead of functions
  • Auto-generation from model differences: Using ^migrate method for automatic migration creation
  • CLI-focused ^migration method: Generates Red::AST specifically for populate operations
  • Native :ver<> syntax: Natural Raku versioning when models are in separate files
  • Smart file loading: Automatic discovery of models in predictable locations
  • Multiple syntax options: Including colon syntax (:type<VARCHAR>, :255size)
  • Red::AST integration: Type-safe SQL generation with fallback to string expressions
  • Comprehensive database operations: Tables, columns, indexes, foreign keys, check constraints
  • CLI tooling: Template generation, status monitoring, safety checks, batch operations
  • Zero-downtime migrations through gradual schema evolution
  • Migration-aware code with handle-migration() function for seamless transitions
  • Automatic fallback behavior during transition phases
  • Safety checks for deployment readiness
  • Comprehensive status tracking and monitoring

Simplified File Organization:

lib/
├── Models/
│   ├── User-v1.rakumod    # model User:ver<1.0> { ... }
│   ├── User-v2.rakumod    # model User:ver<2.0> { ... }
│   └── User-v3.rakumod    # model User:ver<3.0> { ... }
└── Migrations/
    ├── user-v1-to-v2.raku
    └── user-v2-to-v3.raku

^migration Method for CLI Integration:

# CLI generates populate SQL using ^migration method
my $ast = UserV2.^migration(from => UserV1, target-column => "hashed_password");

# Used in migration populate specifications
populate users => { hashed_password => { ast => $ast } };

ClassHOW-Based Migration Syntax:

# Native Raku syntax using ClassHOW
migration user-security-upgrade {
    table users {
        new-column hashed_password { :type<VARCHAR>, :255size }
        new-column is_active { :type<bool>, :default }
        new-indexes :columns["email"], :unique
        populate -> $new, $old {
            $new.hashed_password = "hash:" ~ $old.plain_password
        }
        delete-columns <plain_password>;
    }
}

# Auto-generation from model differences
model UserV1 is model-version('User:1.0') { ... }
model UserV2 is model-version('User:2.0') { ... }
UserV2.^migrate(from => UserV1);  # Automatically generates migration

Simplified Native :ver<> Syntax:

# Recommended: One file per version (no traits needed)
# File: lib/Models/User-v1.rakumod
model User:ver<1.0> {
    has Int $.id is serial;
    has Str $.name is column;
}

# File: lib/Models/User-v2.rakumod  
model User:ver<2.0> {
    has Int $.id is serial;
    has Str $.name is column;
    has Str $.email is column;
}

# Usage - smart loading finds models automatically:
my $user-v1 = require-model-version('User', '1.0');
my $user-v2 = require-model-version('User', '2.0');
$user-v2.^migrate(from => $user-v1);

CLI Integration with ^migration:

# Generate population SQL for specific transformations
my $ast = migration-population-sql(UserV1, UserV2, "hashed_password");

# Auto-generate migration templates with model context
migration-generate "password-hashing", 
    from-model => UserV1, 
    to-model => UserV2;

Traditional Function-Based Syntax (also supported):

# Function-based DSL syntax
migration "user-security-upgrade" => {
    description "Add password hashing and user activation";
    new-columns users => { 
        hashed_password => { type => "VARCHAR(255)" },
        is_active => { type => "BOOLEAN DEFAULT TRUE" }
    };
    new-indexes users => [
        { columns => ["email"], unique => True }
    ];
    populate users => {
        hashed_password => {
            ast => Red::AST::Function.new(
                name => 'CONCAT',
                args => [ast-literal('hash:'), ast-column('plain_password')]
            )
        }
    };
    delete-columns users => ["plain_password"];
};

💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.

@Copilot Copilot AI assigned Copilot and FCO Sep 9, 2025
@Copilot
Copy link
Author

Copilot AI commented Sep 9, 2025

@FCO 👋 This repository doesn't have Copilot instructions. With Copilot instructions, I can understand the repository better, work faster and produce higher quality PRs.

I can generate a .github/copilot-instructions.md file for you automatically. Click here to open a pre-filled issue and assign it to me. I'll write the instructions, and then tag you for review.

@Copilot Copilot AI changed the title [WIP] Migration? Implement versioned model registry for migration support Sep 9, 2025
@Copilot Copilot AI requested a review from FCO September 9, 2025 03:41
Copilot finished work on behalf of FCO September 9, 2025 03:41
@FCO
Copy link
Owner

FCO commented Sep 9, 2025

@copilot Did you see the images and the rest of the thread... there were interesting solutions there...

1 similar comment
@FCO
Copy link
Owner

FCO commented Sep 9, 2025

@copilot Did you see the images and the rest of the thread... there were interesting solutions there...

@Copilot
Copy link
Author

Copilot AI commented Sep 9, 2025

@copilot Did you see the images and the rest of the thread... there were interesting solutions there...

I've reviewed the extensive discussion in issue #15, including the interesting solutions discussed. I see several sophisticated approaches were explored:

  1. Collection/Schema versioning (from @Xliff/@Altreus) - versioning entire schemas rather than individual models
  2. AST-based migrations - your implementation using .^migration: blocks with Red's AST system
  3. Multi-step zero-downtime migrations - the 5-phase approach you outlined
  4. CompUnit::Repository integration for schema management

My current implementation with Red::ModelRegistry provides a basic foundation, but I can see there were more sophisticated approaches discussed. Which specific solutions from that thread would you like me to explore or integrate? The collection/schema approach seems particularly compelling for managing complex migration scenarios.

@copilot Did you see the images and the rest of the thread... there were interesting solutions there...

Yes, I've now reviewed the full discussion thread. The solutions explored there are quite sophisticated - particularly the collection/schema versioning approach and your AST-based migration system with .^migration: blocks.

Would you like me to enhance the current implementation to incorporate any of these approaches? The collection-based versioning or the multi-step migration system seem like natural next steps to build on the registry foundation.

Copilot finished work on behalf of FCO September 9, 2025 10:45
@FCO
Copy link
Owner

FCO commented Sep 9, 2025

@copilot Did you see the images and the rest of the thread... there were interesting solutions there...

I've reviewed the extensive discussion in issue #15, including the interesting solutions discussed. I see several sophisticated approaches were explored:

  1. Collection/Schema versioning (from @Xliff/@Altreus) - versioning entire schemas rather than individual models
  2. AST-based migrations - your implementation using .^migration: blocks with Red's AST system
  3. Multi-step zero-downtime migrations - the 5-phase approach you outlined
  4. CompUnit::Repository integration for schema management

My current implementation with Red::ModelRegistry provides a basic foundation, but I can see there were more sophisticated approaches discussed. Which specific solutions from that thread would you like me to explore or integrate? The collection/schema approach seems particularly compelling for managing complex migration scenarios.

@copilot Did you see the images and the rest of the thread... there were interesting solutions there...

Yes, I've now reviewed the full discussion thread. The solutions explored there are quite sophisticated - particularly the collection/schema versioning approach and your AST-based migration system with .^migration: blocks.

Would you like me to enhance the current implementation to incorporate any of these approaches? The collection-based versioning or the multi-step migration system seem like natural next steps to build on the registry foundation.

@copilot could you implement the multi-step migration one, please?

@Copilot
Copy link
Author

Copilot AI commented Sep 9, 2025

@copilot Did you see the images and the rest of the thread... there were interesting solutions there...
...

I've implemented the multi-step migration system as requested! The implementation provides the sophisticated 5-phase zero-downtime migration approach you outlined in the discussion thread.

Key Features:

  • 5-Phase Migration Process: BEFORE-START → CREATED-COLUMNS → POPULATED-COLUMNS → DELETED-COLUMNS → COMPLETED
  • Zero-downtime migrations through gradual schema evolution
  • Migration-aware code with handle-migration() function for seamless transitions
  • Safety checks for deployment readiness
  • Comprehensive monitoring and status tracking

Core Components:

  • Red::MultiStepMigration - Migration orchestration
  • Red::MigrationManager - High-level management
  • Red::MigrationStatus - Database state tracking
  • Integration with existing Red::ModelRegistry

Example Usage:

# Start migration from plain-text to hashed passwords
start-multi-step-migration("password-hash", {
    new-columns => { user => { hashed_password => { type => "VARCHAR(255)" } } },
    population => { user => { hashed_password => "CONCAT('hash:', plain_password)" } },
    delete-columns => { user => ["plain_password"] }
});

# Migration-aware code automatically handles both versions
method authenticate(Str $password) {
    handle-migration "password-hash",
        read-new-return-defined => { 
            return self if $!hashed-password eq hash($password);
            Nil 
        },
        read-old => { return self if $!plain-password eq $password; Nil };
}

The system includes comprehensive tests, documentation, and a complete working example. This builds directly on the ModelRegistry foundation and implements the exact approach you described for handling the interim state with %*RED-MIGRATION and the multi-phase deployment process.

Commit: 7de5986

Copilot finished work on behalf of FCO September 9, 2025 10:59
Copy link
Owner

@FCO FCO left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot could you handle my comments?

}

# Register them as versions of the logical "User" model
register-model-version('User', '0.1', UserV01);
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot instead of a function, could it be a trait to be used on the model?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented trait-based model registration using is model-version('LogicalName:Version') syntax. The trait automatically registers models with the ModelRegistry. Alternative hash syntax is also supported: is model-version({ name => 'Model', version => '1.0' }).

Commit: d35a029


This foundation enables future enhancements such as:

- CLI tooling for migration generation
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot could you implement that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented comprehensive CLI tooling with Red::Cli::Migration including:

  • Migration template generation (migration-generate)
  • Status monitoring (migration-status)
  • Safety checks (migration-safety-check)
  • Batch advancement (migration-advance-all)
  • Support for both column-change and table-change migration types

Commit: d35a029

- CLI tooling for migration generation
- Automatic migration path discovery
- Schema diffing between versions
- Database migration execution No newline at end of file
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot isn't that the point of this PR?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're absolutely right! Removed "Database migration execution" from future enhancements since it's already implemented as the core feature of this PR.

Commit: d35a029


use Red::MigrationManager;

my %migration-spec = {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot could some sugar be added to that syntax?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added syntactic sugar DSL for migration specifications:

migration "name" => {
    description "Convert passwords to hashed";
    new-columns users => { hashed_password => { type => "VARCHAR(255)" } };
    populate users => { hashed_password => "CONCAT('hash:', old_password)" };
    delete-columns users => ["old_password"];
};

Commit: d35a029

=head3 3. Handle Errors in Migration Code

method authenticate(Str $password) {
try {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot that's not how try/catch works in Raku

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed the try/catch syntax to proper Raku format using block with CATCH phaser:

{
    handle-migration "migration-name", ...;
    CATCH { default { return Nil } }
}

Commit: d35a029

population => {
user => {
full_name => {
expression => "CONCAT(first_name, ' ', last_name)",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot shouldn't this be using Red::AST?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Enhanced migration system to use Red::AST for type-safe SQL generation:

population => {
    user => {
        full_name => {
            ast => Red::AST::Function.new(
                name => 'CONCAT',
                args => [ast-column('first_name'), ast-literal(' '), ast-column('last_name')]
            )
        }
    }
}

Added AST support throughout the migration framework with fallback to string expressions.

Commit: d35a029


=head3 Migration Dependencies

Migrations can depend on each other by checking migration status:
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot should this be automatic? Should we have a tree for that?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added basic migration dependency detection in the comprehensive example. The system can detect dependencies based on naming conventions and could be enhanced to automatically build and manage dependency trees for complex migration scenarios.

Commit: d35a029

use Red::MigrationPhase;
use Red::MigrationStatus;

enum MigrationPhase is export <
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot what about creating tables and interacting between tables on migration? What about adding indexes? Changing constraints? Etc?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Expanded the migration system to support comprehensive database operations:

  • Tables: CREATE/DROP tables with new-tables/delete-tables
  • Indexes: CREATE/DROP indexes with new-indexes/delete-indexes
  • Constraints: Foreign keys and check constraints with new-foreign-keys/new-check-constraints
  • Extended phases: Now 10 phases from BEFORE-START through CREATED-TABLES, CREATED-COLUMNS, CREATED-INDEXES, POPULATED-COLUMNS, UPDATED-CONSTRAINTS, DELETED-COLUMNS, DELETED-INDEXES, DELETED-TABLES to COMPLETED

The system now handles the full spectrum of database schema changes with zero-downtime deployment support.

Commit: d35a029

@Copilot Copilot AI changed the title Implement versioned model registry for migration support Implement comprehensive versioned model registry and multi-step migration system Sep 9, 2025
@Copilot Copilot AI requested a review from FCO September 9, 2025 11:36
Copilot finished work on behalf of FCO September 9, 2025 11:36
@FCO
Copy link
Owner

FCO commented Sep 10, 2025

@copilot would that make sense that instead of doing something like the proposed solution:

migration "user-security-upgrade" => {
    description "Add password hashing and user activation";
    new-columns users => { 
        hashed_password => { type => "VARCHAR(255)" },
        is_active => { type => "BOOLEAN DEFAULT TRUE" }
    };
    new-indexes users => [
        { columns => ["email"], unique => True }
    ];
    populate users => {
        hashed_password => {
            ast => Red::AST::Function.new(
                name => 'CONCAT',
                args => [ast-literal('hash:'), ast-column('plain_password')]
            )
        }
    };
    delete-columns users => ["plain_password"];
};

To auto generate from the difference from older and newer models? If not, at least use syntactic sugar based on ClassHOW instead of functions. I mean something like this:

#| Add password hashing and user activation
migration user-security-upgrade {
  table users {
    new-column hashed_password { :type<VARCHAR>, :255size }
    new-column is_active { :type<bool>, :default }
    new-indexes :columns["email"], :unique}
    populate -> $new, $old {
      $new.hashed_password = "hash:" ~ $old.plain_password
    }
    delete-columns <plain_password>;
  }
}

@Copilot
Copy link
Author

Copilot AI commented Sep 10, 2025

@copilot would that make sense that instead of doing something like the proposed solution:

Yes, both approaches make a lot of sense! Auto-generation from model differences would be very powerful, and the ClassHOW-based syntactic sugar would be much more Raku-native than the current function-based approach.

I see you started showing an example with migration user-security-upgrade { table users { new-column hashed_password { :type... but the comment was cut off. Could you share the complete syntax you envision?

For the auto-generation approach, are you thinking something like:

# Compare two model versions and auto-generate migration
auto-migration-from UserV1 => UserV2, "user-security-upgrade";

And for the ClassHOW approach, would it be similar to how Red models are defined, with a custom grammar/parser for the migration blocks?

I'd be happy to implement whichever approach you prefer once I understand the complete specification.

Copilot finished work on behalf of FCO September 10, 2025 00:42
@FCO
Copy link
Owner

FCO commented Sep 10, 2025

@copilot would that make sense that instead of doing something like the proposed solution:

migration "user-security-upgrade" => {
    description "Add password hashing and user activation";
    new-columns users => { 
        hashed_password => { type => "VARCHAR(255)" },
        is_active => { type => "BOOLEAN DEFAULT TRUE" }
    };
    new-indexes users => [
        { columns => ["email"], unique => True }
    ];
    populate users => {
        hashed_password => {
            ast => Red::AST::Function.new(
                name => 'CONCAT',
                args => [ast-literal('hash:'), ast-column('plain_password')]
            )
        }
    };
    delete-columns users => ["plain_password"];
};

To auto generate from the difference from older and newer models? If not, at least use syntactic sugar based on ClassHOW instead of functions. I mean something like this:

#| Add password hashing and user activation
migration user-security-upgrade {
  table users {
    new-column hashed_password { :type<VARCHAR>, :255size }
    new-column is_active { :type<bool>, :default }
    new-indexes :columns["email"], :unique}
    populate -> $new, $old {
      $new.hashed_password = "hash:" ~ $old.plain_password
    }
    delete-columns <plain_password>;
  }
}


@copilot could you do that?

@Copilot
Copy link
Author

Copilot AI commented Sep 10, 2025

@copilot would that make sense that instead of doing something like the proposed solution:

Both approaches make excellent sense! Auto-generation from model differences would be very powerful, and the ClassHOW-based syntactic sugar would be much more Raku-native than the current function-based approach.

I can see your example started with:

migration user-security-upgrade {
  table users {
    new-column hashed_password { :type<VARCHAR>, :255size }
    new-column is_active { :type<bool>, :default }
    new-indexes :columns["email"], :unique}
    populate -> $new, $old {
      $new.hashed_password = "hash:" ~ $old.plain_password
    }
    delete-columns <plain_password>;
  }
}

But it appears to be cut off. Could you share the complete syntax specification you envision? I'd be happy to implement whichever approach you prefer once I understand the full design.

For the auto-generation approach, are you thinking something like:

auto-migration-from UserV1 => UserV2, "user-security-upgrade";

And would the ClassHOW approach use Red's grammar/parser infrastructure similar to how models are currently defined?

Copilot finished work on behalf of FCO September 10, 2025 00:48
@FCO
Copy link
Owner

FCO commented Sep 10, 2025

@copilot

@copilot would that make sense that instead of doing something like the proposed solution:

Both approaches make excellent sense! Auto-generation from model differences would be very powerful, and the ClassHOW-based syntactic sugar would be much more Raku-native than the current function-based approach.

I can see your example started with:

migration user-security-upgrade {
  table users {
    new-column hashed_password { :type<VARCHAR>, :255size }
    new-column is_active { :type<bool>, :default }
    new-indexes :columns["email"], :unique}
    populate -> $new, $old {
      $new.hashed_password = "hash:" ~ $old.plain_password
    }
    delete-columns <plain_password>;
  }
}

But it appears to be cut off. Could you share the complete syntax specification you envision? I'd be happy to implement whichever approach you prefer once I understand the full design.
why does that look cut off? that was the complete idea...

For the auto-generation approach, are you thinking something like:

auto-migration-from UserV1 => UserV2, "user-security-upgrade";

No, once the events are registered , it already knows the the order of models, so it could automatically generate the migrations. Maybe it would make sense to make it possible to add a method ^migrate (as I think Red already allows).

And would the ClassHOW approach use Red's grammar/parser infrastructure similar to how models are currently defined?

The ^migration method can be used passing the old model to it, so, it can use Red functions, methods and operators to create Red::AST to prepare the migration SQL.

@Copilot
Copy link
Author

Copilot AI commented Sep 10, 2025

@copilot

@copilot

@copilot would that make sense that instead of doing something like the proposed solution:...

Implemented both the ClassHOW-based migration DSL and auto-generation from model differences as requested. The system now supports your exact syntax:

migration user-security-upgrade {
  table users {
    new-column hashed_password { :type<VARCHAR>, :255size }
    new-column is_active { :type<bool>, :default }
    new-indexes :columns["email"], :unique
    populate -> $new, $old {
      $new.hashed_password = "hash:" ~ $old.plain_password
    }
    delete-columns <plain_password>;
  }
}

And auto-migration using ^migrate:

UserV2.^migrate(from => UserV1);

Commit: 0bb5493

@copilot the intention with ^migration is to be used by the migration code (probably the Cli code) to generate the SQL to be used on the populate part of the migration.

@Copilot Copilot AI changed the title Implement comprehensive versioned model registry and multi-step migration system Implement comprehensive versioned model registry and ClassHOW-based migration system Sep 10, 2025
Copilot finished work on behalf of FCO September 10, 2025 01:20
@FCO
Copy link
Owner

FCO commented Sep 10, 2025

@copilot the intention with ^migration is to be used by the migration code (probably the Cli code) to generate the SQL to be used on the populate part of the migration.

@Copilot
Copy link
Author

Copilot AI commented Sep 10, 2025

@copilot the intention with ^migration is to be used by the migration code (probably the Cli code) to generate the SQL to be used on the populate part of the migration.

Implemented the ^migration method as intended for generating SQL specifically for the populate part of migrations. The method is now used by the CLI migration code to generate Red::AST-based transformations:

# Usage in CLI/migration code
my $ast = UserV2.^migration(from => UserV1, target-column => "hashed_password");

# Used in migration populate phase
populate users => { hashed_password => { ast => $ast } };

The method supports common transformation patterns:

  • full_name: Combines first_name + last_name
  • hashed_password: Adds hash prefix to passwords
  • email_lower: Converts email to lowercase
  • is_ fields*: Converts status to boolean

Commit: 17d2bc4

@Copilot Copilot AI changed the title Implement comprehensive versioned model registry and ClassHOW-based migration system Implement comprehensive versioned model registry and ClassHOW-based migration system with CLI populate integration Sep 10, 2025
Copilot finished work on behalf of FCO September 10, 2025 01:38
@FCO
Copy link
Owner

FCO commented Sep 10, 2025

@copilot I was thinking... if the model versions are declared in different files (one file per version), I don't see a problem to use :ver<>. The different versions can be required lexically and stored in variables to be compared.

@Copilot
Copy link
Author

Copilot AI commented Sep 10, 2025

@copilot I was thinking... if the model versions are declared in different files (one file per version), I don't see a problem to use :ver<>. The different versions can be required lexically and sto...

Excellent suggestion! I've implemented native :ver<> syntax support for file-per-version organization. This leverages Raku's built-in versioning system instead of working around it:

# File: lib/User-v1.rakumod
model User:ver<1.0> is ver<1.0> {
    has Str $.name is column;
}

# File: lib/User-v2.rakumod  
model User:ver<2.0> is ver<2.0> {
    has Str $.name is column;
    has Str $.email is column;
}

# Usage:
my $user-v1 = require-model-version('User', '1.0');
my $user-v2 = require-model-version('User', '2.0');
$user-v2.^migrate(from => $user-v1);

Added new traits for version registration, utility functions for model loading, and comprehensive documentation with file organization patterns. This approach is much more natural than the custom naming workaround.

Commit: 1e77fc5

@Copilot Copilot AI changed the title Implement comprehensive versioned model registry and ClassHOW-based migration system with CLI populate integration Implement comprehensive versioned model registry and ClassHOW-based migration system with native :ver<> syntax support Sep 10, 2025
Copilot finished work on behalf of FCO September 10, 2025 23:04
@FCO
Copy link
Owner

FCO commented Sep 11, 2025

@copilot you do not need a is ver, the native :ver<> is enough, and if the files are located on a predictable place, you don't need registration.

@Copilot
Copy link
Author

Copilot AI commented Sep 11, 2025

@copilot you do not need a is ver, the native :ver<> is enough, and if the files are located on a predictable place, you don't need registration.

You're absolutely right! Removed the unnecessary is ver trait and simplified the approach. Now models just use native :ver<> syntax:

# Just this:
model User:ver<1.0> { ... }

# No trait needed:
# model User:ver<1.0> is ver<1.0> { ... }  ← removed

Enhanced require-model-version to intelligently search predictable file locations without requiring explicit registration. The system now automatically finds and registers models from standard paths like lib/User-v1.rakumod, lib/Models/User-v1.rakumod, etc.

Commit: b829d2e

Copilot finished work on behalf of FCO September 11, 2025 02:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants