[PATCH] Fix for amavisd-sql constraint problem

Josh Endries <[email protected]> Sun, 14 Aug 2005 09:40:45 -0400
Newsgroups gmane.comp.horde.sam
Message-ID <[email protected]>
This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--===============1248815944==
Content-Type: multipart/signed; micalg=pgp-sha1;
	protocol="application/pgp-signature";
	boundary="------------enigC59EC8DFC9AD861CE80A8716"

This is an OpenPGP/MIME signed message (RFC 2440 and 3156)
--------------enigC59EC8DFC9AD861CE80A8716
Content-Type: multipart/mixed; boundary="------------020208010908040809040405"

This is a multi-part message in MIME format.
--------------020208010908040809040405
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit

Hello,

I'm not a PHP/PEAR/Horde expert, but attached is a patch I hacked up
to fix a constraint problem I was having with SAM. The problem is
that, when a user submits a whitelist, the existence of sender
addresses is only checked for addresses in the existing wblist and
not for new additions. If one user adds an address, and someone else
tries to add that same address, it breaks the unique index in the DB.
This patch simply checks for the existence of new addresses. If
found, it uses the current ID, otherwise it inserts as usual.

Josh

--------------020208010908040809040405
Content-Type: text/plain;
 name="sam-diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="sam-diff"

--- amavisd_sql.php.orig        Mon Jul 25 11:27:46 2005
+++ amavisd_sql.php     Sat Aug 13 22:29:45 2005
@@ -595,21 +595,8 @@
             if (isset($this->_options[$list])) {
                 foreach ($this->_options[$list] as $sender) {
                     if (!in_array($sender, $existing[$list])) {
-                        $query = sprintf('INSERT INTO %s (%s) VALUES (?)',
-                                         $this->_mapNameToTable('senders'),
-                                         $this->_mapAttributeToField('senders', 'email'));
-                        $values = array($sender);
-
-                        /* Log the query at a DEBUG log level. */
-                        Horde::logMessage(sprintf('SAM_Driver_amavisd_sql::_store(): %s', $query),
-                                          __FILE__, __LINE__, PEAR_LOG_DEBUG);
-
-                        $result = $this->_db->query($query, $values);
-                        if (is_a($result, 'PEAR_Error')) {
-                            Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
-                            return $result;
-                        }

+                        /* Check if this sender address exists already. */
                         $query = sprintf('SELECT %s FROM %s WHERE %s = ?',
                                          $this->_mapAttributeToField('senders', 'id'),
                                          $this->_mapNameToTable('senders'),
@@ -620,27 +607,74 @@
                         Horde::logMessage(sprintf('SAM_Driver_amavisd_sql::_store(): %s', $query),
                                           __FILE__, __LINE__, PEAR_LOG_DEBUG);

-                        $senderID = $this->_db->getOne($query, $values);
-                        if (is_a($senderID, 'PEAR_Error')) {
-                            Horde::logMessage($senderID, __FILE__, __LINE__, PEAR_LOG_ERR);
-                            return $senderID;
-                        }
+                        $wb_result = $this->_db->getOne($query, $values);
+                        if (is_null($wb_result)) {
+                            /* Address doesn't exist, add it. */
+                            $query = sprintf('INSERT INTO %s (%s) VALUES (?)',
+                                             $this->_mapNameToTable('senders'),
+                                             $this->_mapAttributeToField('senders', 'email'));
+                            $values = array($sender);

-                        $query = sprintf('INSERT INTO %s (%s, %s, %s) VALUES (?, ?, ?)',
-                                         $this->_mapNameToTable('wblists'),
-                                         $this->_mapAttributeToField('wblists', 'recipient'),
-                                         $this->_mapAttributeToField('wblists', 'sender'),
-                                         $this->_mapAttributeToField('wblists', 'type'));
-                        $values = array($userID, $senderID, $type);
+                            /* Log the query at a DEBUG log level. */
+                            Horde::logMessage(sprintf('SAM_Driver_amavisd_sql::_store(): %s', $query),
+                                              __FILE__, __LINE__, PEAR_LOG_DEBUG);

-                        /* Log the query at a DEBUG log level. */
-                        Horde::logMessage(sprintf('SAM_Driver_amavisd_sql::_store(): %s', $query),
-                                          __FILE__, __LINE__, PEAR_LOG_DEBUG);
+                            $result = $this->_db->query($query, $values);
+                            if (is_a($result, 'PEAR_Error')) {
+                                Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+                                return $result;
+                            }

-                        $result = $this->_db->query($query, $values);
-                        if (is_a($result, 'PEAR_Error')) {
-                            Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
-                            return $result;
+                            $query = sprintf('SELECT %s FROM %s WHERE %s = ?',
+                                             $this->_mapAttributeToField('senders', 'id'),
+                                             $this->_mapNameToTable('senders'),
+                                             $this->_mapAttributeToField('senders', 'email'));
+                            $values = array($sender);
+
+                            /* Log the query at a DEBUG log level. */
+                            Horde::logMessage(sprintf('SAM_Driver_amavisd_sql::_store(): %s', $query),
+                                              __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+                            $senderID = $this->_db->getOne($query, $values);
+                            if (is_a($senderID, 'PEAR_Error')) {
+                                Horde::logMessage($senderID, __FILE__, __LINE__, PEAR_LOG_ERR);
+                                return $senderID;
+                            }
+
+                            $query = sprintf('INSERT INTO %s (%s, %s, %s) VALUES (?, ?, ?)',
+                                             $this->_mapNameToTable('wblists'),
+                                             $this->_mapAttributeToField('wblists', 'recipient'),
+                                             $this->_mapAttributeToField('wblists', 'sender'),
+                                             $this->_mapAttributeToField('wblists', 'type'));
+                            $values = array($userID, $senderID, $type);
+
+                            /* Log the query at a DEBUG log level. */
+                            Horde::logMessage(sprintf('SAM_Driver_amavisd_sql::_store(): %s', $query),
+                                              __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+                            $result = $this->_db->query($query, $values);
+                            if (is_a($result, 'PEAR_Error')) {
+                                Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+                                return $result;
+                            }
+                        } else {
+                            /* Address exists, use it's ID */
+                            $query = sprintf('INSERT INTO %s (%s, %s, %s) VALUES (?, ?, ?)',
+                                             $this->_mapNameToTable('wblists'),
+                                             $this->_mapAttributeToField('wblists', 'recipient'),
+                                             $this->_mapAttributeToField('wblists', 'sender'),
+                                             $this->_mapAttributeToField('wblists', 'type'));
+                            $values = array($userID, $wb_result, $type);
+
+                            /* Log the query at a DEBUG log level. */
+                            Horde::logMessage(sprintf('SAM_Driver_amavisd_sql::_store(): %s', $query),
+                                              __FILE__, __LINE__, PEAR_LOG_DEBUG);
+
+                            $result = $this->_db->query($query, $values);
+                            if (is_a($result, 'PEAR_Error')) {
+                                Horde::logMessage($result, __FILE__, __LINE__, PEAR_LOG_ERR);
+                                return $result;
+                            }
                         }
                     }
                 }
--------------020208010908040809040405--

--------------enigC59EC8DFC9AD861CE80A8716
Content-Type: application/pgp-signature; name="signature.asc"
Content-Description: OpenPGP digital signature
Content-Disposition: attachment; filename="signature.asc"

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.5 (MingW32)
Comment: Using GnuPG with Thunderbird - http://enigmail.mozdev.org

iD8DBQFC/0nlV/+PyAj2L+IRAgzaAJ9J0i2xbI9xU3kZ3RKScf1AluoSawCfWE5h
QukZx4689cs/8Wfl4eJdT4E=
=kUbq
-----END PGP SIGNATURE-----

--------------enigC59EC8DFC9AD861CE80A8716--

--===============1248815944==
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

-- 
sam mailing list - Join the hunt: http://horde.org/bounties/#sam
Frequently Asked Questions: http://horde.org/faq/
To unsubscribe, mail: [email protected]

--===============1248815944==--