Skip to content

Conversation

Copy link

Copilot AI commented Sep 11, 2025

This PR adds a new update method to schema(...) objects that intelligently compares the current schema definition with the database state and applies necessary changes to make them match.

Problem

Previously, there was no way to automatically update database schemas when model definitions changed. Users had to manually manage schema migrations or recreate tables entirely:

schema(Account, Transaction).create;  # Works first time
# After changing model definitions, no easy way to update the database

Solution

Added a new update method to Red::Schema that provides intelligent schema migration:

schema(Account, Transaction).update;  # Compares schema with DB and applies changes
schema(Account, Transaction).update;  # Idempotent - safe to run multiple times

The method can also be chained like other schema methods:

schema(Account, Transaction).create.update;  # Method chaining supported

Implementation

The implementation leverages Red's existing schema comparison infrastructure:

  1. Added Red::Schema.update method that compares model definitions with database state using diff-from-db
  2. Uses existing diff-to-ast infrastructure to convert differences into executable AST nodes
  3. Executes changes in proper order to handle dependencies and constraints
  4. Runs in a transaction to ensure atomicity of schema changes
  5. Preserves existing data during schema updates

The solution reuses Red's robust schema reading and migration mechanisms, ensuring consistency with existing patterns.

Key Features

  • Intelligent Comparison: Automatically detects differences between model definitions and database schema
  • Idempotent: Safe to run multiple times - only applies necessary changes
  • Data Preservation: Existing data is preserved during schema updates
  • Transaction Safety: All changes are wrapped in a transaction
  • Method Chaining: Returns schema object to allow method chaining
  • Comprehensive: Handles missing tables, column changes, constraints, and relationships

Testing

Added comprehensive tests covering:

  • Basic update functionality with single and multiple tables
  • Missing table creation during updates
  • Idempotent behavior (multiple updates are safe)
  • Data preservation during schema changes
  • Method chaining capabilities
  • Complex schemas with foreign key relationships

All existing tests continue to pass, ensuring no breaking changes.

Usage Example

use Red;
use Red::Schema;

# Define your models
model User {
    has Int $.id   is serial;
    has Str $.name is column;
}

# Create schema
my $schema = schema(User);
$schema.create;

# Later, after modifying your model definitions...
# Just call update to apply changes automatically
$schema.update;

Fixes #482.


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

Copilot AI and others added 2 commits September 11, 2025 02:22
Co-authored-by: FCO <99834+FCO@users.noreply.github.com>
Co-authored-by: FCO <99834+FCO@users.noreply.github.com>
Copilot AI changed the title [WIP] :if-not-exists flag for schema(...).create? Add :if-not-exists flag support to schema(...).create Sep 11, 2025
Copilot AI requested a review from FCO September 11, 2025 02:25
@FCO
Copy link
Owner

FCO commented Sep 11, 2025

@copilot instead of implementing that, I think it's better to add the method update to the schema object, and that will see if there is differences between the schema definition and the database, if it does, it will execute the changes needed on db to make it equal

Copy link
Author

Copilot AI commented Sep 11, 2025

@copilot instead of implementing that, I think it's better to add the method update to the schema object, and that will see if there is differences between the schema definition and the database, if...

I understand. Instead of the :if-not-exists flag, you'd prefer a schema update method that compares the current schema definition with the database and applies necessary changes. I'll revert the current implementation and implement the update method approach instead. This will provide more intelligent schema management.

Copilot AI and others added 2 commits September 11, 2025 02:46
- Add update method to Red::Schema that compares model definitions with database state
- Uses existing diff-from-db and diff-to-ast infrastructure for changes
- Handles missing tables, column differences, and relationship updates
- Includes comprehensive tests for various update scenarios
- Method is idempotent and preserves existing data
- Supports method chaining like other schema methods

This addresses FCO's feedback to provide a more sophisticated schema update mechanism instead of simple :if-not-exists flag.

Co-authored-by: FCO <99834+FCO@users.noreply.github.com>
- Add comprehensive documentation to the update method
- Create example showing real-world usage patterns
- Document that method is idempotent and preserves data
- Show method chaining capabilities

Co-authored-by: FCO <99834+FCO@users.noreply.github.com>
Copilot AI changed the title Add :if-not-exists flag support to schema(...).create Add schema.update method for intelligent schema migration Sep 11, 2025
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.

:if-not-exists flag for schema(...).create?

2 participants