Index: setup.py
===================================================================
--- setup.py	(revision 12970)
+++ setup.py	(working copy)
@@ -13,7 +13,7 @@
 from setuptools import setup, find_packages
 
 PACKAGE = 'TracDirectoryAuth'
-VERSION = '1.0.2'
+VERSION = '1.0.3'
 
 setup(  name=PACKAGE, version=VERSION,
         author = 'John Hampton',
Index: tracext/dirauth/auth.py
===================================================================
--- tracext/dirauth/auth.py	(revision 12970)
+++ tracext/dirauth/auth.py	(working copy)
@@ -313,55 +313,58 @@
                 continue
         return (username, displayname, email)
 
+    def _insert_or_update_session(self, sid, auth, last_visit):
+        """Attempt to implement a portable database upsert for session table"""
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            cursor.execute("""
+                UPDATE session
+                SET authenticated=%s, last_visit=%s
+                WHERE sid=%s;
+                INSERT INTO session
+                (sid, authenticated, last_visit)
+                SELECT %s, %s, %s
+                WHERE NOT EXISTS
+                (SELECT sid from session WHERE sid=%s)
+                """, (auth, last_visit, sid, sid, auth, last_visit, sid))
+
+    def _insert_or_update_session_attribute(self, sid, auth, name, value):
+        """Attempt to implement a portable database upsert for session_attribute table"""
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            cursor.execute("""
+                UPDATE session_attribute
+                SET authenticated=%s, name=%s, value=%s
+                WHERE sid=%s AND name=%s;
+                INSERT INTO session_attribute
+                (sid, authenticated, name, value)
+                SELECT %s, %s, %s, %s
+                WHERE NOT EXISTS
+                (SELECT sid, name from session_attribute WHERE sid=%s AND name=%s)
+                """, (auth, name, value, sid, name, sid, auth, name, value, sid, name))
+
     def _populate_user_session(self, userinfo):
         """ Create user session entries and populate email and last visit """
 
+        (uname, displayname, email) = userinfo
+        
         # Kind of ugly.  First try to insert a new session record.  If it
         # fails, don't worry, means it's already there.  Second, insert the
         # email address session attribute.  If it fails, don't worry, it's
         # already there.
-        (uname, displayname, email) = userinfo
-
-        db = self.env.get_db_cnx()
-        cur = db.cursor()
-        try:
-            cur.execute('INSERT INTO session (sid, authenticated, last_visit) VALUES (%s, 1, %s)' % (uname, 0))
-        except:
-            self.log.debug('session for %s exists.' % uname)
-
+        self._insert_or_update_session(uname, 1, 0)
+        
         # -- assume enabled if we get this far
         #   self.env.get_known_users() needs this.. 
         # TODO need to have it updated by the get_dn stuff long term so the db matches the auth source.
-        cur = db.cursor()
-        try:
-            cur.execute(
-                "INSERT INTO session_attribute (sid, authenticated, name, value) VALUES ('%s', 1, 'enabled', '1')"
-                % uname)
-        except:
-            self.log.debug('session for %s exists.' % uname)
+        self._insert_or_update_session_attribute(uname, 1, 'enabled', '1')
 
         # -- we want to update these regardless.
         if email:
-            cur = db.cursor()
-            cur.execute("""
-                INSERT OR REPLACE INTO session_attribute
-                  (sid, authenticated, name, value)
-                VALUES (%s, 1, 'email', %s)
-                """, (uname, to_unicode(email)))
-            self.log.info('updating user session email info for %s (%s)'
-                          % (uname, to_unicode(email)))
+            self._insert_or_update_session_attribute(uname, 1, 'email', to_unicode(email))
 
         if displayname:
-            cur = db.cursor()
-            cur.execute("""
-                INSERT OR REPLACE INTO session_attribute
-                  (sid, authenticated, name, value)
-                VALUES (%s, 1, 'name', %s)
-                """, (uname, to_unicode(displayname)))
-            self.log.info('updating user session displayname info for %s (%s)'
-                          % (uname, to_unicode(displayname)))
-        db.commit()
-        return db.close()
+            self._insert_or_update_session_attribute(uname, 1, 'name', to_unicode(displayname))
 
     def _cache_get(self, key=None, ttl=None):
         """Get an item from memory cache"""
@@ -494,16 +497,19 @@
 
         # -- set the data in the db cache for the next search, even empty results
         res_str = cPickle.dumps(res, 0)
-        try:
-            cur = db.cursor()
-            cur.execute("""INSERT OR REPLACE INTO dir_cache (id, lut, data)
-                         VALUES (%s, %s, %s)""", [str(key), int(current_time), buffer(res_str)])
-            db.commit()
+        with self.env.db_transaction as db:
+            cursor = db.cursor()
+            cursor.execute("""
+                UPDATE dir_cache
+                SET lut=%s, data=%s
+                WHERE id=%s;
+                INSERT INTO dir_cache
+                (id, lut, data)
+                SELECT %s, %s, %s
+                WHERE NOT EXISTS
+                (SELECT id from dir_cache WHERE id=%s)
+                """, [int(current_time), buffer(res_str), str(key), str(key), int(current_time), buffer(res_str), str(key)])
 
-        except Exception, e:
-            db.rollback()
-            self.log.warn('_dir_search: db cache update failed. %s' % e)
-
         # -- set the data in the memcache
         self._cache_set(key, res)
 
Index: tracext/dirauth/db.py
===================================================================
--- tracext/dirauth/db.py	(revision 12970)
+++ tracext/dirauth/db.py	(working copy)
@@ -22,7 +22,7 @@
     Table('dir_cache', key=('id'))[
         Column('id', type='varchar(32)'),
         Column('lut', type='int'),
-        Column('data', type='blob'),
+        Column('data', type='bytea'),
         Index(['id'])],
 ]
 
