2 namespace wcf\system\package\plugin
;
3 use wcf\data\package\Package
;
4 use wcf\data\package\PackageList
;
5 use wcf\system\exception\SystemException
;
6 use wcf\system\package\PackageInstallationSQLParser
;
10 * Executes the delivered sql file.
12 * @author Alexander Ebert
13 * @copyright 2001-2014 WoltLab GmbH
14 * @license GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
15 * @package com.woltlab.wcf
16 * @subpackage system.package.plugin
17 * @category Community Framework
19 class SQLPackageInstallationPlugin
extends AbstractPackageInstallationPlugin
{
21 * @see \wcf\system\package\plugin\AbstractPackageInstallationPlugin::$tableName
23 public $tableName = 'package_installation_sql_log';
26 * @see \wcf\system\package\plugin\IPackageInstallationPlugin::install()
28 public function install() {
31 // extract sql file from archive
32 if ($queries = $this->getSQL($this->instruction
['value'])) {
33 $package = $this->installation
->getPackage();
35 // replace app1_ with app{WCF_N}_ in the table names for
37 $packageList = new PackageList();
38 $packageList->getConditionBuilder()->add('package.isApplication = ?', array(1));
39 $packageList->readObjects();
40 foreach ($packageList as $package) {
41 $abbreviation = Package
::getAbbreviation($package->package
);
43 $queries = str_replace($abbreviation.'1_', $abbreviation.WCF_N
.'_', $queries);
47 $parser = new PackageInstallationSQLParser($queries, $this->installation
->getPackage(), $this->installation
->getAction());
48 $conflicts = $parser->test();
49 if (!empty($conflicts) && (isset($conflicts['CREATE TABLE']) ||
isset($conflicts['DROP TABLE']))) {
50 $unknownCreateTable = isset($conflicts['CREATE TABLE']) ?
$conflicts['CREATE TABLE'] : array();
51 $unknownDropTable = isset($conflicts['DROP TABLE']) ?
$conflicts['DROP TABLE'] : array();
53 $errorMessage = "Can't";
54 if (!empty($unknownDropTable)) {
55 $errorMessage .= " drop unknown table";
56 if (count($unknownDropTable) > 1) {
59 $errorMessage .= " '".implode("', '", $unknownDropTable)."'";
61 if (!empty($unknownCreateTable)) {
62 if (!empty($unknownDropTable)) {
63 $errorMessage .= " and can't";
66 $errorMessage .= " overwrite unknown table";
67 if (count($unknownCreateTable) > 1) {
70 $errorMessage .= " '".implode("', '", $unknownCreateTable)."'";
73 throw new SystemException($errorMessage);
85 * @see \wcf\system\package\plugin\IPackageInstallationPlugin::uninstall()
87 public function uninstall() {
88 // get logged sql tables/columns
90 FROM wcf".WCF_N
."_package_installation_sql_log
92 ORDER BY sqlIndex DESC, sqlColumn DESC";
93 $statement = WCF
::getDB()->prepareStatement($sql);
94 $statement->execute(array($this->installation
->getPackageID()));
96 while ($row = $statement->fetchArray()) {
100 // get all tablenames from database
101 $existingTableNames = WCF
::getDB()->getEditor()->getTablenames();
103 // delete or alter tables
104 foreach ($entries as $entry) {
105 // don't alter table if it should be dropped
106 if (!empty($entry['sqlColumn'])/* || !empty($entry['sqlIndex'])*/) {
108 foreach ($entries as $entry2) {
109 if ($entry['sqlTable'] == $entry2['sqlTable'] && empty($entry2['sqlColumn']) && empty($entry2['sqlIndex'])) {
113 if ($isDropped) continue;
116 if (!empty($entry['sqlTable']) && empty($entry['sqlColumn']) && empty($entry['sqlIndex'])) {
117 WCF
::getDB()->getEditor()->dropTable($entry['sqlTable']);
120 else if (in_array($entry['sqlTable'], $existingTableNames) && !empty($entry['sqlColumn'])) {
121 WCF
::getDB()->getEditor()->dropColumn($entry['sqlTable'], $entry['sqlColumn']);
124 else if (in_array($entry['sqlTable'], $existingTableNames) && !empty($entry['sqlIndex'])) {
125 if (substr($entry['sqlIndex'], -3) == '_fk') {
126 WCF
::getDB()->getEditor()->dropForeignKey($entry['sqlTable'], $entry['sqlIndex']);
129 WCF
::getDB()->getEditor()->dropIndex($entry['sqlTable'], $entry['sqlIndex']);
133 // delete from log table
138 * Extracts and returns the sql file.
139 * If the specified sql file was not found, an error message is thrown.
141 * @param string $filename
144 protected function getSQL($filename) {
145 // search sql files in package archive
146 if (($fileindex = $this->installation
->getArchive()->getTar()->getIndexByFilename($filename)) === false) {
147 throw new SystemException("SQL file '".$filename."' not found.");
150 // extract sql file to string
151 return $this->installation
->getArchive()->getTar()->extractToString($fileindex);