CVS update: /cowiki/htdocs/setup/class/task/migrator/
[email protected] 12 May 2005 17:10:30 -0000
| Newsgroups | gmane.comp.php.cowiki.cvs |
|---|---|
| Message-ID | <[email protected]> |
User: dgorski Date: 2005/05/12 10:10:30 Modified: cowiki/htdocs/setup/class/task/migrator/class.Migrator_0.php Log: Rewrite File Changes: Directory: /cowiki/htdocs/setup/class/task/migrator/ ==================================================== File [changed]: class.Migrator_0.php Url: http://cowiki.tigris.org/source/browse/cowiki/htdocs/setup/class/task/migrator/class.Migrator_0.php?r1=1.5&r2=1.6 Delta lines: +154 -48 ---------------------- --- class.Migrator_0.php 8 May 2005 00:57:51 -0000 1.5 +++ class.Migrator_0.php 12 May 2005 17:10:28 -0000 1.6 @@ -2,7 +2,7 @@ /** * - * $Id: class.Migrator_0.php,v 1.5 2005/05/08 00:57:51 dgorski Exp $ + * $Id: class.Migrator_0.php,v 1.6 2005/05/12 17:10:28 dgorski Exp $ * * This file is part of coWiki. coWiki is free software under the terms of * the GNU General Public License (GPL). Read the LICENSE file. If you did @@ -17,7 +17,7 @@ * @author Daniel T. Gorski, <[email protected]> * @copyright (C) Daniel T. Gorski, {@link http://www.develnet.org} * @license http://www.gnu.org/licenses/gpl.html - * @version $Revision: 1.5 $ + * @version $Revision: 1.6 $ * */ @@ -47,12 +47,13 @@ public function getDescription() { $aArr = array(); - if ($this->State->mustCreateNewConnectorUser()) { - $aArr[] = 'Initial creation of a connector user.'; + if ($this->State->shallCreateNewConnectorUser()) { + $aArr[] = 'Creation (or update) of the database connector user.'; } - if ($this->State->mustCreateNewDocumentDatabase()) { - $aArr[] = 'Initial creation of the document database schema.'; + if ($this->State->shallCreateNewDocumentDatabase()) { + $aArr[] = 'Initial creation of the document + database schema (if necessary).'; } return $aArr; @@ -69,18 +70,16 @@ public function perform() { // Connect with root credentials and dispatch - if ($this->State->mustCreateNewConnectorUser() - || $this->State->mustCreateNewDocumentDatabase()) { + if ($this->State->shallCreateNewConnectorUser() + || $this->State->shallCreateNewDocumentDatabase()) { // Connect with root user $sResource = $this->State->getDocumentStorageRootDSN(); + $UriInfo = new UriInfo($sResource); - $Storage = StorageFactory::getInstance() - ->createDocumentStorage($sResource); + $Storage = StorageFactory::getInstance()->create($UriInfo); // Dispatch due to the different access schemes - $UriInfo = new UriInfo($sResource); - switch ($UriInfo->get('scheme')) { case 'mysql': case 'mysql+innodb': @@ -103,7 +102,8 @@ private function createMySqlScheme($Storage) { - // Connector user data (not root user!) + // Get connector user data (not root user!) BUT we are connected + // as root user! $sResource = $this->State->getDocumentStorageDSN(); $UriInfo = new UriInfo($sResource); @@ -113,45 +113,114 @@ $sDB = $UriInfo->get('basepath'); // If necessary, create a connector user - if ($this->State->mustCreateNewConnectorUser()) { + if ($this->State->shallCreateNewConnectorUser()) { - // Insert new user - $sQuery = " INSERT INTO mysql.user - SET host = '".$sHost."', - user = '".$sUser."', - password = PASSWORD('".$sPass."')"; + // Let the database create an encrypted password + $aData = $Storage->fetchArrayAndFreeResult( + $Storage->query( + "SELECT PASSWORD('".$sPass."') AS new_pass" + ) + ); - $Storage->query($sQuery); + // Fields for 'mysql.user' + $aFields = array( + 'host' => $sHost, + 'user' => $sUser, + 'password' => $aData['new_pass'] + ); // --- - // Define database and set privileges - $sQuery = " INSERT INTO mysql.db - SET host = '".$sHost."', - db = '".$sDB."', - user = '".$sUser."', - select_priv = 'Y', - insert_priv = 'Y', - update_priv = 'Y', - delete_priv = 'Y', - create_priv = 'Y', - drop_priv = 'Y', - references_priv = 'Y', - index_priv = 'Y', - alter_priv = 'Y', - create_tmp_table_priv = 'Y', - lock_tables_priv = 'Y'"; + $Storage->begin(); - $Storage->query($sQuery); + try { + + // Check if connector user is already in 'mysql.user' + $sQuery = "SELECT COUNT(password) AS rec_count + FROM mysql.user + WHERE user = '".$sUser."'"; + + $aData = $Storage->fetchArrayAndFreeResult( + $Storage->query($sQuery) + ); + + // No such user yet, insert him/her + if ((int)$aData['rec_count'] == 0) { + + // Set further data for insert + $aInsert = array( + 'table' => 'mysql.user', + 'fields' => $aFields + ); + $Storage->insert($aInsert); + + } else { + + // User already there, set further data for update + $aUpdate = array( + 'table' => 'mysql.user', + 'fields' => $aFields, + 'where' => "user = '".$sUser."'" + ); + $Storage->update($aUpdate); + } + + // --- + + // Insert user <-> database permissions + $aRemove = array( + 'table' => 'mysql.db', + 'where' => "db = '".$sDB."'" + ); + $Storage->remove($aRemove); + + // Fields for 'mysql.db' + $aFields = array( + 'host' => $sHost, + 'user' => $sUser, + 'db' => $sDB, + 'select_priv' => 'Y', + 'insert_priv' => 'Y', + 'update_priv' => 'Y', + 'delete_priv' => 'Y', + 'create_priv' => 'Y', + 'drop_priv' => 'Y', + 'references_priv' => 'Y', + 'index_priv' => 'Y', + 'alter_priv' => 'Y', + 'create_tmp_table_priv' => 'Y', + 'lock_tables_priv' => 'Y' + ); + + $aInsert = array( + 'table' => 'mysql.db', + 'fields' => $aFields, + 'where' => "db = '".$sDB."'" + ); + $Storage->insert($aInsert); + + } catch (StorageException $se) { + + // End transaction + $Storage->rollback(); + throw $se; + } + + // End transaction + $Storage->commit(); + + // ------------------------------------------------------------ // Done - $this->State->setMustCreateNewConnectorUser(false); + $this->State->setShallCreateNewConnectorUser(false); + + // Reload the database, initialize settings $Storage->reload(); } // ---------------------------------------------------------------- - if ($this->State->mustCreateNewDocumentDatabase()) { + if ($this->State->shallCreateNewDocumentDatabase()) { $sPath = $this->State->getMiscPath(); $sFile = '/database/mysql.sql'; @@ -181,6 +250,39 @@ // --- + // Begin transaction + $Storage->begin(); + + // Check if database already exists + $aDB = $Storage->fetchRowAndFreeResult( + $Storage->query('SHOW DATABASES LIKE "'.$sDB.'"') + ); + + // A database with this name was found. Check if it seems to + // contain valid tables. Avoid accidents. + if (isset($aDB[0])) { + $Storage->useDatabase($sDB); + + // Check if database contains tables that are prefixed + // with "cowiki_" + $aTable = $Storage->fetchRowAndFreeResult( + $Storage->query('SHOW TABLES LIKE "cowiki_%"') + ); + + if (!is_array($aTable)) { + $Storage->rollback(); + + throw new MigratorException( + 'The selected database \''.$sDB.'\' is already there + and does not seem to be a valid '.COWIKI_NAME.' + database. Heck, what are you doing? Be careful, + you are logged on as database administrator!' + ); + } + } + + // No database with this name found, create it + if (!isset($aDB[0])) { $Storage->query('CREATE DATABASE '.$sDB); $Storage->useDatabase($sDB); @@ -188,9 +290,13 @@ foreach ($aContent as $sQuery) { $Storage->query($sQuery); } + } + + // End transaction + $Storage->commit(); // Done - $this->State->setMustCreateNewDocumentDatabase(false); + $this->State->setShallCreateNewDocumentDatabase(false); } }