sql pip renamed
authorMarcel Werk <burntime@woltlab.com>
Tue, 19 Jul 2011 16:42:59 +0000 (18:42 +0200)
committerMarcel Werk <burntime@woltlab.com>
Tue, 19 Jul 2011 16:42:59 +0000 (18:42 +0200)
com.woltlab.wcf/pip.xml
wcfsetup/install/files/lib/system/package/plugin/SQLPackageInstallationPlugin.class.php [new file with mode: 0644]

index c67580cc8e044c00fb949ec67109a82ef48872a9..9e55af909837ec43f87aa722f60141b61e1ec750 100644 (file)
@@ -12,7 +12,7 @@
                <pip name="options">wcf\system\package\plugin\OptionsPackageInstallationPlugin</pip>
                <pip name="pagemenu">wcf\system\package\plugin\PageMenuPackageInstallationPlugin</pip>
                <pip name="script">wcf\system\package\plugin\ScriptPackageInstallationPlugin</pip>
-               <pip name="sql">wcf\system\package\plugin\SqlPackageInstallationPlugin</pip>
+               <pip name="sql">wcf\system\package\plugin\SQLPackageInstallationPlugin</pip>
                <pip name="templatelistener">wcf\system\package\plugin\TemplateListenerPackageInstallationPlugin</pip>
                <pip name="templates">wcf\system\package\plugin\TemplatesPackageInstallationPlugin</pip>
                <pip name="useroptions">wcf\system\package\plugin\UserOptionsPackageInstallationPlugin</pip>
diff --git a/wcfsetup/install/files/lib/system/package/plugin/SQLPackageInstallationPlugin.class.php b/wcfsetup/install/files/lib/system/package/plugin/SQLPackageInstallationPlugin.class.php
new file mode 100644 (file)
index 0000000..9d29b86
--- /dev/null
@@ -0,0 +1,143 @@
+<?php
+namespace wcf\system\package\plugin;
+use wcf\system\package\PackageInstallationSQLParser;
+use wcf\system\exception\SystemException;
+use wcf\system\WCF;
+use wcf\util\StringUtil;
+
+/**
+ * This PIP executes the delivered sql file.
+ *
+ * @author     Benjamin Kunz
+ * @copyright  2001-2011 WoltLab GmbH
+ * @license    GNU Lesser General Public License <http://opensource.org/licenses/lgpl-license.php>
+ * @package    com.woltlab.wcf
+ * @subpackage system.package.plugin
+ * @category   Community Framework
+ */
+class SQLPackageInstallationPlugin extends AbstractPackageInstallationPlugin {
+       /**
+        * @see wcf\system\package\plugin\AbstractPackageInstallationPlugin::$tableName
+        */     
+       public $tableName = 'package_installation_sql_log';
+       
+       /**
+        * @see wcf\system\package\plugin\PackageInstallationPlugin::install()
+        */
+       public function install() {
+               parent::install();
+
+               // extract sql file from archive
+               if ($queries = $this->getSQL($this->instruction['value'])) {
+                       $package = $this->installation->getPackage();
+                       if ($package->parentPackageID) {
+                               // package is a plugin; get parent package
+                               $package = $package->getParentPackage();
+                       }
+                       
+                       if ($package->standalone == 1) {
+                               // package is standalone
+                               $packageAbbr = $package->getAbbreviation();
+                               $tablePrefix = WCF_N.'_'.$package->instanceNo.'_';
+                               
+                               // Replace the variable xyz1_1 with $tablePrefix in the table names.
+                               $queries = StringUtil::replace($packageAbbr.'1_1_', $packageAbbr.$tablePrefix, $queries);
+                       }
+                       
+                       // replace wcf1_  with the actual WCF_N value
+                       $queries = str_replace("wcf1_", "wcf".WCF_N."_", $queries);
+                       
+                       // check queries
+                       $parser = new PackageInstallationSQLParser($queries, $package, $this->installation->getAction());
+                       $conflicts = $parser->test();
+                       if (count($conflicts)) {
+                               // ask user here
+                               // search default value in session
+                               if (!WCF::getSession()->getVar('overrideAndDontAskAgain')) {
+                                       // show page
+                                       if (!empty($_POST['override']) || !empty($_POST['overrideAndDontAskAgain'])) {
+                                               if (!empty($_POST['overrideAndDontAskAgain'])) {
+                                                       WCF::getSession()->register('overrideAndDontAskAgain', true);
+                                                       WCF::getSession()->update();
+                                               }
+                                       }
+                                       else {
+                                               WCF::getTPL()->assign('conflicts', $conflicts);
+                                               WCF::getTPL()->display('packageInstallationCheckOverrideTables');
+                                               exit;
+                                       }
+                               }
+                       }
+                       
+                       // execute queries
+                       $parser->execute();
+                       
+                       // log changes
+                       $parser->log();
+               }
+       }
+       
+       /**
+        * Deletes the sql tables or columns which where installed by the package.
+        */
+       public function uninstall() {
+               // get logged sql tables/columns
+               $sql = "SELECT  *
+                       FROM    wcf".WCF_N."_package_installation_sql_log
+                       WHERE   packageID = ?";
+               $statement = WCF::getDB()->prepareStatement($sql);
+               $statement->execute(array($this->installation->getPackageID()));
+               $entries = array();
+               while ($row = $statement->fetchArray()) {
+                       $entries[] = $row;
+               }
+               
+               // get all tablenames from database
+               $existingTableNames = WCF::getDB()->getEditor()->getTablenames();
+               
+               // delete or alter tables
+               foreach ($entries as $entry) {
+                       // don't alter table if it should be dropped
+                       if (!empty($entry['sqlColumn']) || !empty($entry['sqlIndex'])) {
+                               $isDropped = false;
+                               foreach ($entries as $entry2) {
+                                       if ($entry['sqlTable'] == $entry2['sqlTable'] && empty($entry2['sqlColumn']) && empty($entry2['sqlIndex'])) {
+                                               $isDropped = true;
+                                       }
+                               }
+                               if ($isDropped) continue;
+                       }
+                       // drop table
+                       if (!empty($entry['sqlTable']) && empty($entry['sqlColumn']) && empty($entry['sqlIndex'])) {
+                               WCF::getDB()->getEditor()->dropTable($entry['sqlTable']);
+                       }
+                       // drop column
+                       else if (in_array($entry['sqlTable'], $existingTableNames) && !empty($entry['sqlColumn'])) {
+                               WCF::getDB()->getEditor()->dropColumn($entry['sqlTable'], $entry['sqlColumn']);
+                       }
+                       // drop index
+                       else if (in_array($entry['sqlTable'], $existingTableNames) && !empty($entry['sqlIndex'])) {
+                               WCF::getDB()->getEditor()->dropIndex($entry['sqlTable'], $entry['sqlIndex']);
+                       }
+               }
+               // delete from log table
+               parent::uninstall();
+       }
+       
+       /**
+        * Extracts and returns the sql file.
+        * If the specified sql file was not found, an error message is thrown.
+        *
+        * @param       string          $filename
+        * @return      string
+        */
+       protected function getSQL($filename) {
+               // search sql files in package archive
+               if (($fileindex = $this->installation->getArchive()->getTar()->getIndexByFilename($filename)) === false) {
+                       throw new SystemException("SQL file '".$filename."' not found.", 13016);
+               }
+
+               // extract sql file to string
+               return $this->installation->getArchive()->getTar()->extractToString($fileindex);
+       }
+}