Update installer to use new Schema code to create the core tables instead of db/statusnet.sql or db/statusnet_pg.sql

This commit is contained in:
Brion Vibber 2010-10-15 12:20:10 -07:00
parent 4c3aebd396
commit a335dcbcbb

View File

@ -53,12 +53,12 @@ abstract class Installer
'mysql' => array( 'mysql' => array(
'name' => 'MySQL', 'name' => 'MySQL',
'check_module' => 'mysqli', 'check_module' => 'mysqli',
'installer' => 'mysql_db_installer', 'scheme' => 'mysqli', // DSN prefix for PEAR::DB
), ),
'pgsql' => array( 'pgsql' => array(
'name' => 'PostgreSQL', 'name' => 'PostgreSQL',
'check_module' => 'pgsql', 'check_module' => 'pgsql',
'installer' => 'pgsql_db_installer', 'scheme' => 'pgsql', // DSN prefix for PEAR::DB
), ),
); );
@ -254,6 +254,7 @@ abstract class Installer
* Set up the database with the appropriate function for the selected type... * Set up the database with the appropriate function for the selected type...
* Saves database info into $this->db. * Saves database info into $this->db.
* *
* @fixme escape things in the connection string in case we have a funny pass etc
* @return mixed array of database connection params on success, false on failure * @return mixed array of database connection params on success, false on failure
*/ */
function setupDatabase() function setupDatabase()
@ -261,119 +262,41 @@ abstract class Installer
if ($this->db) { if ($this->db) {
throw new Exception("Bad order of operations: DB already set up."); throw new Exception("Bad order of operations: DB already set up.");
} }
$method = self::$dbModules[$this->dbtype]['installer'];
$db = call_user_func(array($this, $method),
$this->host,
$this->database,
$this->username,
$this->password);
$this->db = $db;
return $this->db;
}
/**
* Set up a database on PostgreSQL.
* Will output status updates during the operation.
*
* @param string $host
* @param string $database
* @param string $username
* @param string $password
* @return mixed array of database connection params on success, false on failure
*
* @fixme escape things in the connection string in case we have a funny pass etc
*/
function Pgsql_Db_installer($host, $database, $username, $password)
{
$connstring = "dbname=$database host=$host user=$username";
//No password would mean trust authentication used.
if (!empty($password)) {
$connstring .= " password=$password";
}
$this->updateStatus("Starting installation..."); $this->updateStatus("Starting installation...");
if (empty($password)) {
$auth = '';
} else {
$auth = ":$this->password";
}
$scheme = self::$dbModules[$this->dbtype]['scheme'];
$this->updateStatus("Checking database..."); $this->updateStatus("Checking database...");
$conn = pg_connect($connstring); $conn = $this->connectDatabase($dsn);
if (DB::isError($conn)) {
if ($conn ===false) { $this->updateStatus("Database connection error: " . $conn->getMessage(), true);
$this->updateStatus("Failed to connect to database: $connstring");
return false; return false;
} }
//ensure database encoding is UTF8 // ensure database encoding is UTF8
$record = pg_fetch_object(pg_query($conn, 'SHOW server_encoding')); if ($this->dbtype == 'mysql') {
if ($record->server_encoding != 'UTF8') { // @fixme utf8m4 support for mysql 5.5?
$this->updateStatus("StatusNet requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding)); // Force the comms charset to utf8 for sanity
return false; $conn->execute('SET names utf8');
} } else if ($this->dbtype == 'pgsql') {
$record = $conn->getRow('SHOW server_encoding');
$this->updateStatus("Running database script..."); if ($record->server_encoding != 'UTF8') {
//wrap in transaction; $this->updateStatus("StatusNet requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding));
pg_query($conn, 'BEGIN');
$res = $this->runDbScript('statusnet_pg.sql', $conn, 'pgsql');
if ($res === false) {
$this->updateStatus("Can't run database script.", true);
return false;
}
foreach (array('sms_carrier' => 'SMS carrier',
'notice_source' => 'notice source',
'foreign_services' => 'foreign service')
as $scr => $name) {
$this->updateStatus(sprintf("Adding %s data to database...", $name));
$res = $this->runDbScript($scr.'.sql', $conn, 'pgsql');
if ($res === false) {
$this->updateStatus(sprintf("Can't run %s script.", $name), true);
return false; return false;
} }
} }
pg_query($conn, 'COMMIT');
if (empty($password)) { $res = $this->updateStatus("Creating database tables...");
$sqlUrl = "pgsql://$username@$host/$database"; if (!$this->createCoreTables($conn)) {
} else { $this->updateStatus("Error creating tables.", true);
$sqlUrl = "pgsql://$username:$password@$host/$database";
}
$db = array('type' => 'pgsql', 'database' => $sqlUrl);
return $db;
}
/**
* Set up a database on MySQL.
* Will output status updates during the operation.
*
* @param string $host
* @param string $database
* @param string $username
* @param string $password
* @return mixed array of database connection params on success, false on failure
*
* @fixme escape things in the connection string in case we have a funny pass etc
*/
function Mysql_Db_installer($host, $database, $username, $password)
{
$this->updateStatus("Starting installation...");
$this->updateStatus("Checking database...");
$conn = mysqli_init();
if (!$conn->real_connect($host, $username, $password)) {
$this->updateStatus("Can't connect to server '$host' as '$username'.", true);
return false;
}
$this->updateStatus("Changing to database...");
if (!$conn->select_db($database)) {
$this->updateStatus("Can't change to database.", true);
return false; return false;
} }
$this->updateStatus("Running database script...");
$res = $this->runDbScript('statusnet.sql', $conn);
if ($res === false) {
$this->updateStatus("Can't run database script.", true);
return false;
}
foreach (array('sms_carrier' => 'SMS carrier', foreach (array('sms_carrier' => 'SMS carrier',
'notice_source' => 'notice source', 'notice_source' => 'notice source',
'foreign_services' => 'foreign service') 'foreign_services' => 'foreign service')
@ -386,11 +309,48 @@ abstract class Installer
} }
} }
$sqlUrl = "mysqli://$username:$password@$host/$database"; $db = array('type' => $this->dbtype, 'database' => $dsn);
$db = array('type' => 'mysql', 'database' => $sqlUrl);
return $db; return $db;
} }
/**
* Open a connection to the database.
*
* @param <type> $dsn
* @return <type>
*/
function connectDatabase($dsn)
{
require_once 'DB.php';
return DB::connect($dsn);
}
/**
* Create core tables on the given database connection.
*
* @param DB_common $conn
*/
function createCoreTables(DB_common $conn)
{
$schema = Schema::get($conn);
$tableDefs = $this->getCoreSchema();
foreach ($tableDefs as $name => $def) {
$schema->ensureTable($name, $def);
}
}
/**
* Fetch the core table schema definitions.
*
* @return array of table names => table def arrays
*/
function getCoreSchema()
{
$schema = array();
include INSTALLDIR . '/db/core.php';
return $schema;
}
/** /**
* Write a stock configuration file. * Write a stock configuration file.
* *
@ -431,13 +391,12 @@ abstract class Installer
/** /**
* Install schema into the database * Install schema into the database
* *
* @param string $filename location of database schema file * @param string $filename location of database schema file
* @param dbconn $conn connection to database * @param DB_common $conn connection to database
* @param string $type type of database, currently mysql or pgsql
* *
* @return boolean - indicating success or failure * @return boolean - indicating success or failure
*/ */
function runDbScript($filename, $conn, $type = 'mysqli') function runDbScript($filename, DB_common $conn)
{ {
$sql = trim(file_get_contents(INSTALLDIR . '/db/' . $filename)); $sql = trim(file_get_contents(INSTALLDIR . '/db/' . $filename));
$stmts = explode(';', $sql); $stmts = explode(';', $sql);
@ -446,24 +405,9 @@ abstract class Installer
if (!mb_strlen($stmt)) { if (!mb_strlen($stmt)) {
continue; continue;
} }
// FIXME: use PEAR::DB or PDO instead of our own switch $res = $conn->execute($stmt);
switch ($type) { if (DB::isError($res)) {
case 'mysqli': $error = $result->getMessage();
$res = $conn->query($stmt);
if ($res === false) {
$error = $conn->error;
}
break;
case 'pgsql':
$res = pg_query($conn, $stmt);
if ($res === false) {
$error = pg_last_error();
}
break;
default:
$this->updateStatus("runDbScript() error: unknown database type ". $type ." provided.");
}
if ($res === false) {
$this->updateStatus("ERROR ($error) for SQL '$stmt'"); $this->updateStatus("ERROR ($error) for SQL '$stmt'");
return $res; return $res;
} }