/** * Create or upgrade the database needed for pearweb * * This helper function scans for previous database versions, * and upgrades the database based on differences between the * previous version's schema and the one distributed with this * version. * * If the database has never been created, then it is created. * * @param array $answers * @return boolean */ function initializeDatabase($answers) { $this->dsn = array('phptype' => $answers['driver'], 'username' => $answers['user'], 'password' => $answers['password'], 'hostspec' => $answers['host'], 'database' => $answers['database']); $a = MDB2_Schema::factory($this->dsn, array('idxname_format' => '%s', 'seqname_format' => 'id', 'quote_identifier' => true)); // for upgrade purposes if (!file_exists('@www-dir@' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR . '.pearweb-upgrade')) { if (!mkdir('@www-dir@' . DIRECTORY_SEPARATOR . 'sql' . DIRECTORY_SEPARATOR . '.pearweb-upgrade')) { $this->_ui->outputData('error - make sure we can create directories'); return false; } } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $c = $a->parseDatabaseDefinitionFile(realpath('@www-dir@/sql/pearweb_mdb2schema.xml')); PEAR::staticPopErrorHandling(); if (PEAR::isError($c)) { $extra = ''; if (MDB2_Schema::isError($c) || MDB2::isError($c)) { $extra = "\n" . $c->getUserInfo(); } $this->_ui->outputData('ERROR: ' . $c->getMessage() . $extra); return false; } $c['name'] = $answers['database']; $c['create'] = 1; $c['overwrite'] = 0; $dir = opendir('@www-dir@/sql/.pearweb-upgrade'); $oldversion = false; while (false !== ($entry = readdir($dir))) { if ($entry[0] === '.') { continue; } if (strpos($entry, $answers['database']) === 0) { // this is one of ours // strip databasename- $entry = substr($entry, strlen($answers['database']) + 1); // strip ".ser" $entry = substr($entry, 0, strlen($entry) - 4); // ... and we're left with just the version if (!$oldversion) { $oldversion = $entry; continue; } if (version_compare($entry, $oldversion, '>')) { $oldversion = $entry; } } } if (!file_exists('@www-dir@/sql/.pearweb-upgrade/' . $answers['database'] . '-@version@.ser')) { $fp = fopen('@www-dir@/sql/.pearweb-upgrade/' . $answers['database'] . '-@version@.ser', 'w'); fwrite($fp, serialize($c)); fclose($fp); } if ($oldversion == '@version@') { // this is where to change if we need to add a "force upgrade of // structure" option // we would uncomment the following line: //$c['overwrite'] = true; $oldversion = false; } if ($oldversion) { $curdef = unserialize(file_get_contents('@www-dir@/sql/.pearweb-upgrade/' . $answers['database'] . '-' . $oldversion . '.ser')); if (!is_array($curdef)) { $this->_ui->outputData('invalid data returned from previous version'); } // get a database diff (MDB2_Schema is very useful here) PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $c = $a->compareDefinitions($c, $curdef); if (PEAR::isError($c)) { $this->_ui->outputData($err->getMessage()); $this->_ui->outputData($err->getUserInfo()); $this->_ui->outputData('Unable to automatically update database'); return false; } $err = $a->updateDatabase($curdef, $c); PEAR::staticPopErrorHandling(); } else { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $err = $a->createDatabase($c); PEAR::staticPopErrorHandling(); } if (PEAR::isError($err)) { $this->_ui->outputData($err->getUserInfo()); $this->_ui->outputData($err->getMessage()); return false; } return true; }