[Erp5-report] r13704 - /erp5/trunk/products/ZMySQLDA/db.py

nobody at svn.erp5.org nobody at svn.erp5.org
Tue Mar 27 13:19:09 CEST 2007


Author: vincent
Date: Tue Mar 27 13:19:08 2007
New Revision: 13704

URL: http://svn.erp5.org?rev=13704&view=rev
Log:
Implement a method to reconnect automaticaly under some conditions.
Use the new method everywhere instead of directly calling database's query method.
Add a "ping" query at request begining to offer transactionnal use a reconnection opportunity.

Modified:
    erp5/trunk/products/ZMySQLDA/db.py

Modified: erp5/trunk/products/ZMySQLDA/db.py
URL: http://svn.erp5.org/erp5/trunk/products/ZMySQLDA/db.py?rev=13704&r1=13703&r2=13704&view=diff
==============================================================================
--- erp5/trunk/products/ZMySQLDA/db.py (original)
+++ erp5/trunk/products/ZMySQLDA/db.py Tue Mar 27 13:19:08 2007
@@ -270,9 +270,7 @@
                _care=('TABLE', 'VIEW')):
         r=[]
         a=r.append
-        db = self._getConnection()
-        db.query("SHOW TABLES")
-        result = db.store_result()
+        result = self._query("SHOW TABLES")
         row = result.fetch_row(1)
         while row:
             a({'TABLE_NAME': row[0][0], 'TABLE_TYPE': 'TABLE'})
@@ -282,9 +280,7 @@
     def columns(self, table_name):
         from string import join
         try:
-            db = self._getConnection()
-            db.query('SHOW COLUMNS FROM %s' % table_name)
-            c = db.store_result()
+            c = self._query('SHOW COLUMNS FROM %s' % table_name)
         except:
             return ()
         r=[]
@@ -324,35 +320,50 @@
             r.append(info)
         return r
 
+    def _query(self, query, force_reconnect=False):
+      """
+        Send a to MySQL server.
+        It reconnects automaticaly if needed and the following conditions are
+        met:
+         - It has not just tried to reconnect (ie, this function will not
+           attemp to connect twice per call).
+         - This conection is not transactionnal and has set not MySQL locks,
+           because they are bound to the connection. This check can be
+           overridden by passing force_reconnect with True value.
+      """
+      db = self._getConnection()
+      try:
+        db.query(query)
+      except OperationalError, m:
+        if ((not force_reconnect) and \
+            (self._mysql_lock or self._transactions)) or \
+           m[0] not in hosed_connection:
+          raise
+        # Hm. maybe the db is hosed.  Let's restart it.
+        self._forceReconnection()
+        db.query(query)
+      return db.store_result()
+
     def query(self,query_string, max_rows=1000):
         self._use_TM and self._register()
         desc=None
         result=()
-        db = self._getConnection()
-        try:
-            if 1:
-                for qs in filter(None, map(strip,split(query_string, '\0'))):
-                    qtype = upper(split(qs, None, 1)[0])
-                    if qtype == "SELECT" and max_rows:
-                        qs = "%s LIMIT %d" % (qs,max_rows)
-                        r=0
-                    db.query(qs)
-                    c=db.store_result()
-                    if desc is not None:
-                        if c and (c.describe() != desc):
-                            raise 'Query Error', (
-                                'Multiple select schema are not allowed'
-                                )
-                    if c:
-                        desc=c.describe()
-                        result=c.fetch_row(max_rows)
-                    else:
-                        desc=None
-        except OperationalError, m:
-            if m[0] not in hosed_connection: raise
-            # Hm. maybe the db is hosed.  Let's restart it.
-            self._forceReconnection()
-            return self.query(query_string, max_rows)
+        for qs in filter(None, map(strip,split(query_string, '\0'))):
+            qtype = upper(split(qs, None, 1)[0])
+            if qtype == "SELECT" and max_rows:
+                qs = "%s LIMIT %d" % (qs,max_rows)
+                r=0
+            c = self._query(qs)
+            if desc is not None:
+                if c and (c.describe() != desc):
+                    raise 'Query Error', (
+                        'Multiple select schema are not allowed'
+                        )
+            if c:
+                desc=c.describe()
+                result=c.fetch_row(max_rows)
+            else:
+                desc=None
 
         if desc is None: return (),()
 
@@ -373,13 +384,12 @@
 
     def _begin(self, *ignored):
         try:
-            db = self._getConnection()
+            # Ping the database to reconnect if connection was closed.
+            self._query("SELECT 1", force_reconnect=True)
             if self._transactions:
-                db.query("BEGIN")
-                db.store_result()
+                self._query("BEGIN")
             if self._mysql_lock:
-                db.query("SELECT GET_LOCK('%s',0)" % self._mysql_lock)
-                db.store_result()
+                self._query("SELECT GET_LOCK('%s',0)" % self._mysql_lock)
         except:
             LOG('ZMySQLDA', ERROR, "exception during _begin",
                 error=sys.exc_info())
@@ -390,25 +400,19 @@
         if self._getFinishedOrAborted():
             return
         self._setFinishedOrAborted(True)
-        db = self._getConnection()
         if self._mysql_lock:
-            db.query("SELECT RELEASE_LOCK('%s')" % self._mysql_lock)
-            db.store_result()
+            self._query("SELECT RELEASE_LOCK('%s')" % self._mysql_lock)
         if self._transactions:
-            db.query("COMMIT")
-        db.store_result()
+            self._query("COMMIT")
 
     def _abort(self, *ignored):
         if self._getFinishedOrAborted():
             return
         self._setFinishedOrAborted(True)
-        db = self._getConnection()
         if self._mysql_lock:
-            db.query("SELECT RELEASE_LOCK('%s')" % self._mysql_lock)
-            db.store_result()
+            self._query("SELECT RELEASE_LOCK('%s')" % self._mysql_lock)
         if self._transactions:
-            db.query("ROLLBACK")
-            db.store_result()
+            self._query("ROLLBACK")
         else:
             LOG('ZMySQLDA', ERROR, "aborting when non-transactional")
 




More information about the Erp5-report mailing list