From 582efd357e3da2203e5699b72c0c90266d70d6e8 Mon Sep 17 00:00:00 2001
From: RDS-Team <rds@redi-bw.de>
Date: Tue, 29 Apr 2014 11:01:34 -0400
Subject: [PATCH] pgsql driver selection for installer

---
 build.xml                                     |   2 +-
 module/VuFind/sql/{postgres.sql => pgsql.sql} |   2 +-
 .../VuFind/Controller/InstallController.php   | 100 ++++++++++++++----
 .../templates/install/fixdatabase.phtml       |  11 +-
 .../templates/install/fixdatabase.phtml       |  31 +++---
 5 files changed, 109 insertions(+), 37 deletions(-)
 rename module/VuFind/sql/{postgres.sql => pgsql.sql} (99%)

diff --git a/build.xml b/build.xml
index 5846fbffe2c..adc80dcb074 100644
--- a/build.xml
+++ b/build.xml
@@ -120,7 +120,7 @@
         <exec command="sudo su -c &quot;psql -c \&quot;CREATE USER ${vufinddbuser} PASSWORD '${vufinddbpass}';\&quot;&quot; ${pgsqlrootuser}" checkreturn="true" />
         <exec command="sudo su -c &quot;psql -c \&quot;GRANT ALL ON DATABASE ${vufinddb} TO ${vufinddbuser};\&quot;&quot; ${pgsqlrootuser}" checkreturn="true" />
         <!--<exec command="sudo su -c &quot;psql -c \&quot;select 'grant SELECT,INSERT,UPDATE,DELETE on '||schemaname||'.'||tablename||' to ${vufinddbuser};' from pg_tables where schemaname in ('${vufinddb}') order by schemaname, tablename;\&quot;&quot; ${pgsqlrootuser}" checkreturn="true" />-->
-        <exec command="PGPASSWORD=${vufinddbpass} psql -U ${vufinddbuser} -f ${srcdir}/module/VuFind/sql/postgres.sql ${vufinddb}" checkreturn="true" />
+        <exec command="PGPASSWORD=${vufinddbpass} psql -U ${vufinddbuser} -f ${srcdir}/module/VuFind/sql/pgsql.sql ${vufinddb}" checkreturn="true" />
 
         <!-- configure VuFind -->
         <exec command="sed -e &quot;s!mysql://root@localhost/vufind!pgsql://${vufinddbuser}:${vufinddbpass}@${pgsqlhost}/${vufinddb}!&quot; ${srcdir}/config/vufind/config.ini &gt; ${srcdir}/local/config/vufind/config.ini" />
diff --git a/module/VuFind/sql/postgres.sql b/module/VuFind/sql/pgsql.sql
similarity index 99%
rename from module/VuFind/sql/postgres.sql
rename to module/VuFind/sql/pgsql.sql
index 2d8c9aff055..ca9c6d94a8d 100644
--- a/module/VuFind/sql/postgres.sql
+++ b/module/VuFind/sql/pgsql.sql
@@ -1,4 +1,4 @@
--- 
+-- 
 -- Table structure for table comments
 -- 
 
diff --git a/module/VuFind/src/VuFind/Controller/InstallController.php b/module/VuFind/src/VuFind/Controller/InstallController.php
index fe39c3ddd5d..631ca7dd848 100644
--- a/module/VuFind/src/VuFind/Controller/InstallController.php
+++ b/module/VuFind/src/VuFind/Controller/InstallController.php
@@ -325,6 +325,7 @@ class InstallController extends AbstractBase
         $view->dbuser = $this->params()->fromPost('dbuser', 'vufind');
         $view->dbhost = $this->params()->fromPost('dbhost', 'localhost');
         $view->dbrootuser = $this->params()->fromPost('dbrootuser', 'root');
+        $view->driver = $this->params()->fromPost('driver', 'mysql');
 
         $skip = $this->params()->fromPost('printsql', 'nope') == 'Skip';
 
@@ -345,41 +346,48 @@ class InstallController extends AbstractBase
                     ->addMessage('Password fields must match.');
             } else {
                 // Connect to database:
-                $connection = 'mysql://' . $view->dbrootuser . ':'
+                $connection = $view->driver . '://' . $view->dbrootuser . ':'
                     . $this->params()->fromPost('dbrootpass') . '@'
                     . $view->dbhost;
                 try {
+                    $dbName = ($view->driver == 'pgsql')
+                        ? 'template1' : $view->driver;
                     $db = $this->getServiceLocator()->get('VuFind\DbAdapterFactory')
-                        ->getAdapterFromConnectionString($connection . '/mysql');
+                        ->getAdapterFromConnectionString("{$connection}/{$dbName}");
                 } catch (\Exception $e) {
                     $this->flashMessenger()->setNamespace('error')
                         ->addMessage(
                             'Problem initializing database adapter; '
-                            . 'check for missing Mysqli library.  Details: '
-                            . $e->getMessage()
+                            . 'check for missing ' . $view->driver
+                            . ' library .  Details: ' . $e->getMessage()
                         );
                     return $view;
                 }
                 try {
                     // Get SQL together
-                    $query = 'CREATE DATABASE ' . $view->dbname;
-                    $grant = "GRANT SELECT,INSERT,UPDATE,DELETE ON "
-                        . $view->dbname
-                        . ".* TO '{$view->dbuser}'@'{$view->dbhost}' "
-                        . "IDENTIFIED BY " . $db->getPlatform()->quoteValue($newpass)
-                        . " WITH GRANT OPTION";
+                    $escapedPass = $skip
+                        ? "'" . addslashes($newpass) . "'"
+                        : $db->getPlatform()->quoteValue($newpass);
+                    $preCommands = $this->getPreCommands($view, $escapedPass);
+                    $postCommands = $this->getPostCommands($view);
                     $sql = file_get_contents(
-                        APPLICATION_PATH . '/module/VuFind/sql/mysql.sql'
+                        APPLICATION_PATH . "/module/VuFind/sql/{$view->driver}.sql"
                     );
-                    if ($skip == 'Skip') {
-                        $omnisql = $query . ";\n". $grant
-                            . ";\nFLUSH PRIVILEGES;\n\n" . $sql;
+                    if ($skip) {
+                        $omnisql = '';
+                        foreach ($preCommands as $query) {
+                            $omnisql .= $query . ";\n";
+                        }
+                        $omnisql .= "\n" . $sql . "\n";
+                        foreach ($postCommands as $query) {
+                            $omnisql .= $query . ";\n";
+                        }
                         $this->getRequest()->getQuery()->set('sql', $omnisql);
                         return $this->forwardTo('Install', 'showsql');
                     } else {
-                        $db->query($query, $db::QUERY_MODE_EXECUTE);
-                        $db->query($grant, $db::QUERY_MODE_EXECUTE);
-                        $db->query('FLUSH PRIVILEGES', $db::QUERY_MODE_EXECUTE);
+                        foreach ($preCommands as $query) {
+                            $db->query($query, $db::QUERY_MODE_EXECUTE);
+                        }
                         $dbFactory = $this->getServiceLocator()
                             ->get('VuFind\DbAdapterFactory');
                         $db = $dbFactory->getAdapterFromConnectionString(
@@ -393,9 +401,12 @@ class InstallController extends AbstractBase
                             }
                             $db->query($current, $db::QUERY_MODE_EXECUTE);
                         }
+                        foreach ($postCommands as $query) {
+                            $db->query($query, $db::QUERY_MODE_EXECUTE);
+                        }
                         // If we made it this far, we can update the config file and
                         // forward back to the home action!
-                        $string = "mysql://{$view->dbuser}:{$newpass}@"
+                        $string = "{$view->driver}://{$view->dbuser}:{$newpass}@"
                             . $view->dbhost . '/' . $view->dbname;
                         $config = ConfigLocator::getLocalConfigPath(
                             'config.ini', null, true
@@ -416,6 +427,59 @@ class InstallController extends AbstractBase
         return $view;
     }
 
+    /**
+     * Get SQL commands needed to set up a particular database before
+     * loading the main SQL file of table definitions.
+     *
+     * @param \Zend\View\Model $view        View object containing DB settings.
+     * @param string           $escapedPass Password to set for new DB (escaped
+     * appropriately for target database).
+     *
+     * @return array
+     */
+    protected function getPreCommands($view, $escapedPass)
+    {
+        $create = 'CREATE DATABASE ' . $view->dbname;
+        // Special case: PostgreSQL:
+        if ($view->driver == 'pgsql') {
+            $escape = "ALTER DATABASE " . $view->dbname
+                . " SET bytea_output='escape'";
+            $cuser = "CREATE USER " . $view->dbuser
+                . " WITH PASSWORD {$escapedPass}";
+            $grant = "GRANT ALL PRIVILEGES ON DATABASE "
+                . "{$view->dbname} TO {$view->dbuser} ";
+            return array($create, $escape, $cuser, $grant);
+        }
+        // Default: MySQL:
+        $grant = "GRANT SELECT,INSERT,UPDATE,DELETE ON "
+            . $view->dbname
+            . ".* TO '{$view->dbuser}'@'{$view->dbhost}' "
+            . "IDENTIFIED BY {$escapedPass} WITH GRANT OPTION";
+        return array($create, $grant, 'FLUSH PRIVILEGES');
+    }
+
+    /**
+     * Get SQL commands needed to set up a particular database after
+     * loading the main SQL file of table definitions.
+     *
+     * @param \Zend\View\Model $view View object containing DB settings.
+     *
+     * @return array
+     */
+    protected function getPostCommands($view)
+    {
+        // Special case: PostgreSQL:
+        if ($view->driver == 'pgsql') {
+            $grantTables =  "GRANT ALL PRIVILEGES ON ALL TABLES IN "
+                . "SCHEMA public TO {$view->dbuser} ";
+            $grantSequences =  "GRANT ALL PRIVILEGES ON ALL SEQUENCES"
+                ." IN SCHEMA public TO {$view->dbuser} ";
+            return array($grantTables, $grantSequences);
+        }
+        // Default: MySQL:
+        return array();
+    }
+
     /**
      * Display captured SQL commands for database action.
      *
diff --git a/themes/blueprint/templates/install/fixdatabase.phtml b/themes/blueprint/templates/install/fixdatabase.phtml
index cdc029190fc..c03ba347db4 100644
--- a/themes/blueprint/templates/install/fixdatabase.phtml
+++ b/themes/blueprint/templates/install/fixdatabase.phtml
@@ -14,16 +14,17 @@
 <form action="" method="post">
   <table>
     <tbody>
+      <tr><td>Select database type: </td><td><select name="driver"><option value="mysql">MySQL</option><option <? if ($driver == 'pgsql'): ?>selected="selected" <? endif; ?>value="pgsql">PostgreSQL</option></select></td></tr>
       <tr><td>New database name: </td><td><input type="text" name="dbname" value="<?=$this->escapeHtml($this->dbname)?>"/></td></tr>
       <tr><td>New database user: </td><td><input type="text" name="dbuser" value="<?=$this->escapeHtml($this->dbuser)?>"/></td></tr>
       <tr><td>New user password: </td><td><input type="password" name="dbpass" value=""/></td></tr>
       <tr><td>Confirm new user password: </td><td><input type="password" name="dbpassconfirm" value=""/></td></tr>
-      <tr><td>MySQL Host: </td><td><input type="text" name="dbhost" value="<?=$this->escapeHtml($this->dbhost)?>"/></td></tr>
-      <tr><td>MySQL Root User: </td><td><input type="text" name="dbrootuser" value="<?=$this->escapeHtml($this->dbrootuser)?>"/></td></tr>
-      <tr><td>MySQL Root Password: </td><td><input type="password" name="dbrootpass" value=""/></td></tr>
+      <tr><td>SQL Host: </td><td><input type="text" name="dbhost" value="<?=$this->escapeHtml($this->dbhost)?>"/></td></tr>
+      <tr><td>SQL Root User: </td><td><input type="text" name="dbrootuser" value="<?=$this->escapeHtml($this->dbrootuser)?>"/></td></tr>
+      <tr><td>SQL Root Password: </td><td><input type="password" name="dbrootpass" value=""/></td></tr>
       <tr><td width="50%"></td><td><input type="submit" name="submit" value="<?=$this->transEsc('Submit') ?>" /></td></tr>
       <tr><td>If you don't have the credentials or you wish to print the SQL out :</td><td>Click here to <input type="submit" name="printsql" value="Skip" /> credentials.</td></tr>
     </tbody>
   </table>
-   
-</form>
\ No newline at end of file
+
+</form>
diff --git a/themes/bootstrap/templates/install/fixdatabase.phtml b/themes/bootstrap/templates/install/fixdatabase.phtml
index 920d4024b52..b0bbeca1e30 100644
--- a/themes/bootstrap/templates/install/fixdatabase.phtml
+++ b/themes/bootstrap/templates/install/fixdatabase.phtml
@@ -13,44 +13,51 @@
 <p>To create a new database for VuFind, please fill in this form:</p>
 
 <form class="form-horizontal" action="" method="post">
-  <div class="control-group">    
+  <div class="control-group">
+    <label class="control-label" for="dbname">Select database type:</label>
+    <div class="controls">
+      <select name="driver"><option value="mysql">MySQL</option><option <? if ($driver == 'pgsql'): ?>selected="selected" <? endif; ?>value="pgsql">PostgreSQL</option></select>
+    </div>
+  </div>
+
+  <div class="control-group">
     <label class="control-label" for="dbname">New database name:</label>
     <div class="controls">
       <input type="text" name="dbname" value="<?=$this->escapeHtml($this->dbname)?>"/>
     </div>
   </div>
-  <div class="control-group">    
+  <div class="control-group">
     <label class="control-label" for="dbuser">New database user:</label>
     <div class="controls">
       <input type="text" name="dbuser" value="<?=$this->escapeHtml($this->dbuser)?>"/>
     </div>
   </div>
-  <div class="control-group">    
+  <div class="control-group">
     <label class="control-label" for="dbpass">New user password:</label>
     <div class="controls">
       <input type="password" name="dbpass" value=""/>
     </div>
   </div>
-  <div class="control-group">    
+  <div class="control-group">
     <label class="control-label" for="dbpassconfirm">Confirm new user password:</label>
     <div class="controls">
       <input type="password" name="dbpassconfirm" value=""/>
     </div>
   </div>
-  <div class="control-group">    
-    <label class="control-label" for="dbhost">MySQL Host:</label>
+  <div class="control-group">
+    <label class="control-label" for="dbhost">SQL Host:</label>
     <div class="controls">
       <input type="text" name="dbhost" value="<?=$this->escapeHtml($this->dbhost)?>"/>
     </div>
   </div>
-  <div class="control-group">    
-    <label class="control-label" for="dbrootuser">MySQL Root User:</label>
+  <div class="control-group">
+    <label class="control-label" for="dbrootuser">SQL Root User:</label>
     <div class="controls">
       <input type="text" name="dbrootuser" value="<?=$this->escapeHtml($this->dbrootuser)?>"/>
     </div>
   </div>
-  <div class="control-group">    
-    <label class="control-label" for="dbrootpass">MySQL Root Password:</label>
+  <div class="control-group">
+    <label class="control-label" for="dbrootpass">SQL Root Password:</label>
     <div class="controls">
       <input type="password" name="dbrootpass" value=""/>
     </div>
@@ -60,7 +67,7 @@
       <input class="btn btn-primary" type="submit" name="submit" value="<?=$this->transEsc('Submit') ?>" />
     </div>
   </div>
-  <div class="control-group">    
+  <div class="control-group">
     <label class="control-label" for="printsql">If you don't have the credentials or you wish to print the SQL out :</label>
     <div class="controls">
       <span class="help-inline">Click here to</span>
@@ -68,4 +75,4 @@
       <span class="help-inline">credentials.</span>
     </div>
   </div>
-</form>
\ No newline at end of file
+</form>
-- 
GitLab