MDL-19695 field dependencies - defined new exception ddl_dependency_exception that

will be thrown when one DDL operation (drop only for now) is attempted over one
field being part of indexes.
This commit is contained in:
stronk7 2009-07-02 16:08:44 +00:00
parent 4276a19a78
commit 2baf1380d4
3 changed files with 73 additions and 24 deletions

View File

@ -171,6 +171,7 @@ $string['dbsessionmysqlpacketsize'] = 'Serious session error detected.<br /><br
$string['ddlexecuteerror'] = 'DDL sql execution error';
$string['ddlfieldalreadyexists'] = 'Field \"$a\" does not exist';
$string['ddlfieldnotexist'] = 'Field \"$a->fieldname\" does not exist in table \"$a->tablename\"';
$string['ddldependencyerror'] = '$a->targettype \"$a->targetname\" cannot be modifed. Dependency found with $a->offendingtype \"$a->offendingname\"';
$string['ddltablealreadyexists'] = 'Table \"$a\" already exists';
$string['ddltablenotexist'] = 'Table \"$a\" does not exist';
$string['ddlunknownerror'] = 'Unknown DDL library error';

View File

@ -611,6 +611,8 @@ class database_manager {
if (!$this->field_exists($xmldb_table, $xmldb_field)) {
throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName());
}
/// Check for dependencies in the DB before performing any action
$this->check_field_dependencies($xmldb_table, $xmldb_field);
if (!$sqlarr = $this->generator->getDropFieldSQL($xmldb_table, $xmldb_field)) {
throw new ddl_exception('ddlunknownerror', null, 'drop_field sql not generated');
@ -678,6 +680,30 @@ class database_manager {
$this->change_field_type($xmldb_table, $xmldb_field);
}
/**
* This function will change the default of the field in the table passed as arguments
* One null value in the default field means delete the default
*
* @param xmldb_table table object (just the name is mandatory)
* @param xmldb_field field object (full specs are required)
* @return void
*/
public function change_field_default(xmldb_table $xmldb_table, xmldb_field $xmldb_field) {
if (!$this->table_exists($xmldb_table)) {
throw new ddl_table_missing_exception($xmldb_table->getName());
}
/// Check the field exists
if (!$this->field_exists($xmldb_table, $xmldb_field)) {
throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName());
}
if (!$sqlarr = $this->generator->getModifyDefaultSQL($xmldb_table, $xmldb_field)) {
return; //Empty array = nothing to do = no error
}
$this->execute_sql_arr($sqlarr);
}
/**
* This function will drop the existing enum of the field in the table passed as arguments
*
@ -709,30 +735,6 @@ class database_manager {
$this->execute_sql_arr($sqlarr);
}
/**
* This function will change the default of the field in the table passed as arguments
* One null value in the default field means delete the default
*
* @param xmldb_table table object (just the name is mandatory)
* @param xmldb_field field object (full specs are required)
* @return void
*/
public function change_field_default(xmldb_table $xmldb_table, xmldb_field $xmldb_field) {
if (!$this->table_exists($xmldb_table)) {
throw new ddl_table_missing_exception($xmldb_table->getName());
}
/// Check the field exists
if (!$this->field_exists($xmldb_table, $xmldb_field)) {
throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName());
}
if (!$sqlarr = $this->generator->getModifyDefaultSQL($xmldb_table, $xmldb_field)) {
return; //Empty array = nothing to do = no error
}
$this->execute_sql_arr($sqlarr);
}
/**
* This function will rename the field in the table passed as arguments
* Before renaming the field, the function will check it exists
@ -777,6 +779,35 @@ class database_manager {
$this->execute_sql_arr($sqlarr);
}
/**
* This function will check, for the given table and field, if there there is any dependency
* preventing the field to be modified. It's used by all the public methods that perform any
* DDL change on fields, throwing one ddl_dependency_exception if dependencies are found
*/
private function check_field_dependencies(xmldb_table $xmldb_table, xmldb_field $xmldb_field) {
/// Check the table exists
if (!$this->table_exists($xmldb_table)) {
throw new ddl_table_missing_exception($xmldb_table->getName());
}
/// Check the field exists
if (!$this->field_exists($xmldb_table, $xmldb_field)) {
throw new ddl_field_missing_exception($xmldb_field->getName(), $xmldb_table->getName());
}
/// Check the field isn't in use by any index in the table
if ($indexes = $this->mdb->get_indexes($xmldb_table->getName(), false)) {
foreach ($indexes as $indexname => $index) {
$columns = $index['columns'];
if (in_array($xmldb_field->getName(), $columns)) {
throw new ddl_dependency_exception('column', $xmldb_table->getName() . '->' . $xmldb_field->getName(),
'index', $indexname . ' (' . implode(', ', $columns) . ')');
}
}
}
}
/**
* This function will create the key in the table passed as arguments
*

View File

@ -130,3 +130,20 @@ class ddl_change_structure_exception extends ddl_exception {
parent::__construct('ddlexecuteerror', NULL, $errorinfo);
}
}
/**
* Error changing db structure, caused by some depency found
* like trying to modify one field having related indexes.
*/
class ddl_dependency_exception extends ddl_exception {
function __construct($targettype, $targetname, $offendingtype, $offendingname, $debuginfo=null) {
$a = new object();
$a->targettype = $targettype;
$a->targetname = $targetname;
$a->offendingtype = $offendingtype;
$a->offendingname = $offendingname;
parent::__construct('ddldependencyerror', $a, $debuginfo);
}
}