Reviewers: ,


Please review this at http://codereview.tryton.org/80005/

Affected files:
  M trytond/backend/database.py
  M trytond/backend/mysql/database.py
  M trytond/backend/postgresql/database.py
  M trytond/backend/sqlite/database.py
  M trytond/protocols/dispatcher.py
  M trytond/transaction.py


Index: trytond/backend/database.py
===================================================================

--- a/trytond/backend/database.py
+++ b/trytond/backend/database.py
@@ -24,7 +24,7 @@
         '''
         raise NotImplementedError

-    def cursor(self, autocommit=False):
+    def cursor(self, autocommit=False, readonly=False):
         '''
         Retreive a cursor on the database


Index: trytond/backend/mysql/database.py
===================================================================

--- a/trytond/backend/mysql/database.py
+++ b/trytond/backend/mysql/database.py
@@ -29,7 +29,7 @@
     def connect(self):
         return self

-    def cursor(self, autocommit=False):
+    def cursor(self, autocommit=False, readonly=False):
         conv = MySQLdb.converters.conversions.copy()
         conv[float] = lambda value, _: repr(value)
         args = {

Index: trytond/backend/postgresql/database.py
===================================================================

--- a/trytond/backend/postgresql/database.py
+++ b/trytond/backend/postgresql/database.py
@@ -61,7 +61,7 @@
         self._connpool = ThreadedConnectionPool(minconn, maxconn, dsn)
         return self

-    def cursor(self, autocommit=False):
+    def cursor(self, autocommit=False, readonly=False):
         if self._connpool is None:
             self.connect()
         conn = self._connpool.getconn()
@@ -69,7 +69,11 @@
             conn.set_isolation_level(ISOLATION_LEVEL_AUTOCOMMIT)
         else:
             conn.set_isolation_level(ISOLATION_LEVEL_SERIALIZABLE)
-        return Cursor(self._connpool, conn, self.database_name)
+        cursor = Cursor(self._connpool, conn, self.database_name)
+        # TODO change for set_session
+        if readonly:
+            cursor.execute('SET TRANSACTION READ ONLY')
+        return cursor

     def close(self):
         if self._connpool is None:

Index: trytond/backend/sqlite/database.py
===================================================================

--- a/trytond/backend/sqlite/database.py
+++ b/trytond/backend/sqlite/database.py
@@ -120,7 +120,7 @@
             self._conn.create_function('replace', 3, replace)
         return self

-    def cursor(self, autocommit=False):
+    def cursor(self, autocommit=False, readonly=False):
         if self._conn is None:
             self.connect()
         if autocommit:

Index: trytond/protocols/dispatcher.py
===================================================================

--- a/trytond/protocols/dispatcher.py
+++ b/trytond/protocols/dispatcher.py
@@ -122,18 +122,25 @@

     user = security.check(database_name, user, session)

-    with Transaction().start(database_name, user) as transaction:
+    Cache.clean(database_name)
+    database_list = Pool.database_list()
+    pool = Pool(database_name)
+    if not database_name in database_list:
+        with Transaction().start(database_name, user,
+                readonly=True) as transaction:
+            pool.init()
+    obj = pool.get(object_name, type=object_type)
+
+    if method not in obj._rpc:
+        raise Exception('UserError', 'Calling method %s on ' \
+                '%s %s is not allowed!' % \
+                (method, object_type, object_name))
+
+    readonly = not obj._rpc[method]
+
+    with Transaction().start(database_name, user,
+            readonly=readonly) as transaction:
         try:
-            Cache.clean(database_name)
-            database_list = Pool.database_list()
-            pool = Pool(database_name)
-            if not database_name in database_list:
-                pool.init()
-            obj = pool.get(object_name, type=object_type)
-            if method not in obj._rpc:
-                raise Exception('UserError', 'Calling method %s on ' \
-                        '%s %s is not allowed!' % \
-                        (method, object_type, object_name))

             if 'context' in kargs:
                 context = kargs.pop('context')
@@ -145,7 +152,7 @@
                 del context['_timestamp']
             transaction.context = context
             res = getattr(obj, method)(*args, **kargs)
-            if obj._rpc[method]:
+            if not readonly:
                 transaction.cursor.commit()
         except Exception, exception:
             if CONFIG['verbose'] or (exception.args \

Index: trytond/transaction.py
===================================================================

--- a/trytond/transaction.py
+++ b/trytond/transaction.py
@@ -63,7 +63,7 @@
     delete = None # TODO check to merge with delete_records
     timestamp = None

-    def start(self, database_name, user, context=None):
+    def start(self, database_name, user, readonly=False, context=None):
         '''
         Start transaction
         '''
@@ -72,7 +72,7 @@
         assert self.context is None
         self.user = user
         database = Database(database_name).connect()
-        self.cursor = database.cursor()
+        self.cursor = database.cursor(readonly=readonly)
         self.context = context or {}
         self.create_records = {}
         self.delete_records = {}



--
[email protected] mailing list

Reply via email to