Skip to content
This repository has been archived by the owner on Jul 14, 2021. It is now read-only.

Commit

Permalink
fixes #180 Migrations schema change - using records instead of table …
Browse files Browse the repository at this point in the history
…columns for migrations - Important Change
  • Loading branch information
Sean Downey committed Nov 19, 2011
1 parent b166236 commit 9bd89bf
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 107 deletions.
109 changes: 85 additions & 24 deletions bonfire/application/core_modules/migrations/libraries/Migrations.php
Expand Up @@ -145,13 +145,13 @@ function __construct()
if ( ! $this->_ci->db->table_exists('schema_version'))
{
$this->_ci->dbforge->add_field(array(
'version' => array('type' => 'INT', 'constraint' => 4, 'default' => 0),
'app_version' => array('type' => 'INT', 'constraint' => 4, 'default' => 0),
'type' => array('type' => 'VARCHAR', 'constraint' => 20, 'null' => FALSE),
'version_num' => array('type' => 'INT', 'constraint' => 4, 'default' => 0),
));

$this->dbforge->add_key('type', TRUE);
$this->_ci->dbforge->create_table('schema_version', TRUE);

$this->_ci->db->insert('schema_version', array('version' => 0));
$this->_ci->db->insert('schema_version', array('type' => 'core', 'version_num' => 0));
}

// Make sure out application helper is loaded.
Expand Down Expand Up @@ -431,11 +431,22 @@ public function latest()
*/
public function get_schema_version($type='')
{
$row = $this->_ci->db->get('schema_version')->row();
if ($this->_check_migrations_column('type'))
{
// new schema table layout
$type = empty($type) ? 'core' : $type;
$row = $this->_ci->db->get_where('schema_version', array('type' => $type))->row();
return isset($row->version_num) ? $row->version_num: 0;
}
else
{
$row = $this->_ci->db->get('schema_version')->row();

$schema = $type .'version';

return isset($row->$schema) ? $row->$schema : 0;
}

$schema = $type .'version';

return isset($row->$schema) ? $row->$schema : 0;
}

// --------------------------------------------------------------------
Expand Down Expand Up @@ -571,27 +582,77 @@ public function do_sql_migration($sql='')
*/
private function _update_schema_version($schema_version, $type='')
{
logit('[Migrations] Schema updated to: '. $schema_version);
logit('[Migrations] Schema '. $type.' updated to: '. $schema_version);

// If the row doesn't exist, create it...
if (!$this->_ci->db->field_exists($type .'version', 'schema_version'))
{
$this->_ci->load->dbforge();

$this->_ci->dbforge->add_column('schema_version', array(
$type .'version' => array(
'type' => 'INT',
'constraint' => 4,
'null' => true,
'default' => 0
)
if ($this->_check_migrations_column('type'))
{
// new schema table layout
$type = empty($type) ? 'core' : $type;
// If the row doesn't exist, create it...
$query = $this->_ci->db->get_where('schema_version', array('type' => $type));

if (!$query->num_rows())
{
$this->_ci->db->insert('schema_version', array(
'type' => $type,
'version_num' => $schema_version,
));

}

return $this->_ci->db->update('schema_version', array('version_num' => $schema_version), array('type' => $type));
}
else
{
// If the row doesn't exist, create it...
if (!$this->_check_migrations_column($type .'version'))
{
$this->_ci->load->dbforge();

$this->_ci->dbforge->add_column('schema_version', array(
$type .'version' => array(
'type' => 'INT',
'constraint' => 4,
'null' => true,
'default' => 0
)
));

}

return $this->_ci->db->update('schema_version', array(
$type.'version' => $schema_version
));

}
}

return $this->_ci->db->update('schema_version', array(
$type.'version' => $schema_version
));
//--------------------------------------------------------------------

/*
Method: _check_migrations_column()
Method to check if the DB table schema_version is in the new format or old
Access:
private
Parameters:
$column_name - Name of the column to check the existance of
Return:
boolean
*/
private function _check_migrations_column($column_name)
{
$row = $this->_ci->db->get('schema_version')->row();

if (isset($row->$column_name))
{
return TRUE;
}

return FALSE;
}

//--------------------------------------------------------------------
Expand Down
Expand Up @@ -180,12 +180,18 @@ public function delete()
}
}

// drop the schema #
// drop the schema - old Migration schema method
$module_name_lower = strtolower($module_name);
if ($this->db->field_exists( $module_name_lower . '_version', 'schema_version'))
{
$this->dbforge->drop_column('schema_version', $module_name_lower . '_version');
}
// drop the Migration record - new Migration schema method
$module_name_lower = strtolower($module_name);
if ($this->db->field_exists('version_num', 'schema_version'))
{
$this->db->delete('schema_version', array('type' => $module_name_lower.'_'));
}

if ($this->db->trans_status() === FALSE) {
$this->db->trans_rollback();
Expand Down Expand Up @@ -334,16 +340,19 @@ private function build_module($field_total=0)
$data['table_name'] = empty($table_name) ? $module_name : $table_name;
$data = $data + $file_data;

// update the schema first to prevent errors in duplicate column names due to Migrations.php caching db columns
$this->load->dbforge();
$this->dbforge->add_column('schema_version', array(
$data['module_name_lower'] . '_version' => array(
'type' => 'INT',
'constraint' => 4,
'null' => true,
'default' => 0
)
));
// Allow for the Old method - update the schema first to prevent errors in duplicate column names due to Migrations.php caching db columns
if (!$this->db->field_exists('version_num', 'schema_version'))
{
$this->load->dbforge();
$this->dbforge->add_column('schema_version', array(
$data['module_name_lower'] . '_version' => array(
'type' => 'INT',
'constraint' => 4,
'null' => true,
'default' => 0
)
));
}

// load the migrations library
$this->load->library('migrations/Migrations');
Expand Down
112 changes: 40 additions & 72 deletions bonfire/application/db/migrations/core/012_Migration_schema_change.php
@@ -1,66 +1,47 @@
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Migration_Permissions_to_manage_activities extends Migration {
class Migration_Migration_schema_change extends Migration {

public function up()
{
$this->load->library('session');

$prefix = $this->db->dbprefix;

// add the soft deletes column, made it (12) to accomodate time stamp change coming
$sql = "ALTER TABLE `{$prefix}activities` ADD COLUMN `deleted` TINYINT(12) DEFAULT '0' NOT NULL AFTER `created_on`";
$this->db->query($sql);

$data = array(
array(
'name' => 'Bonfire.Activities.Manage' ,
'description' => 'Allow users to access the Activities Reports'
),
array(
'name' => 'Activities.Own.View' ,
'description' => 'To view the users own activity logs'
),
array(
'name' => 'Activities.Own.Delete' ,
'description' => 'To delete the users own activity logs'
),
array(
'name' => 'Activities.User.View' ,
'description' => 'To view the user activity logs'
),
array(
'name' => 'Activities.User.Delete' ,
'description' => 'To delete the user activity logs, except own'
),
array(
'name' => 'Activities.Module.View' ,
'description' => 'To view the module activity logs'
),
array(
'name' => 'Activities.Module.Delete' ,
'description' => 'To delete the module activity logs'
),
array(
'name' => 'Activities.Date.View' ,
'description' => 'To view the users own activity logs'
),
array(
'name' => 'Activities.Date.Delete' ,
'description' => 'To delete the dated activity logs'
)
);

$this->db->insert_batch("{$prefix}permissions", $data);

// give current role (or administrators if fresh install) full right to manage permissions
$assign_role = $this->session->userdata('role_id') ? $this->session->userdata('role_id') : 1;

$permissions = $this->db->select('permission_id')->where("(name = 'Bonfire.Activities.Manage') OR (name LIKE 'Activities.%.View') OR (name LIKE 'Activities.%.Delete')")->get($prefix.'permissions')->result();
if (isset($permissions) && is_array($permissions) && count($permissions)) {
foreach ($permissions as $perm) {
$this->db->query("INSERT INTO {$prefix}role_permissions VALUES(".$assign_role.",".$perm->permission_id.")");
// get the current schema versions
$sql = "SELECT * FROM {$prefix}schema_version";
$schema_version_query = $this->db->query($sql);
$version_array = $schema_version_query->row_array();

// backup the schema_version table
$this->dbforge->rename_table($prefix.'schema_version', $prefix.'schema_version_old');

// modify the schema_version table
$fields = array(
'type' => array(
'type' => 'VARCHAR',
'constraint' => 20,
'null' => FALSE,
),
'version_num' => array(
'type' => 'INT',
'constraint' => '4',
'default' => 0,
),
);
$this->dbforge->add_field($fields);
$this->dbforge->add_key('type', TRUE);
$this->dbforge->create_table('schema_version');

// add records for each of the old permissions
foreach ($version_array as $type => $version_num)
{
$type_field = $type == 'version' ? 'core' : str_replace('version', '', $type);

if ($type_field == 'core')
{
$version_num++;
}

$this->db->query("INSERT INTO {$prefix}schema_version VALUES ('{$type_field}', ".$version_num.");");
}
}

Expand All @@ -70,24 +51,11 @@ public function down()
{
$prefix = $this->db->dbprefix;

$roles = $this->role_model->find_all();
if (isset($roles) && is_array($roles) && count($roles)) {
foreach ($roles as $role) {
// delete any but that has any of these permissions from the role_permissions table
$query = $this->db->query("SELECT `permission_id` FROM `{$prefix}permissions` WHERE `name` LIKE 'Activities.%.View' or `name` LIKE 'Activities.%.Delete' or `name` = 'Bonfire.Activities.Manage'");
foreach ($query->result_array() as $row)
{
$permission_id = $row['permission_id'];
$this->db->query("DELETE FROM `{$prefix}role_permissions` WHERE `permission_id` = '$permission_id';");
}
//delete the role
$this->db->query("DELETE FROM `{$prefix}permissions` WHERE `name` LIKE 'Activities.%.View' or `name` LIKE 'Activities.%.Delete' or `name` = 'Bonfire.Activities.Manage'");
}
}
// Reverse the schema_version table changes
$this->dbforge->drop_table('schema_version');

// drop the added deleted column
$sql = "ALTER TABLE `{$prefix}activities` DROP COLUMN `deleted`";
$this->db->query($sql);
$this->dbforge->rename_table($prefix.'schema_version_old', $prefix.'schema_version');

}

//--------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions docs/_guides/basic_info/changelog.txt
Expand Up @@ -8,6 +8,7 @@ Additions:
- Adding extra functionality to the config_file_helper to allow reading and writing of module config files
- Config setting for front end controller which is checked inside the MY_Controller/Front_Controller
- Adding "matches_pattern" method to Form Validation to ensures a string matches a basic pattern
- Upgrading the Migrations DB schema (issue #180) so that we use records instead of DB table columns for the modules

Bugs:
- #236 - Email Settings - fixing the password validation
Expand Down

0 comments on commit 9bd89bf

Please sign in to comment.