From bc30a228c8bfa0b95ad373c806de0844f3f05b70 Mon Sep 17 00:00:00 2001 From: mscherer Date: Tue, 13 Jan 2026 04:12:57 +0100 Subject: [PATCH] Docs: Improve documentation for 5.x release - Add insertOrUpdate() and insertOrSkip() documentation to seeding guide - Document MySQL ALTER TABLE ALGORITHM/LOCK options - Fix grammar issue in index.rst ("can has" -> "has") - Update phinxlog references to generic "migrations tracking table" --- docs/en/index.rst | 12 ++--- docs/en/seeding.rst | 82 ++++++++++++++++++++++++++++++++++ docs/en/writing-migrations.rst | 66 +++++++++++++++++++++++++++ 3 files changed, 154 insertions(+), 6 deletions(-) diff --git a/docs/en/index.rst b/docs/en/index.rst index 5db4fe1a..7936f48a 100644 --- a/docs/en/index.rst +++ b/docs/en/index.rst @@ -3,7 +3,7 @@ Migrations Migrations is a plugin that lets you track changes to your database schema over time as PHP code that accompanies your application. This lets you ensure each -environment your application runs in can has the appropriate schema by applying +environment your application runs in has the appropriate schema by applying migrations. Instead of writing schema modifications in SQL, this plugin allows you to @@ -468,8 +468,8 @@ for use in unit tests), you can use the ``--generate-only`` flag: bin/cake bake migration_snapshot Initial --generate-only -This will create the migration file but will not add an entry to the phinxlog -table, allowing you to move the file to a different location without causing +This will create the migration file but will not add an entry to the migrations +tracking table, allowing you to move the file to a different location without causing "MISSING" status issues. The same logic will be applied implicitly if you wish to bake a snapshot for a @@ -603,15 +603,15 @@ Cleaning up missing migrations ------------------------------- Sometimes migration files may be deleted from the filesystem but still exist -in the phinxlog table. These migrations will be marked as **MISSING** in the -status output. You can remove these entries from the phinxlog table using the +in the migrations tracking table. These migrations will be marked as **MISSING** in the +status output. You can remove these entries from the tracking table using the ``--cleanup`` option: .. code-block:: bash bin/cake migrations status --cleanup -This will remove all migration entries from the phinxlog table that no longer +This will remove all migration entries from the tracking table that no longer have corresponding migration files in the filesystem. Marking a migration as migrated diff --git a/docs/en/seeding.rst b/docs/en/seeding.rst index 94f9459e..e77446c3 100644 --- a/docs/en/seeding.rst +++ b/docs/en/seeding.rst @@ -450,6 +450,88 @@ within your seed class and then use the ``insert()`` method to insert data: You must call the ``saveData()`` method to commit your data to the table. Migrations will buffer data until you do so. +Upserting Data +-------------- + +.. versionadded:: 5.0.0 + ``insertOrUpdate()`` and ``insertOrSkip()`` were added in 5.0.0. + +For seeds that may be run multiple times, you can use ``insertOrUpdate()`` to insert +new records or update existing ones based on conflict columns. This is particularly +useful for configuration or reference data that should always reflect certain values: + +.. code-block:: php + + 'site_name', + 'value' => 'My Application', + ], + [ + 'key' => 'maintenance_mode', + 'value' => 'false', + ], + ]; + + $settings = $this->table('settings'); + // For PostgreSQL and SQLite, you must specify the conflict column(s) + $settings->insertOrUpdate($data, ['key']) + ->saveData(); + + // For MySQL, conflict columns are optional (uses all unique constraints) + // $settings->insertOrUpdate($data)->saveData(); + } + } + +.. note:: + + The ``$conflictColumns`` parameter behavior differs by database: + + - **MySQL**: The parameter is ignored because MySQL's ``ON DUPLICATE KEY UPDATE`` + automatically applies to all unique constraints. + - **PostgreSQL/SQLite**: The parameter is required and specifies which column(s) + to use for conflict detection. + +Insert or Skip +~~~~~~~~~~~~~~ + +If you want to insert records only when they don't already exist (without updating), +use the ``insertOrSkip()`` method: + +.. code-block:: php + + 'admin', 'description' => 'Administrator'], + ['name' => 'user', 'description' => 'Regular User'], + ['name' => 'guest', 'description' => 'Guest User'], + ]; + + $roles = $this->table('roles'); + // Skip inserting if a role with the same name already exists + $roles->insertOrSkip($data, ['name']) + ->saveData(); + } + } + +This is useful for seeding default data that should not overwrite any customizations +made by users. + Truncating Tables ================= diff --git a/docs/en/writing-migrations.rst b/docs/en/writing-migrations.rst index 81c7df08..b3df56cd 100644 --- a/docs/en/writing-migrations.rst +++ b/docs/en/writing-migrations.rst @@ -599,6 +599,72 @@ configuration key for the time being. To view available column types and options, see :ref:`adding-columns` for details. +MySQL ALTER TABLE Options +------------------------- + +.. versionadded:: 5.0.0 + ``ALGORITHM`` and ``LOCK`` options were added in 5.0.0. + +When modifying tables in MySQL, you can control how the ALTER TABLE operation is +performed using the ``algorithm`` and ``lock`` options. This is useful for performing +zero-downtime schema changes on large tables in production environments. + +.. code-block:: php + + table('large_table'); + $table->addIndex(['status'], [ + 'name' => 'idx_status', + ]); + $table->update([ + 'algorithm' => 'INPLACE', + 'lock' => 'NONE', + ]); + } + } + +Available ``algorithm`` values: + +============ =========== +Algorithm Description +============ =========== +DEFAULT Let MySQL choose the algorithm (default behavior) +INPLACE Modify the table in place without copying data (when possible) +COPY Create a copy of the table with the changes (legacy method) +INSTANT Only modify metadata, no table rebuild (MySQL 8.0+, limited operations) +============ =========== + +Available ``lock`` values: + +========= =========== +Lock Description +========= =========== +DEFAULT Use minimal locking for the algorithm (default behavior) +NONE Allow concurrent reads and writes during the operation +SHARED Allow concurrent reads but block writes +EXCLUSIVE Block all reads and writes during the operation +========= =========== + +.. note:: + + Not all operations support all algorithm/lock combinations. MySQL will raise + an error if the requested combination is not possible for the operation. + The ``INSTANT`` algorithm is only available in MySQL 8.0+ and only for specific + operations like adding columns at the end of a table. + +.. warning:: + + Using ``ALGORITHM=INPLACE, LOCK=NONE`` does not guarantee zero-downtime for + all operations. Some operations may still require a table copy or exclusive lock. + Always test schema changes on a staging environment first. + Table Partitioning ------------------