]> git.mxchange.org Git - quix0rs-gnu-social.git/commitdiff
Merge branch '1.0.x' into schema-x
authorBrion Vibber <brion@pobox.com>
Mon, 18 Oct 2010 22:26:20 +0000 (15:26 -0700)
committerBrion Vibber <brion@pobox.com>
Mon, 18 Oct 2010 22:26:20 +0000 (15:26 -0700)
1  2 
lib/installer.php

diff --combined lib/installer.php
index a5588fbed6404fac095b46a1f5a164f896a29830,a9d8090110a0039d9b8ba89fa1ed4c9337bf4287..441f7266063e932ef83f84369be20ebcebf5d506
@@@ -2,7 -2,7 +2,7 @@@
  
  /**
   * StatusNet - the distributed open-source microblogging tool
 - * Copyright (C) 2009, StatusNet, Inc.
 + * Copyright (C) 2009-2010, StatusNet, Inc.
   *
   * This program is free software: you can redistribute it and/or modify
   * it under the terms of the GNU Affero General Public License as published by
   * @author   Sarven Capadisli <csarven@status.net>
   * @author   Tom Adams <tom@holizz.com>
   * @author   Zach Copley <zach@status.net>
 + * @copyright 2009-2010 StatusNet, Inc http://status.net
   * @copyright 2009 Free Software Foundation, Inc http://www.fsf.org
   * @license  GNU Affero General Public License http://www.gnu.org/licenses/
 - * @version  0.9.x
 + * @version  1.0.x
   * @link     http://status.net
   */
  
@@@ -54,12 -53,12 +54,12 @@@ abstract class Installe
          'mysql' => array(
              'name' => 'MySQL',
              'check_module' => 'mysqli',
 -            'installer' => 'mysql_db_installer',
 +            'scheme' => 'mysqli', // DSN prefix for PEAR::DB
          ),
          'pgsql' => array(
              'name' => 'PostgreSQL',
              'check_module' => 'pgsql',
 -            'installer' => 'pgsql_db_installer',
 +            'scheme' => 'pgsql', // DSN prefix for PEAR::DB
          ),
      );
  
       * Set up the database with the appropriate function for the selected type...
       * 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
       */
      function setupDatabase()
          if ($this->db) {
              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("Checking database...");
 -        $conn = pg_connect($connstring);
  
 -        if ($conn ===false) {
 -            $this->updateStatus("Failed to connect to database: $connstring");
 -            return false;
 +        if (empty($this->password)) {
 +            $auth = '';
 +        } else {
 +            $auth = ":$this->password";
          }
 +        $scheme = self::$dbModules[$this->dbtype]['scheme'];
 +        $dsn = "{$scheme}://{$this->username}{$auth}@{$this->host}/{$this->database}";
  
 -        //ensure database encoding is UTF8
 -        $record = pg_fetch_object(pg_query($conn, 'SHOW server_encoding'));
 -        if ($record->server_encoding != 'UTF8') {
 -            $this->updateStatus("StatusNet requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding));
 -            return false;
 +        $this->updateStatus("Checking database...");
 +        $conn = $this->connectDatabase($dsn);
 +
 +        // ensure database encoding is UTF8
 +        if ($this->dbtype == 'mysql') {
 +            // @fixme utf8m4 support for mysql 5.5?
 +            // Force the comms charset to utf8 for sanity
 +            // This doesn't currently work. :P
 +            //$conn->executes('set names utf8');
 +        } else if ($this->dbtype == 'pgsql') {
 +            $record = $conn->getRow('SHOW server_encoding');
 +            if ($record->server_encoding != 'UTF8') {
 +                $this->updateStatus("StatusNet requires UTF8 character encoding. Your database is ". htmlentities($record->server_encoding));
 +                return false;
 +            }
          }
  
 -        $this->updateStatus("Running database script...");
 -        //wrap in transaction;
 -        pg_query($conn, 'BEGIN');
 -        $res = $this->runDbScript('statusnet_pg.sql', $conn, 'pgsql');
 -
 -        if ($res === false) {
 -            $this->updateStatus("Can't run database script.", true);
 +        $res = $this->updateStatus("Creating database tables...");
 +        if (!$this->createCoreTables($conn)) {
 +            $this->updateStatus("Error creating tables.", 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');
 +            $res = $this->runDbScript($scr.'.sql', $conn);
              if ($res === false) {
 -                $this->updateStatus(sprintf("Can't run %s script.", $name), true);
 +                $this->updateStatus(sprintf("Can't run %d script.", $name), true);
                  return false;
              }
          }
 -        pg_query($conn, 'COMMIT');
 -
 -        if (empty($password)) {
 -            $sqlUrl = "pgsql://$username@$host/$database";
 -        } else {
 -            $sqlUrl = "pgsql://$username:$password@$host/$database";
 -        }
 -
 -        $db = array('type' => 'pgsql', 'database' => $sqlUrl);
  
 +        $db = array('type' => $this->dbtype, 'database' => $dsn);
          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
 +     * Open a connection to the database.
 +     *
 +     * @param <type> $dsn
 +     * @return <type> 
       */
 -    function Mysql_Db_installer($host, $database, $username, $password)
 +    function connectDatabase($dsn)
      {
 -        $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;
 -        }
 +        // @fixme move this someplace more sensible
 +        //set_include_path(INSTALLDIR . '/extlib' . PATH_SEPARATOR . get_include_path());
 +        require_once 'DB.php';
 +        return DB::connect($dsn);
 +    }
  
 -        $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',
 -                    '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);
 -            if ($res === false) {
 -                $this->updateStatus(sprintf("Can't run %d script.", $name), true);
 -                return false;
 +    /**
 +     * 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) {
 +            if (defined('DEBUG_INSTALLER')) {
 +                echo " $name ";
              }
 +            $schema->ensureTable($name, $def);
          }
 +    }
  
 -        $sqlUrl = "mysqli://$username:$password@$host/$database";
 -        $db = array('type' => 'mysql', 'database' => $sqlUrl);
 -        return $db;
 +    /**
 +     * 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;
      }
  
+     /**
+      * Return a parseable PHP literal for the given value.
+      * This will include quotes for strings, etc.
+      *
+      * @param mixed $val
+      * @return string
+      */
+     function phpVal($val)
+     {
+         return var_export($val, true);
+     }
+     /**
+      * Return an array of parseable PHP literal for the given values.
+      * These will include quotes for strings, etc.
+      *
+      * @param mixed $val
+      * @return array
+      */
+     function phpVals($map)
+     {
+         return array_map(array($this, 'phpVal'), $map);
+     }
      /**
       * Write a stock configuration file.
       *
       */
      function writeConf()
      {
+         $vals = $this->phpVals(array(
+             'sitename' => $this->sitename,
+             'server' => $this->server,
+             'path' => $this->path,
+             'db_database' => $this->db['database'],
+             'db_type' => $this->db['type'],
+         ));
          // assemble configuration file in a string
          $cfg =  "<?php\n".
                  "if (!defined('STATUSNET') && !defined('LACONICA')) { exit(1); }\n\n".
  
                  // site name
-                 "\$config['site']['name'] = '{$this->sitename}';\n\n".
+                 "\$config['site']['name'] = {$vals['sitename']};\n\n".
  
                  // site location
-                 "\$config['site']['server'] = '{$this->server}';\n".
-                 "\$config['site']['path'] = '{$this->path}'; \n\n".
+                 "\$config['site']['server'] = {$vals['server']};\n".
+                 "\$config['site']['path'] = {$vals['path']}; \n\n".
  
                  // checks if fancy URLs are enabled
                  ($this->fancy ? "\$config['site']['fancy'] = true;\n\n":'').
  
                  // database
-                 "\$config['db']['database'] = '{$this->db['database']}';\n\n".
+                 "\$config['db']['database'] = {$vals['db_database']};\n\n".
                  ($this->db['type'] == 'pgsql' ? "\$config['db']['quote_identifiers'] = true;\n\n":'').
-                 "\$config['db']['type'] = '{$this->db['type']}';\n\n";
+                 "\$config['db']['type'] = {$vals['db_type']};\n\n";
  
          // Normalize line endings for Windows servers
          $cfg = str_replace("\n", PHP_EOL, $cfg);
      /**
       * Install schema into the database
       *
 -     * @param string $filename location of database schema file
 -     * @param dbconn $conn     connection to database
 -     * @param string $type     type of database, currently mysql or pgsql
 +     * @param string    $filename location of database schema file
 +     * @param DB_common $conn     connection to database
       *
       * @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));
          $stmts = explode(';', $sql);
              if (!mb_strlen($stmt)) {
                  continue;
              }
 -            // FIXME: use PEAR::DB or PDO instead of our own switch
 -            switch ($type) {
 -            case 'mysqli':
 -                $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) {
 +            $res = $conn->execute($stmt);
 +            if (DB::isError($res)) {
 +                $error = $result->getMessage();
                  $this->updateStatus("ERROR ($error) for SQL '$stmt'");
                  return $res;
              }
       */
      function doInstall()
      {
 -        $this->db = $this->setupDatabase();
 -
 -        if (!$this->db) {
 -            // database connection failed, do not move on to create config file.
 +        $this->updateStatus("Initializing...");
 +        ini_set('display_errors', 1);
 +        error_reporting(E_ALL);
 +        define('STATUSNET', 1);
 +        require_once INSTALLDIR . '/lib/framework.php';
 +        StatusNet::initDefaults($this->server, $this->path);
 +
 +        try {
 +            $this->db = $this->setupDatabase();
 +            if (!$this->db) {
 +                // database connection failed, do not move on to create config file.
 +                return false;
 +            }
 +        } catch (Exception $e) {
 +            // Lower-level DB error!
 +            $this->updateStatus("Database error: " . $e->getMessage(), true);
              return false;
          }