Migrations

What are Migrations?

Migrations are simple files that hold the commands to apply and remove changes to your database. This allows you and your team to easily keep track of changes made for each new module. They may create tables, modify tables or fields, etc. But they are not limited to just changing the schema. You could use them to fix bad data in the database or populate new fields.

While you could make the changes to the database by hand, migrations provide a simple, consistent way for developers to stay on track with each other's changes. It also makes it simple to apply the changes in your development environment to your production environment.

Using migration files also creates a version of your database that can be included in your current code versioning, whether you use git, svn, or another solution. While you might not have your data backed up in the case of a devastating loss, you can at least recreate your database and start over.

Migrations are contained in sequentially numbered files so the system knows the order to apply them or remove them.

Migrations Spheres

Bonfire recognizes three distinct areas where migrations can be applied: Core, Application, and Module. All of the files are exactly the same structure, but are placed in different areas to allow you to keep your numbering systems separate.

Core Migrations

Core migrations are files that are necessary for the database schema of Bonfire core. This keeps any Bonfire updates completely separate from your application's needs, and helps to remove any conflict between your own migration file numbers and Bonfire's.

These are stored under application/db/migrations/core.

Application Migrations

For your own application, you should use application-level migrations. This is the perfect place for changes apply to application-specific changes. However, if you are planning on re-using modules from one application to the next, you should consider placing them at the module level.

These migration files are stored under application/db/migrations.

Module Migrations

Each module can contain its own migrations, that can be applied completely separate of any application or core migrations. This allows for you to easily re-use your modules in other applications.

Module-level migrations are stored in modules/my_module/migrations.

Enabling Migrations

A clean install has migrations enabled by default. However, it is recommended when you move to production to disable migrations for security.

To disable migrations, edit the following line in application/core modules/migrations/config/migrations.php to be false.

$config['migrations_enabled'] = true;

Anatomy of a Migration

A migration is a subclass of Migration that implements two methods: up (perform the required transformations) and down (revert them). Within each migration you can use any of the methods that CodeIgniter provides, like the dbutils and dbforge classes.

Creating a Migration

File Name

Migration files MUST be numbered sequentially. The rest of the file name is up to you, but it is recommended that the name describe what actually happens in the file. Like Install_initial_tables, Permissions_upgrade, etc. It must end with the .php extension.

001_Install_initial_tables.php
002_Version_02_upgrades.php
003_Permissions_upgrade.php

File Structure

The file is a standard PHP class, that must follow three simple rules:

  • The class must be named the same as the file, except the number is replaced by Migration. For a file named001_Install_initial_tables.php, the class would be named Migration_Install_initial_tables. The name is case-sensitive.
  • The class MUST extend the Migration class
  • The class MUST include two methods: up() and down(). As the names imply, the up() method is ran whenever you are migrating up to that version. The down() method is ran whenever uninstalling that migration.

A Skeleton Migration

    class Migration_Install_initial_tables extends Migration
    {
      public function up()
      {
          // ...
      }

      public function down()
      {
          // ...
      }
    }

Running Migrations

Migrations can be run, both up and down, in the Bonfire admin pages. You can find them under Database / Database Tools / Migrations.

Auto-Running Migrations

Migrations can be set to auto-run when discovered by changing a couple of lines in the application/config/config.php file. At the bottom of the file you'll find the following lines.

$config['migrate.auto_core']  = TRUE;
$config['migrate.auto_app']   = FALSE;

migrate.auto_core, when set to TRUE, will run a check for new migrations for Bonfire Core on every page load.

migrate.auto_app, when set to TRUE, will run a check for new migrations for your application-specific migrations on every page load.

These are very handy to have set to TRUE in both Development and Staging/Test environments, but will slow your site down some since they check on every page load. It is recommended that Production environments set both of these to FALSE and run your migrations manually or as part of an update script.

Migration Class

The Migration class is an abstract base class which your migrations must extend.
This class provides the ability to use $this-> to reference any libraries currently loaded by Bonfire/CodeIgniter.
It also requires you to define the up()/down() methods and allows you to set the migration_type property to control the behavior of your migration.

migration_type Property

By default, the migration_type property is set to 'forge', which means the library will load dbforge and your migration will be expected to execute the commands required to perform the migration.

If the property is set to 'sql', dbforge will not be loaded, and the Migrations library will attempt to execute your migration as a SQL migration.
A SQL migration is expected to return a SQL string from the up() and down() methods which will perform the required changes when executed against the database.

Migrations Library

Properties

error

Deprecated since 0.7.1. Use getErrorMessage().

The most recent error message.

Methods

autoLatest()

Auto-run core and/or app migrations.
Used on page load to run current core and app migrations up to the latest version, if enabled in the config file.

'migrate.auto_core' determines whether core migrations are run when this method is called.

'migrate.auto_app' determines whether app migrations are run when this method is called.

doSqlMigration([$sql = ''])

Executes raw SQL migrations.
Multiple commands may be passed in $sql by separating them with a semicolon (;).

getAvailableVersions([$type = ''])

Return a list of available migrations files of the given $type.

  • If $type is empty, returns a list of core migrations.
  • If a module name is supplied in $type, returns a list of migrations for that module.
  • If $type is 'app_', returns a list of app migrations.

getErrorMessage()

Returns the most recent error message, or an empty string.

getErrors([$key = ''])

Get all of the errors (in an array), or the error message associated with the given $key.

getModuleVersions()

Retrieve the module versions in a single DB call and set the cache.
The retrieved versions will be in an array with the module names as the keys and the versions as the values.
If the database query fails, an empty array is returned.

getVersion([$type = ''[, $getLatest = false]])

Get the schema version from the cache.
If a database query is required, cache the result.

If $getLatest is true, the latest available version for the given $type will be returned.

$type can be 'app_', 'core', or the name of a module.
If $type is empty, it will default to 'core'.

install([$type = ''])

Install all migrations up to the latest version for the given $type, where $type is the name of the module, 'app_', or empty for core migrations.

Profiler
Profiler Console 0 Load Time 12.4ms Memory Used 0.89 MB Database 4 Queries vars & Config Files 87

Console

Memory Usage

Benchmarks

1 ms Loading Time: Base Classes
9 ms Controller Execution Time ( Docs / Index )
12 ms Total Execution Time

Queries

0.0002 SELECT GET_LOCK('48691f968af0ed7316290ef679199ce0', 300) AS ci_session_lockSpeed: 0.0002 - Possible keys: - Key Used: - Type: - Rows: - Extra: No tables used
0.0003 SELECT `data` FROM `bf_ci_sessions` WHERE `id` = 'eo9joaesbguiht01ags635086s4n87d3' and `ip_address` = '3.139.86.74'Speed: 0.0003 - Possible keys: - Key Used: - Type: - Rows: - Extra: Impossible WHERE noticed after reading const tables
0.0003 SHOW TABLES FROM `bonfire`
0.0003 SELECT * FROM `bf_settings`Speed: 0.0003 - Possible keys: - Key Used: - Type: ALL - Rows: 42 - Extra:
0.0010 Total Query Execution Time

Session User Data

__ci_last_regenerate 1734909235
requested_page https://kampensonline.com/docs/developer/migrations
previous_page https://kampensonline.com/docs/developer/migrations

GET DATA

No GET data exists

POST DATA

No POST data exists

URI STRING

docs/developer/migrations

CLASS/METHOD

docs/index

HTTP HEADERS

HTTP_ACCEPT */*
HTTP_USER_AGENT Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; +claudebot@anthropic.com)
HTTP_CONNECTION
SERVER_PORT 443
SERVER_NAME kampensonline.com
REMOTE_ADDR 3.139.86.74
SERVER_SOFTWARE Apache/2.4.62 (Ubuntu)
HTTP_ACCEPT_LANGUAGE
SCRIPT_NAME /index.php
REQUEST_METHOD GET
HTTP_HOST
REMOTE_HOST
CONTENT_TYPE
SERVER_PROTOCOL HTTP/1.1
QUERY_STRING
HTTP_ACCEPT_ENCODING gzip, br, zstd, deflate
HTTP_X_FORWARDED_FOR

CONFIG VARIABLES

domain kampensonline.com
base_url https://kampensonline.com
index_page
uri_protocol AUTO
url_suffix
language english
charset UTF-8
enable_hooks true
subclass_prefix MY_
composer_autoload false
permitted_uri_chars a-z 0-9~%.:_-
allow_get_array true
enable_query_strings false
controller_trigger c
function_trigger m
directory_trigger d
log_threshold 4
log_path /var/www/htdocs/bonfire/application/logs/
log_file_extension
log_file_permissions 436
log_date_format Y-m-d H:i:s
error_views_path
cache_path /var/www/htdocs/bonfire/application/cache/
cache_query_string false
encryption_key 92b35b02920621aedbed3b8b9a68c0f1
sess_cookie_name bf_session
sess_expiration 7200
sess_time_to_update 300
sess_match_ip true
sess_driver database
sess_regenerate_destroy false
sess_save_path ci_sessions
cookie_prefix
cookie_domain kampensonline.com
cookie_path /
cookie_secure false
cookie_httponly true
cookie_samesite Strict
standardize_newlines false
csrf_protection true
csrf_token_name ci_csrf_token
csrf_cookie_name ci_csrf_token
csrf_expire 7200
csrf_regenerate true
csrf_exclude_uris Array ( )
compress_output false
time_reference local
rewrite_short_tags false
proxy_ips
bonfire.installed 1
site.default_user_timezone UP12
modules_locations Array ( [/var/www/htdocs/bonfire/application/modules/] => ../../application/modules/ [/var/www/htdocs/bonfire/bonfire/modules/] => ../../bonfire/modules/ )
site.backup_folder archives/
contexts Array ( [0] => content [1] => reports [2] => settings [3] => developer )
enable_activity_logging true
sparks_path ../sparks/
template.site_path /var/www/htdocs/bonfire/public/
template.theme_paths Array ( [0] => themes )
template.default_layout index
template.ajax_layout ajax
template.use_mobile_themes false
template.default_theme default/
template.admin_theme admin
template.message_template <div class="alert alert-{type} alert-dismissable"> <button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button> <div>{message}</div> </div>
template.breadcrumb_symbol :
template.parse_views false
assets.directories Array ( [base] => assets [cache] => cache [css] => css [image] => images [js] => js [module] => module )
assets.js_opener $(document).ready(function() {
assets.js_closer });
assets.css_combine false
assets.js_combine false
assets.css_minify true
assets.js_minify true
assets.encrypt_name false
assets.encode false
assets.base_folder assets
assets.asset_folders Array ( [css] => css [js] => js [image] => images )
ui.current_shortcuts Array ( [form_save] => Array ( [description] => Save any form in the admin area. [action] => $("input[name=save]").click();return false; ) [create_new] => Array ( [description] => Create a new record in the module. [action] => window.location.href=$("a#create_new").attr("href"); ) [select_all] => Array ( [description] => Select all records in an index page. [action] => $("table input[type=checkbox]").click();return false; ) [delete] => Array ( [description] => Delete the record(s). [action] => $("#delete-me.btn-danger").click(); ) [module_index] => Array ( [description] => Return to the index of the current module. [action] => window.location.href=$("a#list").attr("href"); ) [goto_content] => Array ( [description] => Jump to the Content context. [action] => window.location.href=$("#tb_content").attr("href") ) [goto_reports] => Array ( [description] => Jump to the Reports context. [action] => window.location.href=$("#tb_reports").attr("href") ) [goto_settings] => Array ( [description] => Jump to the Settings context. [action] => window.location.href=$("#tb_settings").attr("href") ) [goto_developer] => Array ( [description] => Jump to the Developer context. [action] => window.location.href=$("#tb_developer").attr("href") ) )
emailer.write_to_file false
migrate.auto_core false
migrate.auto_app false
commonmark.valid_drivers Array ( [0] => Parsedown [1] => Markdown [2] => MarkdownExtra [3] => LeagueCommonMark )
commonmark.driver MarkdownExtended
docs.theme docs
docs.default_group developer
docs.show_dev_docs true
docs.show_app_docs true
docs.toc_file _toc.ini
docs.permitted_environments Array ( [0] => development [1] => testing [2] => production )

Files

application.php
/var/www/htdocs/bonfire/application/config/application.php
autoload.php
/var/www/htdocs/bonfire/application/config/autoload.php
config.php
/var/www/htdocs/bonfire/application/config/config.php
constants.php
/var/www/htdocs/bonfire/application/config/constants.php
database.php
/var/www/htdocs/bonfire/application/config/database.php
events.php
/var/www/htdocs/bonfire/application/config/events.php
hooks.php
/var/www/htdocs/bonfire/application/config/hooks.php
mimes.php
/var/www/htdocs/bonfire/application/config/mimes.php
profiler.php
/var/www/htdocs/bonfire/application/config/profiler.php
routes.php
/var/www/htdocs/bonfire/application/config/routes.php
Base_Controller.php
/var/www/htdocs/bonfire/application/core/Base_Controller.php
MY_Model.php
/var/www/htdocs/bonfire/application/core/MY_Model.php
App_hooks.php
/var/www/htdocs/bonfire/application/hooks/App_hooks.php
application_lang.php
/var/www/htdocs/bonfire/application/language/english/application_lang.php
Profiler.php
/var/www/htdocs/bonfire/application/libraries/Profiler.php
Base.php
/var/www/htdocs/bonfire/application/third_party/MX/Base.php
Config.php
/var/www/htdocs/bonfire/application/third_party/MX/Config.php
Controller.php
/var/www/htdocs/bonfire/application/third_party/MX/Controller.php
Lang.php
/var/www/htdocs/bonfire/application/third_party/MX/Lang.php
Loader.php
/var/www/htdocs/bonfire/application/third_party/MX/Loader.php
Benchmark.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Benchmark.php
CodeIgniter.php
/var/www/htdocs/bonfire/bonfire/ci3/core/CodeIgniter.php
Common.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Common.php
Config.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Config.php
Controller.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Controller.php
Hooks.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Hooks.php
Input.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Input.php
Lang.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Lang.php
Loader.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Loader.php
Log.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Log.php
Model.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Model.php
Output.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Output.php
Router.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Router.php
Security.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Security.php
URI.php
/var/www/htdocs/bonfire/bonfire/ci3/core/URI.php
Utf8.php
/var/www/htdocs/bonfire/bonfire/ci3/core/Utf8.php
hash.php
/var/www/htdocs/bonfire/bonfire/ci3/core/compat/hash.php
mbstring.php
/var/www/htdocs/bonfire/bonfire/ci3/core/compat/mbstring.php
password.php
/var/www/htdocs/bonfire/bonfire/ci3/core/compat/password.php
standard.php
/var/www/htdocs/bonfire/bonfire/ci3/core/compat/standard.php
DB.php
/var/www/htdocs/bonfire/bonfire/ci3/database/DB.php
DB_driver.php
/var/www/htdocs/bonfire/bonfire/ci3/database/DB_driver.php
DB_query_builder.php
/var/www/htdocs/bonfire/bonfire/ci3/database/DB_query_builder.php
DB_result.php
/var/www/htdocs/bonfire/bonfire/ci3/database/DB_result.php
mysqli_driver.php
/var/www/htdocs/bonfire/bonfire/ci3/database/drivers/mysqli/mysqli_driver.php
mysqli_result.php
/var/www/htdocs/bonfire/bonfire/ci3/database/drivers/mysqli/mysqli_result.php
directory_helper.php
/var/www/htdocs/bonfire/bonfire/ci3/helpers/directory_helper.php
form_helper.php
/var/www/htdocs/bonfire/bonfire/ci3/helpers/form_helper.php
language_helper.php
/var/www/htdocs/bonfire/bonfire/ci3/helpers/language_helper.php
url_helper.php
/var/www/htdocs/bonfire/bonfire/ci3/helpers/url_helper.php
profiler_lang.php
/var/www/htdocs/bonfire/bonfire/ci3/language/english/profiler_lang.php
Cache.php
/var/www/htdocs/bonfire/bonfire/ci3/libraries/Cache/Cache.php
Cache_dummy.php
/var/www/htdocs/bonfire/bonfire/ci3/libraries/Cache/drivers/Cache_dummy.php
Driver.php
/var/www/htdocs/bonfire/bonfire/ci3/libraries/Driver.php
CI_Session_driver_interface.php
/var/www/htdocs/bonfire/bonfire/ci3/libraries/Session/CI_Session_driver_interface.php
PHP8SessionWrapper.php
/var/www/htdocs/bonfire/bonfire/ci3/libraries/Session/PHP8SessionWrapper.php
Session.php
/var/www/htdocs/bonfire/bonfire/ci3/libraries/Session/Session.php
Session_driver.php
/var/www/htdocs/bonfire/bonfire/ci3/libraries/Session/Session_driver.php
Session_database_driver.php
/var/www/htdocs/bonfire/bonfire/ci3/libraries/Session/drivers/Session_database_driver.php
BF_Loader.php
/var/www/htdocs/bonfire/bonfire/core/BF_Loader.php
BF_Router.php
/var/www/htdocs/bonfire/bonfire/core/BF_Router.php
BF_directory_helper.php
/var/www/htdocs/bonfire/bonfire/helpers/BF_directory_helper.php
BF_form_helper.php
/var/www/htdocs/bonfire/bonfire/helpers/BF_form_helper.php
application_helper.php
/var/www/htdocs/bonfire/bonfire/helpers/application_helper.php
config_file_helper.php
/var/www/htdocs/bonfire/bonfire/helpers/config_file_helper.php
markdown_extended_helper.php
/var/www/htdocs/bonfire/bonfire/helpers/markdown_extended_helper.php
markdown_helper.php
/var/www/htdocs/bonfire/bonfire/helpers/markdown_helper.php
Assets.php
/var/www/htdocs/bonfire/bonfire/libraries/Assets.php
BF_Model.php
/var/www/htdocs/bonfire/bonfire/libraries/BF_Model.php
CommonMark.php
/var/www/htdocs/bonfire/bonfire/libraries/CommonMark.php
CommonMarkDriver.php
/var/www/htdocs/bonfire/bonfire/libraries/CommonMark/CommonMarkDriver.php
CommonMark_MarkdownExtended.php
/var/www/htdocs/bonfire/bonfire/libraries/CommonMark/drivers/CommonMark_MarkdownExtended.php
Console.php
/var/www/htdocs/bonfire/bonfire/libraries/Console.php
Events.php
/var/www/htdocs/bonfire/bonfire/libraries/Events.php
Modules.php
/var/www/htdocs/bonfire/bonfire/libraries/Modules.php
Route.php
/var/www/htdocs/bonfire/bonfire/libraries/Route.php
Template.php
/var/www/htdocs/bonfire/bonfire/libraries/Template.php
docs.php
/var/www/htdocs/bonfire/bonfire/modules/docs/config/docs.php
routes.php
/var/www/htdocs/bonfire/bonfire/modules/docs/config/routes.php
Docs.php
/var/www/htdocs/bonfire/bonfire/modules/docs/controllers/Docs.php
docs_lang.php
/var/www/htdocs/bonfire/bonfire/modules/docs/language/english/docs_lang.php
_sidebar.php
/var/www/htdocs/bonfire/bonfire/modules/docs/views/_sidebar.php
index.php
/var/www/htdocs/bonfire/bonfire/modules/docs/views/index.php
Settings_lib.php
/var/www/htdocs/bonfire/bonfire/modules/settings/libraries/Settings_lib.php
Settings_model.php
/var/www/htdocs/bonfire/bonfire/modules/settings/models/Settings_model.php
index.php
index.php
index.php
themes/docs/index.php