mirror of
https://github.com/moodle/moodle.git
synced 2025-01-18 05:58:34 +01:00
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:
parent
4276a19a78
commit
2baf1380d4
@ -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';
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user