8000 feat: [#280] Optimize migrate:status command by hwbrzzl · Pull Request #696 · goravel/framework · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

feat: [#280] Optimize migrate:status command #696

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Oct 29, 2024
Merged

feat: [#280] Optimize migrate:status command #696

merged 7 commits into from
Oct 29, 2024

Conversation

hwbrzzl
Copy link
Contributor
@hwbrzzl hwbrzzl commented Oct 28, 2024

📑 Description

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a Status method for migration management, allowing users to retrieve the current migration status.
    • Added GetMigrationsByStep method to retrieve migrations based on specified steps.
    • Enhanced migration command functionality by integrating a more streamlined approach to status checks.
  • Bug Fixes

    • Improved error handling and logging for migration status checks.
  • Tests

    • Expanded test coverage for migration status and batch retrieval, ensuring accurate functionality.
  • Documentation

    • Updated command registration to reflect changes in dependency management for migration commands.

✅ Checks

  • Added test cases for my code

@hwbrzzl hwbrzzl requested a review from a team as a code owner October 28, 2024 11:25
Copy link
Contributor
coderabbitai bot commented Oct 28, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

The changes in this pull request introduce new methods and modify existing structures within the migration framework. Notably, the Migrator interface is enhanced with a new method for retrieving migration statuses. The Repository interface is updated to include a method for retrieving migrations by step and to simplify the existing method for retrieving all migrations. The MigrateStatusCommand structure is modified to utilize the Migrator interface instead of configuration settings. Additionally, several test files are adjusted to accommodate these changes, with new test cases added to ensure comprehensive coverage of the updated functionalities.

Changes

File Change Summary
contracts/database/migration/migrator.go Added method Status() error to Migrator interface.
contracts/database/migration/repository.go Updated GetMigrations method signature to remove parameter; added method GetMigrationsByStep(steps int) ([]File, error).
database/console/migration/migrate_status_command.go Updated NewMigrateStatusCommand to accept migration.Migrator. Modified Handle method to call r.migrator.Status().
database/console/migration/migrate_status_command_test.go Deleted file containing tests for MigrateStatusCommand.
database/migration/default_creator_test.go Updated Up and Down methods in DefaultCreatorSuite to use facades.Schema().
database/migration/default_migrator.go Added status struct and methods for migration status reporting; removed initialization of migrations map, now lazily populated.
database/migration/default_migrator_test.go Added TestStatus method to test migration status; updated references from driver to migrator.
database/migration/repository.go Added method GetMigrationsByStep(steps int) ([]migration.File, error) to Repository struct.
database/migration/repository_test.go Updated tests to reflect new method signatures in Repository.
database/migration/sql_migrator.go Added method Status() error to SqlMigrator struct for migration status retrieval.
database/migration/sql_migrator_test.go Added TestStatus method to SqlMigratorSuite for testing migration status.
database/migration/stubs.go Updated Create and Update methods in Stubs to include facades imports.
database/service_provider.go Updated registerCommands method to pass migrator to NewMigrateStatusCommand.

Possibly related PRs

Suggested reviewers

  • kkumar-gcc
  • devhaozi

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor
@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 13

🧹 Outside diff range and nitpick comments (10)
contracts/database/migration/migrator.go (1)

17-18: Enhance method documentation for better clarity.

The addition of the Status() method is well-designed and aligns with the interface's purpose. However, the documentation could be more descriptive about what kind of status information is returned and potential error cases.

Consider expanding the documentation like this:

-// Status get the migration's status.
+// Status retrieves the current state of all migrations, including which migrations
+// have been run and which are pending. Returns an error if the status cannot be
+// determined, e.g., due to database connectivity issues.
contracts/database/migration/repository.go (1)

20-21: LGTM! Consider enhancing the documentation.

The new method signature is well-designed and consistent with the interface's patterns. It complements existing functionality while maintaining the interface's cohesion.

Consider expanding the documentation comment to clarify the ordering of returned migrations:

-// GetMigrationBatches Get the completed migrations with their batch numbers.
+// GetMigrationBatches Get the completed migrations with their batch numbers.
+// Returns migrations ordered by batch number and migration name.
database/migration/repository.go (1)

61-68: Implementation looks good but consider pagination for large datasets.

The implementation is clean and follows the established patterns in the codebase. However, for repositories with a large number of migrations, retrieving all records at once could impact memory usage and performance.

Consider adding pagination support:

-func (r *Repository) GetMigrationBatches() ([]migration.File, error) {
+func (r *Repository) GetMigrationBatches(page, perPage int) ([]migration.File, error) {
 	var files []migration.File
-	if err := r.schema.Orm().Query().Table(r.table).OrderByDesc("batch").OrderByDesc("migration").Get(&files); err != nil {
+	if err := r.schema.Orm().Query().Table(r.table).
+		OrderByDesc("batch").
+		OrderByDesc("migration").
+		Offset((page - 1) * perPage).
+		Limit(perPage).
+		Get(&files); err != nil {
 		return nil, err
 	}
 
 	return files, nil
 }

This would allow clients to fetch migrations in smaller chunks, reducing memory usage and improving response times.

database/migration/stubs.go (1)

32-35: Great architectural improvement using the schema builder.

The transition from raw SQL to using the framework's schema builder is a solid improvement that:

  • Provides better type safety
  • Improves maintainability
  • Makes the code more consistent with the framework's design patterns

Also applies to: 63-66

database/migration/default_migrator.go (1)

239-246: Consistent Formatting for Output Titles

The printTitle method formats the title for the migration status display. Ensure that the title formatting aligns with the output for better readability.

Consider adjusting the separator length to match the total width of the output:

 func (r *DefaultMigrator) printTitle(maxNameLength int) {
 	color.Default().Print(fmt.Sprintf("%-*s", maxNameLength, "Migration name"))
 	color.Default().Println(" | Batch / Status")
-	for i := 0; i < maxNameLength+17; i++ {
+	for i := 0; i < maxNameLength+15; i++ {
 		color.Default().Print("-")
 	}
 	color.Default().Println()
 }
database/migration/default_migrator_test.go (5)

Line range hint 130-137: Ensure Cleanup of Generated Files in TestCreate

While the defer function removes the database directory after the test, consider explicitly removing the created migration file to prevent residual files if the test directory structure changes or if the test fails before reaching the defer statement.


146-157: Use Descriptive Error Messages in TestFresh

In TestFresh, errors are compared using assert.AnError, which may not provide sufficient detail. Consider using more specific error checks or custom error messages to improve test clarity and debuggability.


Line range hint 229-239: Expand Test Coverage in TestGetFilesForRollback

The TestGetFilesForRollback method could include additional test cases to cover edge conditions, such as when no migrations exist or invalid step and batch numbers are provided. This will ensure the method behaves correctly under all possible scenarios.


332-336: Simplify Output Comparison in TestPrintTitle

Comparing the exact output string with color codes in TestPrintTitle can be fragile due to potential changes in formatting or color schemes. Consider abstracting the color codes or using a helper function to compare the output without color codes to make the test more robust.


Line range hint 356-363: Enhance TestRollback with Additional Scenarios

Currently, TestRollback lacks test cases. Adding tests for various rollback scenarios, such as rolling back multiple batches or handling errors during rollback, will improve test coverage and ensure the rollback functionality is reliable.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 6ee0755 and 51d5484.

⛔ Files ignored due to path filters (2)
  • mocks/database/migration/Migrator.go is excluded by !mocks/**
  • mocks/database/migration/Repository.go is excluded by !mocks/**
📒 Files selected for processing (13)
  • contracts/database/migration/migrator.go (1 hunks)
  • contracts/database/migration/repository.go (1 hunks)
  • database/console/migration/migrate_status_command.go (1 hunks)
  • database/console/migration/migrate_status_command_test.go (0 hunks)
  • database/migration/default_creator_test.go (2 hunks)
  • database/migration/default_migrator.go (4 hunks)
  • database/migration/default_migrator_test.go (19 hunks)
  • database/migration/repository.go (1 hunks)
  • database/migration/repository_test.go (1 hunks)
  • database/migration/sql_migrator.go (2 hunks)
  • database/migration/sql_migrator_test.go (3 hunks)
  • database/migration/stubs.go (2 hunks)
  • database/service_provider.go (1 hunks)
💤 Files with no reviewable changes (1)
  • database/console/migration/migrate_status_command_test.go
🔇 Additional comments (23)
database/console/migration/migrate_status_command.go (4)

6-6: LGTM! Import changes align with the new dependency.

The addition of the migration contract import and removal of the config import properly reflect the structural changes in the command.


10-10: Great improvement in dependency design!

The switch from config.Config to migration.Migrator is a solid improvement that:

  • Makes the dependencies more explicit and focused
  • Follows interface segregation principle
  • Improves testability by allowing mock injection

13-16: LGTM! Constructor properly initializes the new dependency.

The constructor changes are consistent with the struct modifications and maintain clean initialization 8000 .


20-20: LGTM! Consistent and idiomatic receiver naming.

The change to use r as the receiver name follows Go's common practice of using short, consistent receiver names.

Also applies to: 25-25, 30-30

database/migration/repository.go (1)

61-68: Verify interface implementation and usage.

Let's ensure the new method is properly integrated into the codebase.

✅ Verification successful

Based on the results, I can generate the final response as we have comprehensive information about the implementation, interface, and usage:

Implementation is properly integrated and tested

The method is:

  • Correctly declared in the interface (contracts/database/migration/repository.go)
  • Used in the default migrator implementation (database/migration/default_migrator.go)
  • Well covered by tests in both repository_test.go and default_migrator_test.go
  • Has corresponding mock implementations for testing
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify interface declaration and usage of GetMigrationBatches

# Test 1: Check if the interface is updated
echo "Checking interface declaration..."
rg -A 1 "type Repository interface" "contracts/database/migration"

# Test 2: Look for usages of the new method
echo "Checking method usage..."
rg "GetMigrationBatches" -A 2

# Test 3: Check for corresponding tests
echo "Checking test coverage..."
rg "TestRepository.*GetMigrationBatches" "database/migration"

Length of output: 4589

database/migration/default_creator_test.go (3)

65-68: LGTM: Import statements are appropriate for the updated test implementation.

The added imports for schema contracts and facades are necessary to support the new implementation using facades.Schema().


98-101: LGTM: Duplicate imports are acceptable in test data.

The repeated import block is appropriate here as it's part of different test cases in the test data, maintaining self-contained and readable test cases.


Line range hint 114-116: Verify the empty table modification implementation.

The Update stub test case contains an empty implementation for the table modification. While this might be intentional for testing purposes, please verify if this accurately represents the test scenario you're trying to cover.

✅ Verification successful

The previous search might have been too specific. Let's broaden the search to:

  1. Find all table modifications in tests to understand the patterns
  2. Look at the complete test file to understand the context better

Empty table modification is intentional for the update stub template

The empty implementation is correct and intentional. This is a test case for verifying the migration stub generator's template structure. The test suite (DefaultCreatorSuite) is specifically testing the PopulateStub method with different stub types:

  1. Empty stub - generates a migration with empty Up/Down methods
  2. Create stub - generates a migration with table creation logic
  3. Update stub - generates a migration with an empty table modification template

The empty table modification is the expected template structure that developers will later populate with their specific column modifications. This is evident from:

  • The systematic test structure covering all stub types
  • The presence of similar empty implementations in database/migration/stubs.go
  • The test's purpose of verifying stub generation, not actual migration logic
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for similar patterns in other test files to understand if this is a common testing pattern
rg -l 'Schema\(\)\.Table.*\{\s*\}' --type go

Length of output: 46


Script:

#!/bin/bash
# Let's try a broader search pattern to find table modifications in tests
rg -A 5 'Schema\(\)\.Table.*\{' --type go

# Also search for the specific test file content
cat database/migration/default_creator_test.go

Length of output: 3908

database/migration/repository_test.go (1)

97-107: Verify edge case handling.

The current test case covers the happy path, but it would be beneficial to verify how the method handles edge cases.

Let's check if there are any existing edge case tests:

Would you like me to help generate additional test cases for:

  • Empty migrations table
  • Database connection errors
  • Invalid batch numbers
✅ Verification successful

Edge cases are already covered in the test suite

After analyzing the codebase, I found that edge cases for GetMigrationBatches are adequately covered:

  1. The empty migrations case is tested in default_migrator_test.go with "No migrations found" test case
  2. Database errors are properly handled in the implementation and tested:
    • Error handling in repository: if err := r.schema.Orm().Query()...
    • Error case tested in migrator: s.mockRepository.EXPECT().GetMigrationBatches().Return(nil, assert.AnError)
  3. The current test in repository_test.go verifies correct ordering and batch numbers

The original review comment's concern about edge cases has been addressed in the broader test suite, making additional test cases unnecessary.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for edge case tests in migration-related test files
# Expected: Tests for empty migrations table, error cases, etc.

# Look for test cases involving empty or error scenarios
rg -A 5 "TestRecord|TestCreate" "database/migration/*_test.go"

Length of output: 133


Script:

#!/bin/bash
# Let's first find the correct test file path
fd "repository_test.go"

# Then search for all test cases in the repository test file
rg -A 5 "func.*Test" repository_test.go

# Also search for error handling patterns
rg "s\.(Error|NoError)" repository_test.go

Length of output: 266


Script:

#!/bin/bash
# Now that we have the correct path, let's search in it
rg -A 5 "func.*Test" "database/migration/repository_test.go"

# Search for error handling patterns in the correct path
rg "s\.(Error|NoError)" "database/migration/repository_test.go"

# Look for the GetMigrationBatches implementation to understand error cases
rg -A 10 "GetMigrationBatches" "database/migration/"

Length of output: 7357

database/migration/sql_migrator_test.go (2)

4-4: LGTM: Required imports added correctly

The new imports (io and color) are necessary for implementing the output capture and formatting functionality in the new test.

Also applies to: 17-17


127-146: LGTM: Comprehensive test coverage

The test method effectively covers both the "no migrations" and "successful migration" scenarios across different database drivers. It properly validates the output format and error handling.

database/migration/stubs.go (1)

32-35: LGTM! Imports are correctly structured.

The new imports are properly organized and necessary for the schema operations used in the migration stubs.

database/migration/sql_migrator.go (2)

20-20: LGTM!

The color package import is correctly added and appropriately used for formatting status messages.


106-124: LGTM! Error handling and basic status reporting implemented correctly.

The implementation properly handles different error cases and reports the basic migration state.

database/migration/default_migrator.go (2)

4-11: Imports and Dependencies Added Appropriately

The additional imports such as "fmt", "slices", and support packages are necessary for the new functionality and are correctly included.


16-20: Definition of status Struct

The new status struct is correctly defined to encapsulate migration status information with the fields Name, Batch, and Ran.

database/migration/default_migrator_test.go (7)

100-100: Variable Renaming Enhances Clarity

Renaming the driver field to migrator in the DefaultMigratorSuite struct improves code readability and accurately reflects the purpose of the field.


112-112: Correct Initialization of migrator in SetupTest

Initializing s.migrator with a new DefaultMigrator instance in SetupTest is appropriate and ensures the test suite has the necessary setup for migration tests.


241-270: Thorough Testing in TestGetMaxNameLength

The TestGetMaxNameLength function comprehensively tests various cases, including empty lists, single items, multiple items, and equal length names, ensuring the method correctly calculates the maximum name length.


272-287: Proper Retrieval of Migrations in TestGetMigrations

TestGetMigrations effectively tests the retrieval of migrations from the schema, confirming that all registered migrations are correctly returned.


307-322: Accurate Pending Migrations Identification in TestPendingMigrations

The TestPendingMigrations function correctly identifies pending migrations by comparing registered migrations against those that have already run.


323-331: Correct Handling of Repository State in TestPrepareDatabase

The TestPrepareDatabase method appropriately tests both scenarios where the migration repository exists and when it needs to be created, ensuring that the migrator prepares the database as expected.


Line range hint 608-617: Graceful Handling of No Pending Migrations in TestRunPending

The TestRunPending method correctly handles cases where there are no pending migrations to run, ensuring the method does not fail or produce unintended side effects in such scenarios.

devhaozi
devhaozi previously approved these changes Oct 28, 2024
Copy link
Member
@devhaozi devhaozi left a comment

Choose a reason for hiding this comment

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

LGTM

coderabbitai[bot]
coderabbitai bot previously approved these changes Oct 28, 2024
Copy link
@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.50.

Benchmark suite Current: 1b7bb09 Previous: bef1222 Ratio
Benchmark_Fatal 2e-7 ns/op 0 B/op 0 allocs/op 1e-7 ns/op 0 B/op 0 allocs/op 2
Benchmark_Fatal - ns/op 2e-7 ns/op 1e-7 ns/op 2

This comment was automatically generated by workflow using github-action-benchmark.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0