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
