Lesson 91 Implementation: Versioned Database Migration System & Watchlist Table
Introduction
In this lesson, I implemented a proper database migration system for the Flipnzee Auctions plugin. Instead of recreating tables or manually modifying the database whenever a new release introduces schema changes, the plugin now supports version-based migrations. This makes future updates much safer and easier to maintain.
The major objective of this lesson was to introduce the Watchlist table while ensuring that existing installations can upgrade without affecting current auction, bid, or transaction data.
Objectives
- Implement a version-based database migration manager.
- Support automatic schema upgrades during plugin activation.
- Add database version tracking.
- Create a dedicated Watchlist table.
- Keep existing auction data intact during upgrades.
- Prepare the plugin for future schema changes.
Files Modified
flipnzee-auctions.php
includes/class-database.php
includes/class-database-migration.php
Step 1: Added Database Version Constant
A dedicated database schema version constant was introduced.
define( 'FLIPNZEE_DB_VERSION', '1.3.0' );
This version is independent from the plugin version and is used exclusively for database migrations.
Step 2: Added Database Version Tracking
A helper method was implemented for updating the stored schema version.
public static function update_db_version() {
update_option(
'flipnzee_db_version',
FLIPNZEE_DB_VERSION
);
}
This ensures the plugin always knows which schema version is currently installed.
Step 3: Implemented Version-Based Migration Manager
A migration manager was created to execute pending migrations only when required.
$current_version = get_option(
'flipnzee_db_version',
'1.0.0'
);
The migration manager compares the stored version with the latest schema version and runs only the necessary migrations.
Step 4: Added Migration Methods
Separate migration methods were implemented for each schema version.
Example:
private static function migrate_to_1_3_0() {
Flipnzee_Auction_Database::create_watchlist_table();
Flipnzee_Auction_Database::update_db_version();
}
This structure keeps every database upgrade isolated and easy to maintain.
Step 5: Created Dedicated Watchlist Table
A separate Watchlist table was added.
CREATE TABLE wp_flipnzee_watchlist
The table stores:
- Watchlist ID
- Auction ID
- User ID
- Created timestamp
Watchlist Table Structure
id
auction_id
user_id
created_at
To prevent duplicate watchlist entries, a composite unique key was added.
UNIQUE KEY auction_user
(
auction_id,
user_id
)
Step 6: Database Indexes
Indexes were added for efficient lookups.
KEY auction_id
KEY user_id
These indexes improve performance when retrieving user watchlists or auction followers.
Step 7: Updated Table Creation
The database creation routine now creates four plugin tables.
flipnzee_auctions
flipnzee_bids
flipnzee_transactions
flipnzee_watchlist
Each table is created independently using dbDelta().
Step 8: Activation Flow
The activation sequence now performs the following operations:
Plugin Activation
│
▼
Create Core Tables
│
▼
Check Stored DB Version
│
▼
Run Pending Migrations
│
▼
Update Database Version
This ensures new installations receive the latest schema while existing installations are upgraded safely.
Testing Performed
The implementation was tested by:
- Activating the plugin on a clean WordPress installation.
- Verifying automatic database version updates.
- Confirming the creation of the Watchlist table.
- Checking successful execution of migration methods.
- Ensuring existing auction, bid, and transaction tables remained intact.
- Running PHP syntax validation on modified files.
- Testing activation on multiple environments.
Challenges Encountered
During implementation, several issues were identified and resolved:
- Missing migration method caused activation errors.
- Incorrect
dbDelta()variable usage during table creation. - Separate table creation logic required refinement.
- Database version synchronization needed adjustment.
- Environment-specific activation behaviour differed between hosting providers.
Interestingly, the plugin activated successfully on a clean WP Engine installation, while one development environment produced activation warnings. Since the same code functioned correctly on another WordPress installation, the issue was determined to be environment-specific rather than a problem with the migration implementation.
Lessons Learned
This lesson reinforced several important WordPress development concepts:
- Database schema versions should be managed separately from plugin versions.
- Incremental migrations are safer than rebuilding database tables.
- Each migration should have a dedicated method to improve maintainability.
dbDelta()should be executed independently for each table definition.- Proper indexing and unique constraints improve performance and data integrity.
- Testing across multiple hosting environments is valuable, as environment-specific behaviour can expose issues that are not caused by the plugin itself.
Download Source Code
Download the starting version of the plugin before the lesson:
Download the completed version after this lesson:
Outcome
At the end of this lesson, Flipnzee Auctions now includes a robust versioned database migration system capable of upgrading existing installations without data loss. The new Watchlist table has been integrated successfully, providing the foundation for upcoming Watchlist functionality while establishing a scalable migration framework for future plugin releases.
