Skip to content

Commit e20336b

Browse files
authored
Merge pull request #1076 from kabalin/pluginupgrades
[docs] Plugin upgrade step delaying.
2 parents 562f79d + cb093e4 commit e20336b

File tree

1 file changed

+34
-17
lines changed

1 file changed

+34
-17
lines changed

docs/guides/upgrade/index.md

+34-17
Original file line numberDiff line numberDiff line change
@@ -16,19 +16,20 @@ Correct use of this API allows Moodle to automatically create, and handle upgrad
1616

1717
This process is controlled by three primary files within your plugin, and a number of additional optional files for optional features:
1818

19-
- [version.php](../../apis/commonfiles/version.php/index.md): This records the version of the plugin code. You must increase version in version.php after any change in the `/db/` folder, any change in JavaScript code, any new auto-loaded class, any new setting and also after any change in language pack, because a new version triggers the upgrade procedure and resets all caches.
20-
- db/install.xml: This file describes the database tables that will be created during installation. It is only used during the initial installation of the plugin.
21-
- db/upgrade.php: This file is used during the upgrade process when upgrading from an older version of the plugin installed upgrades to the latest version.
19+
- [`version.php`](../../apis/commonfiles/version.php/index.md): This records the version of the plugin code. You must increase version in `version.php` after any change in the `db/` folder, any change in JavaScript code, any new auto-loaded class, any new setting and also after any change in language pack, because a new version triggers the upgrade procedure and resets all caches.
20+
- `db/install.xml`: This file describes the database tables that will be created during installation. It is only used during the initial installation of the plugin.
21+
- `db/upgrade.php`: This file is used during the upgrade process when upgrading from an older version of the plugin installed upgrades to the latest version.
22+
- `db/upgradelib.php`: This file is optional. When upgrade step process is not trivial, it is possible to define upgrade function here and call it from upgrade step. Functions added to `upgradelib.php` can be covered by unittest to be sure it does right thing and reflects recent API changes.
2223

2324
### version.php
2425

25-
The version.php file describes the current version of the plugin, and additional features such as its maturity, any dependencies or requirements, and a release name.
26+
The `version.php` file describes the current version of the plugin, and additional features such as its maturity, any dependencies or requirements, and a release name.
2627

2728
See the documentation on [version.php](../../apis/commonfiles/version.php/index.md) for further information on the features of this file.
2829

2930
### db/install.xml
3031

31-
The install.xml file describes the database tables that will be created when the plugin is installed.
32+
The `install.xml` file describes the database tables that will be created when the plugin is installed.
3233

3334
:::important
3435

@@ -38,11 +39,11 @@ The content of the `install.xml` file **must** be created and maintained using t
3839

3940
### db/upgrade.php
4041

41-
The upgrade.php file describes the steps used to migrate the plugin from one version to a newer version. Moodle only supports the upgrade of plugins. **Plugins can not be downgraded**.
42+
The `upgrade.php` file describes the steps used to migrate the plugin from one version to a newer version. Moodle only supports the upgrade of plugins. **Plugins can not be downgraded**.
4243

4344
:::important
4445

45-
The content of the `upgrade.php` file **must** be created and maintained using the [XMLDB Editor](/general/development/tools/xmldb).
46+
The database fields definition content of the `upgrade.php` file **must** be created and maintained using the [XMLDB Editor](/general/development/tools/xmldb).
4647

4748
:::
4849

@@ -58,14 +59,10 @@ function xmldb_[plugintype]_[pluginname]_upgrade($oldversion): bool {
5859

5960
if ($oldversion < 2019031200) {
6061
// Perform the upgrade from version 2019031200 to the next version.
61-
62-
// The content of this section should be generated using the XMLDB Editor.
6362
}
6463

6564
if ($oldversion < 2019031201) {
6665
// Perform the upgrade from version 2019031201 to the next version.
67-
68-
// The content of this section should be generated using the XMLDB Editor.
6966
}
7067

7168
// Everything has succeeded to here. Return true.
@@ -78,7 +75,7 @@ function xmldb_[plugintype]_[pluginname]_upgrade($oldversion): bool {
7875
During an upgrade, restrictions are placed on the functions that your upgrade code may call. This is because Moodle has not been fully update and some APIs may have code in place relating to a future database or data format.
7976

8077
- All upgrade code may use the [basic database API](../../apis/core/dml/index.md).
81-
- In a **plugin**, upgrade code should not call **any plugin functions**. For example, if your plugin has a function that changes frog settings to 'green', and you need to do this during upgrade, then you **must not** call this function; instead, manually update the database rows so that the frog settings become green). However, **you _may_ call core functions** rather than making core changes in database.
78+
- In a **plugin**, upgrade code should not call **any plugin functions** directly. For example, if your plugin has a function that changes frog settings to 'green', and you need to do this during upgrade, then you **must not** call this function; instead, manually update the database rows so that the frog settings become green). However, **you _may_ call core functions** rather than making core changes in database.
8279
- In **core**, upgrade code should not even call **any core functions**. For example, if you need to add a calendar event, this should be done by inserting into a database table rather than calling a function to add the event. Certain functions marked with a comment such as `set_config` and `get_config` are excepted.
8380

8481
:::info Rationale for these rules
@@ -99,13 +96,33 @@ Core functions are now safe to call because the core data is in Current state. B
9996

10097
:::
10198

99+
### Delaying upgrade
100+
101+
In some cases, upgrade function execution needs to be delayed:
102+
103+
- For example, if we change the DB structure **after** this upgrade script and the API method expects that a field is present but at the moment when the upgrade script is executed it is not there yet.
104+
- The upgrade script requires cache rebuild or any other operation that is simply not available during upgrade (i.e. calling course cache rebuild will throw an exception if executed during upgrade)
105+
- It is a long-running script
106+
107+
In this scenario, we call upgrade function in [adhoc task](../../apis/subsystems/task/adhoc.md) and schedule its run as follows:
108+
109+
```php title="Example of scheduling adhoc task in upgrade step"
110+
if ($oldversion < 2020031001) {
111+
// Schedule ad-hoc task to migrate existing course completion data.
112+
$task = new \plugintype_pluginname\task\migrate_course_completion();
113+
\core\task\manager::queue_adhoc_task($task, true);
114+
// Datastore savepoint reached.
115+
upgrade_plugin_savepoint(true, 2020031001, 'plugintype', 'pluginname');
116+
}
117+
```
118+
102119
## Summary
103120

104-
The first time a user installs any version of your plugin, the install.xml file will be used to create all the required database tables. Therefore install.xml should always contain the definition of the up-to-date database structure. Moodle recognises this situation because there is a version.php file on disc, but there is no (*plugintype*_*pluginname*, version) value in the config_plugins table.
121+
The first time a user installs any version of your plugin, the `install.xml` file will be used to create all the required database tables. Therefore `install.xml` should always contain the definition of the up-to-date database structure. Moodle recognises this situation because there is a `version.php` file on disc, but there is no (*plugintype*_*pluginname*, version) value in the `config_plugins` table.
105122

106-
If the user already had a version of your plugin installed, and then upgrades to a newer version, Moodle will detect this because the version.php file will contain a newer version number than the (*plugintype*_*pluginname*, version) value in the mdl_config_plugins table. In this case, Moodle will run the code in the upgrade.php file, passing in the old version number, so that the correct bits of upgrade can be run, as controlled by the if ($oldversion < XXXXXXXXXX) blocks of code.
123+
If the user already had a version of your plugin installed, and then upgrades to a newer version, Moodle will detect this because the `version.php` file will contain a newer version number than the (*plugintype*_*pluginname*, version) value in the `mdl_config_plugins` table. In this case, Moodle will run the code in the `upgrade.php` file, passing in the old version number, so that the correct bits of upgrade can be run, as controlled by the `if ($oldversion < XXXXXXXXXX)` blocks of code.
107124

108-
The contents of the install.xml and upgrade.php files should be generated using the XMLDB editor.
125+
The contents of the `install.xml` and database fields changes in `upgrade.php` files should be generated using the XMLDB editor.
109126

110127
## Other things that can be in the db folder
111128

@@ -138,7 +155,7 @@ Some of these functions have variants depending on whether they are being called
138155

139156
When called from core, the `main` variant should be used, otherwise the frankenstyle name of the component should be used.
140157

141-
For example, if you are defining an installation behaviour in the install.php script of a block named `block_example`, you would have an install.php similar to the following:
158+
For example, if you are defining an installation behaviour in the `install.php` script of a block named `block_example`, you would have an `install.php` similar to the following:
142159

143160
```php title="blocks/example/db/install.php"
144161
<?php
@@ -194,7 +211,7 @@ if (!$dbman->table_exists($table)) {
194211

195212
</ValidExample>
196213

197-
You should also think about what version numbers to put in your version.php file on each branch. Above all, test carefully.
214+
You should also think about what version numbers to put in your `version.php` file on each branch. Above all, test carefully.
198215

199216
:::
200217

0 commit comments

Comments
 (0)