From d52fbf760f2060f1b68b1ec2ee9149af44078a5e Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Thu, 9 May 2013 10:00:17 -0400
Subject: [PATCH] Progress on PostgreSQL compatibility (thanks to Michele
 Meloni).

---
 config/vufind/config.ini                      |  3 +++
 module/VuFind/config/module.config.php        | 13 ++++++++++++
 .../VuFind/src/VuFind/Db/AdapterFactory.php   | 20 +++++++++++++++----
 module/VuFind/src/VuFind/Db/Table/Gateway.php | 16 +++++++++++++++
 module/VuFind/src/VuFind/Db/Table/Tags.php    |  4 ++--
 5 files changed, 50 insertions(+), 6 deletions(-)

diff --git a/config/vufind/config.ini b/config/vufind/config.ini
index 8c10756ab7d..76385cbd80f 100644
--- a/config/vufind/config.ini
+++ b/config/vufind/config.ini
@@ -262,6 +262,9 @@ require_login   = true
 [Database]
 database          = mysql://root@localhost/vufind
 
+; If your database (e.g. PostgreSQL) uses a schema, you can set it here:
+;schema = schema_name
+
 ; The character set of the database -- may be latin1 or utf8; utf8 is STRONGLY
 ; RECOMMENDED and is the default if no value is set here.  You may need latin1
 ; for compatibility with existing VuFind 1.x installations.
diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php
index 8fb8b2a3a62..545b2210cc8 100644
--- a/module/VuFind/config/module.config.php
+++ b/module/VuFind/config/module.config.php
@@ -346,6 +346,19 @@ $config = array(
         'config_reader' => array(
             'abstract_factories' => array('VuFind\Config\PluginFactory'),
         ),
+        // PostgreSQL sequence mapping
+        'pgsql_seq_mapping'  => array(
+            'comments'       => array('id', 'comments_id_seq'),
+            'oai_resumption' => array('id', 'oai_resumption_id_seq'),
+            'resource'       => array('id', 'resource_id_seq'),
+            'resource_tags'  => array('id', 'resource_tags_id_seq'),
+            'search'         => array('id', 'search_id_seq'),
+            'session'        => array('id', 'session_id_seq'),
+            'tags'           => array('id', 'tags_id_seq'),
+            'user'           => array('id', 'user_id_seq'),
+            'user_list'      => array('id', 'user_list_id_seq'),
+            'user_resource'  => array('id', 'user_resource_id_seq')
+        ),
         // This section contains service manager configurations for all VuFind
         // pluggable components:
         'plugin_managers' => array(
diff --git a/module/VuFind/src/VuFind/Db/AdapterFactory.php b/module/VuFind/src/VuFind/Db/AdapterFactory.php
index 8a32d721d72..f37dc46cc6d 100644
--- a/module/VuFind/src/VuFind/Db/AdapterFactory.php
+++ b/module/VuFind/src/VuFind/Db/AdapterFactory.php
@@ -102,18 +102,30 @@ class AdapterFactory
      * @return object
      */
     public function getAdapterFromOptions($options)
-    {
+    {       
         // Set up custom options by database type:
-        switch (strtolower($options['driver'])) {
+        $driver = strtolower($options['driver']);
+        switch ($driver) {
         case 'mysqli':
             $options['charset'] = isset($this->config->Database->charset)
                 ? $this->config->Database->charset : 'utf8';
             $options['options'] = array('buffer_results' => true);
-            break;
+            break; 
         }
 
         // Set up database connection:
-        return new Adapter($options);
+        $adapter = new Adapter($options);
+
+        // Special-case setup:
+        if ($driver == 'pdo_pgsql' && isset($this->config->Database->schema)) {
+            // Set schema
+            $statement = $adapter->createStatement(
+                'SET search_path TO ' . $this->config->Database->schema
+            );
+            $result = $statement->execute();
+        }
+
+        return $adapter;
     }
 
     /**
diff --git a/module/VuFind/src/VuFind/Db/Table/Gateway.php b/module/VuFind/src/VuFind/Db/Table/Gateway.php
index b05e8436947..77bd885deca 100644
--- a/module/VuFind/src/VuFind/Db/Table/Gateway.php
+++ b/module/VuFind/src/VuFind/Db/Table/Gateway.php
@@ -27,6 +27,7 @@
  */
 namespace VuFind\Db\Table;
 use Zend\Db\TableGateway\AbstractTableGateway,
+    Zend\Db\TableGateway\Feature,
     Zend\ServiceManager\ServiceLocatorAwareInterface,
     Zend\ServiceManager\ServiceLocatorInterface;
 
@@ -85,6 +86,21 @@ class Gateway extends AbstractTableGateway implements ServiceLocatorAwareInterfa
         if ($this->isInitialized) {
             return;
         }
+
+        // Special case for PostgreSQL sequences:
+        if ($this->adapter->getDriver()->getDatabasePlatformName() == "Postgresql") {
+            $cfg = $this->getServiceLocator()->getServiceLocator()->get('config');
+            $maps = $cfg['vufind']['pgsql_seq_mapping'];
+            if (isset($maps[$this->table])) {
+                $this->featureSet = new Feature\FeatureSet();
+                $this->featureSet->addFeature(
+                    new Feature\SequenceFeature(
+                        $maps[$this->table][0], $maps[$this->table][1]
+                    )
+                );
+            }
+        }
+
         parent::initialize();
         if (null !== $this->rowClass) {
             $resultSetPrototype = $this->getResultSetPrototype();
diff --git a/module/VuFind/src/VuFind/Db/Table/Tags.php b/module/VuFind/src/VuFind/Db/Table/Tags.php
index a00ed47c15f..bbe8fd74c7c 100644
--- a/module/VuFind/src/VuFind/Db/Table/Tags.php
+++ b/module/VuFind/src/VuFind/Db/Table/Tags.php
@@ -99,7 +99,7 @@ class Tags extends Gateway
      */
     public function getForResource($id, $source = 'VuFind', $limit = 0,
         $list = null, $user = null, $sort = 'count'
-    ) {
+    ) {   
         return $this->select(
             function ($select) use ($id, $source, $limit, $list, $user, $sort) {
                 $select->columns(
@@ -119,7 +119,7 @@ class Tags extends Gateway
                 );
                 $select->where->equalTo('r.record_id', $id)
                     ->equalTo('r.source', $source);
-                $select->group(array('id', 'tag'));
+                $select->group(array('tags.id', 'tag'));
 
                 if ($sort == 'count') {
                     $select->order(array('cnt DESC', 'tags.tag'));
-- 
GitLab