changeset 262:7b821432d012

fixed node auto-create feature
author souliane <souliane@mailoo.org>
date Fri, 06 Dec 2013 00:37:08 +0100
parents 65d4fed44edf
children 9dfd3890e646
files sat_pubsub/pgsql_storage.py
diffstat 1 files changed, 22 insertions(+), 10 deletions(-) [+]
line wrap: on
line diff
--- a/sat_pubsub/pgsql_storage.py	Mon Jun 17 01:14:31 2013 +0200
+++ b/sat_pubsub/pgsql_storage.py	Fri Dec 06 00:37:08 2013 +0100
@@ -52,7 +52,7 @@
 
 """
 
-import copy
+import copy, logging
 
 from zope.interface import implements
 
@@ -63,6 +63,7 @@
 from wokkel.pubsub import Subscription
 
 from sat_pubsub import error, iidavoll, const
+import psycopg2
 
 class Storage:
 
@@ -171,8 +172,19 @@
                        (owner,))
 
         if not cursor.fetchone():
-            cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""",
-                           (owner,))
+            # XXX: we can NOT rely on the previous query! Commit is needed now because
+            # if the entry exists the next query will leave the database in a corrupted
+            # state: the solution is to rollback. I tried with other methods like
+            # "WHERE NOT EXISTS" but none of them worked, so the following solution
+            # looks like the sole - unless you have auto-commit on. More info
+            # about this issue: http://cssmay.com/question/tag/tag-psycopg2
+            cursor._connection.commit()
+            try:
+                cursor.execute("""INSERT INTO entities (jid) VALUES (%s)""",
+                               (owner,))
+            except psycopg2.IntegrityError as e:
+                cursor._connection.rollback()
+                logging.warning("during node creation: %s" % e.message)
 
         cursor.execute("""INSERT INTO affiliations
                           (node_id, entity_id, affiliation)
@@ -531,7 +543,7 @@
     def _storeItem(self, cursor, item_datum, publisher):
         access_model, item_config, item = item_datum
         data = item.toXml()
-        
+
         cursor.execute("""UPDATE items SET date=now(), publisher=%s, data=%s
                           FROM nodes
                           WHERE nodes.node_id = items.node_id AND
@@ -611,7 +623,7 @@
                        INNER  JOIN items USING (node_id)
                        LEFT JOIN item_groups_authorized USING (item_id)
                        WHERE node=%s AND
-                       (items.access_model='open' """ + 
+                       (items.access_model='open' """ +
                        ("or (items.access_model='roster' and groupname in %s)" if authorized_groups else '') +
                        """)
                        ORDER BY date DESC"""]
@@ -622,7 +634,7 @@
         if maxItems:
             query.append("LIMIT %s")
             args.append(maxItems)
-       
+
         cursor.execute(' '.join(query), args)
 
         result = cursor.fetchall()
@@ -634,7 +646,7 @@
                 item_id = data[2]
                 if access_model == 'roster': #TODO: jid access_model
                     cursor.execute('SELECT groupname FROM item_groups_authorized WHERE item_id=%s', (item_id,))
-                    access_list = [r[0] for r in cursor.fetchall()] 
+                    access_list = [r[0] for r in cursor.fetchall()]
                 else:
                     access_list = None
 
@@ -672,7 +684,7 @@
                         item_id = data[2]
                         if access_model == 'roster': #TODO: jid access_model
                             cursor.execute('SELECT groupname FROM item_groups_authorized WHERE item_id=%s', (item_id,))
-                            access_list = [r[0] for r in cursor.fetchall()] 
+                            access_list = [r[0] for r in cursor.fetchall()]
                         else:
                             access_list = None
 
@@ -686,14 +698,14 @@
                            INNER  JOIN items USING (node_id)
                            LEFT JOIN item_groups_authorized USING (item_id)
                            WHERE node=%s AND item=%s AND
-                           (items.access_model='open' """ + 
+                           (items.access_model='open' """ +
                            ("or (items.access_model='roster' and groupname in %s)" if authorized_groups else '') + ")",
                            args)
 
                 result = cursor.fetchone()
                 if result:
                     ret.append(parseXml(result[0]))
-        
+
         return ret
 
     def purge(self):