Merge pull request #1319 from ss23/853-alter-table

Check for ALTER TABLE in installer (fixes #853)
This commit is contained in:
Simon Welsh 2013-03-24 03:06:34 -07:00
commit a6e8169d00
3 changed files with 76 additions and 2 deletions

View File

@ -39,4 +39,14 @@ interface DatabaseConfigurationHelper {
*/
public function requireDatabaseOrCreatePermissions($databaseConfig);
/**
* Ensure we have permissions to alter tables.
*
* @param array $databaseConfig Associative array of db configuration, e.g. "server", "username" etc
* @return array Result - e.g. array('okay' => true, 'applies' => true), where applies is whether
* the test is relevant for the database
*/
public function requireDatabaseAlterPermissions($databaseConfig);
}

View File

@ -134,4 +134,45 @@ class MySQLDatabaseConfigurationHelper implements DatabaseConfigurationHelper {
);
}
/**
* Ensure we have permissions to alter tables.
*
* @param array $databaseConfig Associative array of db configuration, e.g. "server", "username" etc
* @return array Result - e.g. array('okay' => true, 'applies' => true), where applies is whether
* the test is relevant for the database
*/
public function requireDatabaseAlterPermissions($databaseConfig) {
$success = false;
$conn = new MySQLi($databaseConfig['server'], $databaseConfig['username'], $databaseConfig['password']);
if($conn) {
if ($res = $conn->query('SHOW GRANTS')) {
// Annoyingly, MySQL 'escapes' the database, so we need to do it too.
$db = str_replace(array('%', '_', '`'), array('\%', '\_', '``'), $databaseConfig['database']);
while ($row = $res->fetch_array()) {
if (preg_match('/^GRANT (.+) ON (.+) TO/', $row[0], $matches) && (count($matches) == 2)) {
// Need to change to an array of permissions, because ALTER is contained in ALTER ROUTINES.
$permission = array_map('trim', explode(',', $matches[1]));
$on_database = $matches[2];
// The use of both ` and " is because of ANSI mode.
if (in_array('ALL PRIVILEGES', $permission) and (
($on_database == '*.*') or ($on_database == '`' . $db . '`.*')
or ($on_database == '"' . $db . '".*'))) {
$success = true;
break;
}
if (in_array('ALTER', $permission) and (
($on_database == '*.*') or ($on_database == '`' . $db . '`.*')
or ($on_database == '"' . $db . '".*'))) {
$success = true;
break;
}
}
}
}
}
return array(
'success' => $success,
'applies' => true
);
}
}

View File

@ -311,14 +311,23 @@ class InstallRequirements {
'Version ' . $this->getDatabaseConfigurationHelper($databaseConfig['type'])->getDatabaseVersion($databaseConfig)
)
)) {
$this->requireDatabaseOrCreatePermissions(
if($this->requireDatabaseOrCreatePermissions(
$databaseConfig,
array(
"Database Configuration",
"Can I access/create the database",
"I can't create new databases and the database '$databaseConfig[database]' doesn't exist"
)
);
)) {
$this->requireDatabaseAlterPermissions(
$databaseConfig,
array(
"Database Configuration",
"Can I ALTER tables",
"I don't have permission to ALTER tables"
)
);
}
}
}
}
@ -913,6 +922,20 @@ class InstallRequirements {
}
}
function requireDatabaseAlterPermissions($databaseConfig, $testDetails) {
$this->testing($testDetails);
$helper = $this->getDatabaseConfigurationHelper($databaseConfig['type']);
$result = $helper->requireDatabaseAlterPermissions($databaseConfig);
if ($result['success']) {
return true;
} else {
$testDetails[2] = "Silverstripe cannot alter tables. This won't prevent installation, however it may "
. "cause issues if you try to run a /dev/build once installed.";
$this->warning($testDetails);
return;
}
}
function requireServerVariables($varNames, $errorMessage) {
//$this->testing($testDetails);
foreach($varNames as $varName) {