* @param string $indexName
*/
public abstract function dropIndex($tableName, $indexName);
+
+ /**
+ * Drops an existing foreign key.
+ *
+ * @param string $tableName
+ * @param string $indexName
+ */
+ public abstract function dropForeignKey($tableName, $indexName);
}
$statement->execute();
}
+ /**
+ * @see DatabaseEditor::dropForeignKey()
+ */
+ public function dropForeignKey($tableName, $indexName) {
+ $sql = "ALTER TABLE ".$tableName." DROP FOREIGN KEY ".$indexName;
+ $statement = $this->dbObj->prepareStatement($sql);
+ $statement->execute();
+ }
+
/**
* Builds a column definition for execution in a create table or alter table statement.
*
$statement->execute();
}
+ /**
+ * @see DatabaseEditor::dropForeignKey()
+ */
+ public function dropForeignKey($tableName, $indexName) {
+ // TODO: implement this function
+ }
+
/**
* Builds a column definition for execution in a create table or alter table statement.
*
case 'ALTER TABLE':
// add index
if (preg_match('~^ALTER\s+TABLE\s+(\w+)\s+ADD\s+(?:(UNIQUE|FULLTEXT)\s+)?(?:INDEX|KEY)\s+(?:(\w+)\s*)?\((\s*\w+\s*(?:,\s*\w+\s*)*)\)~is', $query, $match)) {
- $this->executeAddIndexStatement($match[1], $match[3], array('type' => strtoupper($match[2]), 'columns' => $match[4]));
+ $this->executeAddIndexStatement($match[1], ($match[3] ? $match[3] : self::getGenericIndexName($match[1], $match[4])), array('type' => strtoupper($match[2]), 'columns' => $match[4]));
}
// add foreign key
else if (preg_match('~^ALTER\s+TABLE\s+(\w+)\s+ADD\s+FOREIGN KEY\s+(?:(\w+)\s*)?\((\s*\w+\s*(?:,\s*\w+\s*)*)\)\s+REFERENCES\s+(\w+)\s+\((\s*\w+\s*(?:,\s*\w+\s*)*)\)(?:\s+ON\s+(UPDATE|DELETE)\s+(CASCADE|SET NULL|NO ACTION))?~is', $query, $match)) {
- $this->executeAddForeignKeyStatement($match[1], $match[2], array('columns' => $match[3], 'referencedTable' => $match[4], 'referencedColumns' => $match[5], 'operation' => $match[6], 'action' => $match[7]));
+ $this->executeAddForeignKeyStatement($match[1], ($match[2] ? $match[2] : self::getGenericIndexName($match[1], $match[3], 'fk')), array('columns' => $match[3], 'referencedTable' => $match[4], 'referencedColumns' => $match[5], 'operation' => $match[6], 'action' => $match[7]));
}
// add/change column
else if (preg_match("~^ALTER\s+TABLE\s+(\w+)\s+(?:(ADD)\s+(?:COLUMN\s+)?|(CHANGE)\s+(?:COLUMN\s+)?(\w+)\s+)(\w+)\s+(\w+)(?:\s*\((\s*(?:\d+(?:\s*,\s*\d+)?|'[^']*'(?:\s*,\s*'[^']*')*))\))?(?:\s+UNSIGNED)?(?:\s+(NOT NULL|NULL))?(?:\s+DEFAULT\s+(\d+.\d+|\d+|NULL|'[^'\\\\]*(?:\\\\.[^'\\\\]*)*'))?(?:\s+(AUTO_INCREMENT))?(?:\s+(UNIQUE|PRIMARY)(?: KEY)?)?~is", $query, $match)) {
case 'CREATE INDEX':
if (preg_match('~^CREATE\s+(?:(UNIQUE|FULLTEXT)\s+)?INDEX\s+(\w+)\s+ON\s+(\w+)\s+\((\s*\w+\s*(?:,\s*\w+\s*)*)\)~is', $query, $match)) {
- $this->executeAddIndexStatement($match[3], $match[2], array('type' => strtoupper($match[1]), 'columns' => $match[4]));
+ $this->executeAddIndexStatement($match[3], ($match[2] ? $match[2] : self::getGenericIndexName($match[3], $match[4])), array('type' => strtoupper($match[1]), 'columns' => $match[4]));
}
else {
throw new SystemException("Unsupported SQL statement '".$query."'");
$statement = WCF::getDB()->prepareStatement($query);
$statement->execute();
}
+
+ /**
+ * Creates a generic index name.
+ *
+ * @param string $tableName
+ * @param string $columns
+ * @param string $suffix
+ * @return string index name
+ */
+ protected static function getGenericIndexName($tableName, $columns, $suffix = '') {
+ // get first column
+ $columns = ArrayUtil::trim(explode(',', $columns));
+
+ return $tableName . '_' . reset($columns) . ($suffix ? '_' . $suffix : '');
+ }
}
// fetch all pips associated with current PACKAGE_ID and include pips
// previously installed by current installation queue
- $sql = "SELECT pip.className, package.packageDir
- FROM wcf".WCF_N."_package_installation_plugin pip
- LEFT JOIN wcf".WCF_N."_package_dependency package_dependency
- ON (package_dependency.packageID = pip.packageID)
- LEFT JOIN wcf".WCF_N."_package package
- ON (package.packageID = pip.packageID)
- WHERE pip.pluginName = ?
- AND (
- package_dependency.dependency = ?
- OR pip.packageID = ?
- OR pip.packageID IS NULL
- )";
+ $sql = "SELECT className
+ FROM wcf".WCF_N."_package_installation_plugin
+ WHERE pluginName = ?";
$statement = WCF::getDB()->prepareStatement($sql);
$statement->execute(array(
- $nodeData['pip'],
- PACKAGE_ID,
- $this->queue->packageID
+ $nodeData['pip']
));
$row = $statement->fetchArray();
- // PIP is unknown, ignore
+ // PIP is unknown
if (!$row) {
- return $installationStep;
+ throw new SystemException("unable to find package installation plugin '".$nodeData['pip']."'");
}
// valdidate class definition
$sql = "SELECT pluginName, className,
CASE pluginName WHEN 'packageinstallationplugins' THEN 1 WHEN 'files' THEN 2 ELSE 0 END 'pluginOrder'
FROM wcf".WCF_N."_package_installation_plugin
- WHERE packageID IN (
- 1 /* TESTING ONLY */
- /*
- SELECT dependency
- FROM wcf".WCF_N."_package_dependency
- WHERE packageID = ".$this->installation->queue->packageID."
- */
- )
- ORDER BY pluginOrder ASC, priority DESC";
+ ORDER BY pluginOrder, priority";
$statement = WCF::getDB()->prepareStatement($sql);
$statement->execute();
while ($row = $statement->fetchArray()) {
*/
public function uninstall() {
// get logged sql tables/columns
- $sql = "SELECT *
- FROM wcf".WCF_N."_package_installation_sql_log
- WHERE packageID = ?";
+ $sql = "SELECT *
+ FROM wcf".WCF_N."_package_installation_sql_log
+ WHERE packageID = ?
+ ORDER BY sqlIndex DESC, sqlColumn DESC";
$statement = WCF::getDB()->prepareStatement($sql);
$statement->execute(array($this->installation->getPackageID()));
$entries = array();
// delete or alter tables
foreach ($entries as $entry) {
// don't alter table if it should be dropped
- if (!empty($entry['sqlColumn']) || !empty($entry['sqlIndex'])) {
+ if (!empty($entry['sqlColumn'])/* || !empty($entry['sqlIndex'])*/) {
$isDropped = false;
foreach ($entries as $entry2) {
if ($entry['sqlTable'] == $entry2['sqlTable'] && empty($entry2['sqlColumn']) && empty($entry2['sqlIndex'])) {
}
// drop index
else if (in_array($entry['sqlTable'], $existingTableNames) && !empty($entry['sqlIndex'])) {
- WCF::getDB()->getEditor()->dropIndex($entry['sqlTable'], $entry['sqlIndex']);
+ if (substr($entry['sqlIndex'], -3) == '_fk') {
+ WCF::getDB()->getEditor()->dropForeignKey($entry['sqlTable'], $entry['sqlIndex']);
+ }
+ else {
+ WCF::getDB()->getEditor()->dropIndex($entry['sqlTable'], $entry['sqlIndex']);
+ }
}
}
// delete from log table