From 8fb13634ea481779691f230fc825f4b6dbe015ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicolas=20=C3=89vrard?= Date: Fri, 6 Dec 2019 17:33:47 +0100 Subject: [PATCH] Use direct access to backend classes issue8836 review258421002 --- CHANGELOG | 1 + trytond/admin.py | 5 +-- trytond/backend/__init__.py | 43 ++++++++++------------ trytond/backend/postgresql/database.py | 2 +- trytond/bus.py | 3 +- trytond/cache.py | 8 ++-- trytond/ir/cron.py | 4 +- trytond/ir/module.py | 16 +++----- trytond/ir/sequence.py | 2 +- trytond/model/fields/date.py | 6 +-- trytond/model/fields/dict.py | 2 +- trytond/model/fields/field.py | 3 -- trytond/model/fields/numeric.py | 4 +- trytond/model/modelsql.py | 20 ++++------ trytond/modules/__init__.py | 5 +-- trytond/protocols/dispatcher.py | 13 ++----- trytond/protocols/wrappers.py | 3 +- trytond/security.py | 15 +++----- trytond/tests/run-tests.py | 2 +- trytond/tests/test_bus.py | 4 +- trytond/tests/test_cache.py | 2 +- trytond/tests/test_field_char.py | 5 +-- trytond/tests/test_field_dict.py | 17 ++++----- trytond/tests/test_field_multiselection.py | 5 +-- trytond/tests/test_history.py | 6 +-- trytond/tests/test_modelsql.py | 9 ++--- trytond/tests/test_tryton.py | 38 ++++++++----------- trytond/tools/multivalue.py | 3 +- trytond/transaction.py | 7 ++-- trytond/worker.py | 8 ++-- 30 files changed, 107 insertions(+), 154 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a79c991536..a66494e3eb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,4 @@ +* Use direct access to backend classes * Add weasyprint support * Add slugify tool * Add is_secure, host and http_host to url module diff --git a/trytond/admin.py b/trytond/admin.py index a1661afe00..11d08747a2 100644 --- a/trytond/admin.py +++ b/trytond/admin.py @@ -17,12 +17,11 @@ logger = logging.getLogger(__name__) def run(options): - Database = backend.get('Database') main_lang = config.get('database', 'language') init = {} for db_name in options.database_names: init[db_name] = False - database = Database(db_name) + database = backend.Database(db_name) database.connect() if options.update: if not database.test(): @@ -36,7 +35,7 @@ def run(options): if options.update: with Transaction().start(db_name, 0) as transaction,\ transaction.connection.cursor() as cursor: - database = Database(db_name) + database = backend.Database(db_name) database.connect() if not database.test(): raise Exception('"%s" is not a Tryton database.' % db_name) diff --git a/trytond/backend/__init__.py b/trytond/backend/__init__.py index 4df464f19f..80308aa4da 100644 --- a/trytond/backend/__init__.py +++ b/trytond/backend/__init__.py @@ -1,7 +1,6 @@ # This file is part of Tryton. The COPYRIGHT file at the top level of # this repository contains the full copyright notices and license terms. import importlib -import sys import urllib.parse try: import pkg_resources @@ -10,29 +9,27 @@ except ImportError: from trytond.config import config -__all__ = ['name', 'get'] -_database_uri = config.get('database', 'uri', default='') +__all__ = ['name', 'Database', 'DatabaseIntegrityError', 'TableHandler'] -def name(): - return urllib.parse.urlparse(_database_uri).scheme +name = urllib.parse.urlparse(config.get('database', 'uri', default='')).scheme +_modname = 'trytond.backend.%s' % name +try: + _module = importlib.import_module(_modname) +except ImportError: + if not pkg_resources: + raise + for ep in pkg_resources.iter_entry_points('trytond.backend', name): + try: + _module = ep.load() + break + except ImportError: + continue + else: + raise -def get(prop): - db_type = name() - modname = 'trytond.backend.%s' % db_type - try: - module = importlib.import_module(modname) - except ImportError: - if not pkg_resources: - raise - for ep in pkg_resources.iter_entry_points( - 'trytond.backend', db_type): - try: - sys.modules[modname] = module = ep.load() - break - except ImportError: - continue - else: - raise - return getattr(module, prop) +Database = _module.Database +DatabaseIntegrityError = _module.DatabaseIntegrityError +DatabaseOperationalError = _module.DatabaseOperationalError +TableHandler = _module.TableHandler diff --git a/trytond/backend/postgresql/database.py b/trytond/backend/postgresql/database.py index ac78b50dd8..8bf3d9dd8b 100644 --- a/trytond/backend/postgresql/database.py +++ b/trytond/backend/postgresql/database.py @@ -36,7 +36,6 @@ from sql.operators import BinaryOperator from trytond.backend.database import DatabaseInterface, SQLType from trytond.config import config, parse_uri -from trytond.protocols.jsonrpc import JSONDecoder from trytond.tools.gevent import is_gevent_monkey_patched __all__ = ['Database', 'DatabaseIntegrityError', 'DatabaseOperationalError'] @@ -561,6 +560,7 @@ register_adapter(Decimal, lambda value: AsIs(str(value))) def convert_json(value): + from trytond.protocols.jsonrpc import JSONDecoder return json.loads(value, object_hook=JSONDecoder()) register_default_json(loads=convert_json) register_default_jsonb(loads=convert_json) diff --git a/trytond/bus.py b/trytond/bus.py index d46ba28881..07d0484625 100644 --- a/trytond/bus.py +++ b/trytond/bus.py @@ -140,8 +140,7 @@ class LongPollingBus: @classmethod def _listen(cls, database): - Database = backend.get('Database') - db = Database(database) + db = backend.Database(database) if not db.has_channel(): raise NotImplemented diff --git a/trytond/cache.py b/trytond/cache.py index 208c27e1d9..cba8a1b748 100644 --- a/trytond/cache.py +++ b/trytond/cache.py @@ -28,7 +28,7 @@ def _cast(column): __slots__ = () _function = 'DATETIME' - if backend.name() == 'sqlite': + if backend.name == 'sqlite': column = SQLite_DateTime(column) return column @@ -259,8 +259,7 @@ class MemoryCache(BaseCache): with cls._listener_lock: listener = cls._listener.pop(dbname, None) if listener: - Database = backend.get('Database') - database = Database(dbname) + database = backend.Database(dbname) conn = database.get_connection() try: cursor = conn.cursor() @@ -276,8 +275,7 @@ class MemoryCache(BaseCache): @classmethod def _listen(cls, dbname): - Database = backend.get('Database') - database = Database(dbname) + database = backend.Database(dbname) if not database.has_channel(): raise NotImplementedError diff --git a/trytond/ir/cron.py b/trytond/ir/cron.py index 4534408173..8f4fe570fb 100644 --- a/trytond/ir/cron.py +++ b/trytond/ir/cron.py @@ -113,7 +113,6 @@ class Cron(DeactivableMixin, ModelSQL, ModelView): @classmethod def run(cls, db_name): - DatabaseOperationalError = backend.get('DatabaseOperationalError') logger.info('cron started for "%s"', db_name) now = datetime.datetime.now() retry = config.getint('database', 'retry') @@ -136,7 +135,8 @@ class Cron(DeactivableMixin, ModelSQL, ModelView): transaction.commit() except Exception as e: transaction.rollback() - if isinstance(e, DatabaseOperationalError) and count: + if (isinstance(e, backend.DatabaseOperationalError) + and count): continue logger.error('Running cron %s', cron.id, exc_info=True) break diff --git a/trytond/ir/module.py b/trytond/ir/module.py index 39de36bc7b..9aa542c915 100644 --- a/trytond/ir/module.py +++ b/trytond/ir/module.py @@ -103,15 +103,14 @@ class Module(ModelSQL, ModelView): def __register__(cls, module_name): pool = Pool() ModelData = pool.get('ir.model.data') - TableHandler = backend.get('TableHandler') sql_table = cls.__table__() model_data_sql_table = ModelData.__table__() cursor = Transaction().connection.cursor() # Migration from 3.6: remove double module old_table = 'ir_module_module' - if TableHandler.table_exist(old_table): - TableHandler.table_rename(old_table, cls._table) + if backend.TableHandler.table_exist(old_table): + backend.TableHandler.table_rename(old_table, cls._table) super(Module, cls).__register__(module_name) @@ -361,12 +360,10 @@ class ModuleDependency(ModelSQL, ModelView): @classmethod def __register__(cls, module_name): - TableHandler = backend.get('TableHandler') - # Migration from 3.6: remove double module old_table = 'ir_module_module_dependency' - if TableHandler.table_exist(old_table): - TableHandler.table_rename(old_table, cls._table) + if backend.TableHandler.table_exist(old_table): + backend.TableHandler.table_rename(old_table, cls._table) super(ModuleDependency, cls).__register__(module_name) @@ -394,7 +391,6 @@ class ModuleConfigWizardItem(sequence_ordered(), ModelSQL, ModelView): @classmethod def __register__(cls, module_name): - TableHandler = backend.get('TableHandler') cursor = Transaction().connection.cursor() pool = Pool() ModelData = pool.get('ir.model.data') @@ -402,8 +398,8 @@ class ModuleConfigWizardItem(sequence_ordered(), ModelSQL, ModelView): # Migration from 3.6: remove double module old_table = 'ir_module_module_config_wizard_item' - if TableHandler.table_exist(old_table): - TableHandler.table_rename(old_table, cls._table) + if backend.TableHandler.table_exist(old_table): + backend.TableHandler.table_rename(old_table, cls._table) cursor.execute(*model_data.update( columns=[model_data.model], values=[cls.__name__], diff --git a/trytond/ir/sequence.py b/trytond/ir/sequence.py index 5d6a7083a0..3e343fa712 100644 --- a/trytond/ir/sequence.py +++ b/trytond/ir/sequence.py @@ -18,7 +18,7 @@ __all__ = [ 'SequenceType', 'Sequence', 'SequenceStrict', ] -sql_sequence = backend.get('Database').has_sequence() +sql_sequence = backend.Database.has_sequence() class AffixError(ValidationError): diff --git a/trytond/model/fields/date.py b/trytond/model/fields/date.py index 595ffb525f..54597f88b7 100644 --- a/trytond/model/fields/date.py +++ b/trytond/model/fields/date.py @@ -42,7 +42,7 @@ class Date(Field): return super().sql_format(value) def sql_cast(self, expression): - if backend.name() == 'sqlite': + if backend.name == 'sqlite': return SQLite_Date(expression) return super(Date, self).sql_cast(expression) @@ -80,7 +80,7 @@ class Timestamp(FormatMixin, Field): return super().sql_format(value) def sql_cast(self, expression): - if backend.name() == 'sqlite': + if backend.name == 'sqlite': return SQLite_DateTime(expression) return super().sql_cast(expression) @@ -145,7 +145,7 @@ class Time(FormatMixin, Field): return value def sql_cast(self, expression): - if backend.name() == 'sqlite': + if backend.name == 'sqlite': return SQLite_Time(expression) return super(Time, self).sql_cast(expression) diff --git a/trytond/model/fields/dict.py b/trytond/model/fields/dict.py index 37d8575479..58172682c3 100644 --- a/trytond/model/fields/dict.py +++ b/trytond/model/fields/dict.py @@ -69,7 +69,7 @@ class Dict(Field): return column def _domain_value(self, operator, value): - if backend.name() == 'sqlite' and isinstance(value, bool): + if backend.name == 'sqlite' and isinstance(value, bool): # json_extract returns 0 for JSON false and 1 for JSON true value = int(value) if isinstance(value, (Select, CombiningQuery)): diff --git a/trytond/model/fields/field.py b/trytond/model/fields/field.py index 9bd44604d7..f9f1a12739 100644 --- a/trytond/model/fields/field.py +++ b/trytond/model/fields/field.py @@ -8,7 +8,6 @@ from sql import (operators, Column, Literal, Select, CombiningQuery, Null, from sql.conditionals import Coalesce, NullIf from sql.operators import Concat -from trytond import backend from trytond.pyson import PYSON, PYSONEncoder, PYSONDecoder, Eval from trytond.const import OPERATORS from trytond.tools.string_ import StringPartitioned, LazyString @@ -18,8 +17,6 @@ from trytond.cache import LRUDictTransaction from ...rpc import RPC -Database = backend.get('Database') - def domain_validate(value): assert isinstance(value, list), 'domain must be a list' diff --git a/trytond/model/fields/numeric.py b/trytond/model/fields/numeric.py index b9e250cb97..d7d17b6fe2 100644 --- a/trytond/model/fields/numeric.py +++ b/trytond/model/fields/numeric.py @@ -24,7 +24,7 @@ class Numeric(Float): def sql_column(self, table): column = super(Numeric, self).sql_column(table) - db_type = backend.name() + db_type = backend.name if db_type == 'sqlite': # Must be casted as Decimal is stored as bytes column = SQLite_Cast(column, self.sql_type().base) @@ -32,7 +32,7 @@ class Numeric(Float): def _domain_value(self, operator, value): value = super(Numeric, self)._domain_value(operator, value) - db_type = backend.name() + db_type = backend.name if db_type == 'sqlite': if isinstance(value, (Select, CombiningQuery)): return value diff --git a/trytond/model/modelsql.py b/trytond/model/modelsql.py index 0ace0b7fdb..13c0c41e77 100644 --- a/trytond/model/modelsql.py +++ b/trytond/model/modelsql.py @@ -209,13 +209,11 @@ class ModelSQL(ModelStorage): @classmethod def __table_handler__(cls, module_name=None, history=False): - TableHandler = backend.get('TableHandler') - return TableHandler(cls, module_name, history=history) + return backend.TableHandler(cls, module_name, history=history) @classmethod def __register__(cls, module_name): cursor = Transaction().connection.cursor() - TableHandler = backend.get('TableHandler') super(ModelSQL, cls).__register__(module_name) if callable(cls.table_query): @@ -268,8 +266,8 @@ class ModelSQL(ModelStorage): and not callable(ref_model.table_query)): ref = ref_model._table # Create foreign key table if missing - if not TableHandler.table_exist(ref): - TableHandler(ref_model) + if not backend.TableHandler.table_exist(ref): + backend.TableHandler(ref_model) else: ref = None if field_name in ['create_uid', 'write_uid']: @@ -338,7 +336,6 @@ class ModelSQL(ModelStorage): def __raise_integrity_error( cls, exception, values, field_names=None, transaction=None): pool = Pool() - TableHandler = backend.get('TableHandler') if field_names is None: field_names = list(cls._fields.keys()) if transaction is None: @@ -356,7 +353,7 @@ class ModelSQL(ModelStorage): gettext('ir.msg_required_validation_record', **cls.__names__(field_name))) for name, _, error in cls._sql_constraints: - if TableHandler.convert_name(name) in str(exception): + if backend.TableHandler.convert_name(name) in str(exception): raise SQLConstraintError(gettext(error)) # Check foreign key in last because this can raise false positive # if the target is created during the same transaction. @@ -555,7 +552,6 @@ class ModelSQL(ModelStorage): @classmethod @no_table_query def create(cls, vlist): - DatabaseIntegrityError = backend.get('DatabaseIntegrityError') transaction = Transaction() cursor = transaction.connection.cursor() pool = Pool() @@ -626,7 +622,7 @@ class ModelSQL(ModelStorage): [insert_values])) id_new = transaction.database.lastid(cursor) new_ids.append(id_new) - except DatabaseIntegrityError as exception: + except backend.DatabaseIntegrityError as exception: transaction = Transaction() with Transaction().new_transaction(), \ Transaction().set_context(_check_access=False): @@ -929,7 +925,6 @@ class ModelSQL(ModelStorage): @classmethod @no_table_query def write(cls, records, values, *args): - DatabaseIntegrityError = backend.get('DatabaseIntegrityError') transaction = Transaction() cursor = transaction.connection.cursor() pool = Pool() @@ -982,7 +977,7 @@ class ModelSQL(ModelStorage): try: cursor.execute(*table.update(columns, update_values, where=red_sql)) - except DatabaseIntegrityError as exception: + except backend.DatabaseIntegrityError as exception: transaction = Transaction() with Transaction().new_transaction(), \ Transaction().set_context(_check_access=False): @@ -1021,7 +1016,6 @@ class ModelSQL(ModelStorage): @classmethod @no_table_query def delete(cls, records): - DatabaseIntegrityError = backend.get('DatabaseIntegrityError') transaction = Transaction() cursor = transaction.connection.cursor() pool = Pool() @@ -1134,7 +1128,7 @@ class ModelSQL(ModelStorage): try: cursor.execute(*table.delete(where=red_sql)) - except DatabaseIntegrityError as exception: + except backend.DatabaseIntegrityError as exception: transaction = Transaction() with Transaction().new_transaction(): cls.__raise_integrity_error( diff --git a/trytond/modules/__init__.py b/trytond/modules/__init__.py index 11185137d6..2ce35676b7 100644 --- a/trytond/modules/__init__.py +++ b/trytond/modules/__init__.py @@ -350,15 +350,14 @@ def load_modules( def _load_modules(update): global res - TableHandler = backend.get('TableHandler') transaction = Transaction() with transaction.connection.cursor() as cursor: # Migration from 3.6: remove double module old_table = 'ir_module_module' new_table = 'ir_module' - if TableHandler.table_exist(old_table): - TableHandler.table_rename(old_table, new_table) + if backend.TableHandler.table_exist(old_table): + backend.TableHandler.table_rename(old_table, new_table) # Migration from 4.0: rename installed to activated cursor.execute(*ir_module.select(ir_module.name, diff --git a/trytond/protocols/dispatcher.py b/trytond/protocols/dispatcher.py index f4c3fb91f7..f79f6053be 100644 --- a/trytond/protocols/dispatcher.py +++ b/trytond/protocols/dispatcher.py @@ -49,11 +49,9 @@ def rpc(request, database_name): def login(request, database_name, user, parameters, language=None): - Database = backend.get('Database') - DatabaseOperationalError = backend.get('DatabaseOperationalError') try: - Database(database_name).connect() - except DatabaseOperationalError: + backend.Database(database_name).connect() + except backend.DatabaseOperationalError: logger.error('fail to connect to %s', database_name, exc_info=True) abort(HTTPStatus.NOT_FOUND) context = { @@ -95,9 +93,8 @@ def options(request, path): def db_exist(request, database_name): - Database = backend.get('Database') try: - Database(database_name).connect() + backend.Database(database_name).connect() return True except Exception: return False @@ -143,8 +140,6 @@ def help_method(request, pool): @app.auth_required @with_pool def _dispatch(request, pool, *args, **kwargs): - DatabaseOperationalError = backend.get('DatabaseOperationalError') - obj, method = get_object_method(request, pool) if method in obj.__rpc__: rpc = obj.__rpc__[method] @@ -192,7 +187,7 @@ def _dispatch(request, pool, *args, **kwargs): else: result = [rpc.result(meth(i, *c_args, **c_kwargs)) for i in inst] - except DatabaseOperationalError: + except backend.DatabaseOperationalError: if count and not rpc.readonly: transaction.rollback() continue diff --git a/trytond/protocols/wrappers.py b/trytond/protocols/wrappers.py index 5a115bfd33..79a2c44431 100644 --- a/trytond/protocols/wrappers.py +++ b/trytond/protocols/wrappers.py @@ -139,7 +139,6 @@ def with_transaction(readonly=None, user=0, context=None): @wraps(func) def wrapper(request, pool, *args, **kwargs): nonlocal user, context - DatabaseOperationalError = backend.get('DatabaseOperationalError') readonly_ = readonly # can not modify non local if readonly_ is None: if request.method in {'POST', 'PUT', 'DELETE', 'PATCH'}: @@ -162,7 +161,7 @@ def with_transaction(readonly=None, user=0, context=None): context=context) as transaction: try: result = func(request, pool, *args, **kwargs) - except DatabaseOperationalError: + except backend.DatabaseOperationalError: if count and not readonly_: transaction.rollback() continue diff --git a/trytond/security.py b/trytond/security.py index 78a2dee554..35de8e3973 100644 --- a/trytond/security.py +++ b/trytond/security.py @@ -25,7 +25,6 @@ def _get_remote_addr(context): def login(dbname, loginname, parameters, cache=True, context=None): - DatabaseOperationalError = backend.get('DatabaseOperationalError') for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(dbname, 0, context=context) as transaction: pool = _get_pool(dbname) @@ -33,7 +32,7 @@ def login(dbname, loginname, parameters, cache=True, context=None): try: user_id = User.get_login(loginname, parameters) break - except DatabaseOperationalError: + except backend.DatabaseOperationalError: if count: continue raise @@ -58,7 +57,6 @@ def login(dbname, loginname, parameters, cache=True, context=None): def logout(dbname, user, session, context=None): - DatabaseOperationalError = backend.get('DatabaseOperationalError') for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(dbname, 0, context=context): pool = _get_pool(dbname) @@ -66,7 +64,7 @@ def logout(dbname, user, session, context=None): try: name = Session.remove(session) break - except DatabaseOperationalError: + except backend.DatabaseOperationalError: if count: continue raise @@ -79,7 +77,6 @@ def logout(dbname, user, session, context=None): def check(dbname, user, session, context=None): - DatabaseOperationalError = backend.get('DatabaseOperationalError') for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(dbname, user, context=context) as transaction: pool = _get_pool(dbname) @@ -87,7 +84,7 @@ def check(dbname, user, session, context=None): try: find = Session.check(user, session) break - except DatabaseOperationalError: + except backend.DatabaseOperationalError: if count: continue raise @@ -108,7 +105,6 @@ def check(dbname, user, session, context=None): def check_timeout(dbname, user, session, context=None): - DatabaseOperationalError = backend.get('DatabaseOperationalError') for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(dbname, user, context=context) as transaction: pool = _get_pool(dbname) @@ -116,7 +112,7 @@ def check_timeout(dbname, user, session, context=None): try: valid = Session.check_timeout(user, session) break - except DatabaseOperationalError: + except backend.DatabaseOperationalError: if count: continue raise @@ -129,11 +125,10 @@ def check_timeout(dbname, user, session, context=None): def reset(dbname, session, context): - DatabaseOperationalError = backend.get('DatabaseOperationalError') try: with Transaction().start(dbname, 0, context=context): pool = _get_pool(dbname) Session = pool.get('ir.session') Session.reset(session) - except DatabaseOperationalError: + except backend.DatabaseOperationalError: logger.debug('Reset session failed', exc_info=True) diff --git a/trytond/tests/run-tests.py b/trytond/tests/run-tests.py index 0386645ebc..f711bec983 100755 --- a/trytond/tests/run-tests.py +++ b/trytond/tests/run-tests.py @@ -36,7 +36,7 @@ config.update_etc(opt.config) # Import after application is configured from trytond import backend -if backend.name() == 'sqlite': +if backend.name == 'sqlite': database_name = ':memory:' else: database_name = 'test_' + str(int(time.time())) diff --git a/trytond/tests/test_bus.py b/trytond/tests/test_bus.py index f435f46996..ea633bc4e8 100644 --- a/trytond/tests/test_bus.py +++ b/trytond/tests/test_bus.py @@ -107,14 +107,14 @@ class BusTestCase(unittest.TestCase): "Test notify" notify("Test", "Message", user=1) - @unittest.skipIf(backend.name() == 'sqlite', 'SQLite has not channel') + @unittest.skipIf(backend.name == 'sqlite', 'SQLite has not channel') def test_subscribe_nothing(self): "Test subscribe with nothing" response = Bus.subscribe(DB_NAME, ['user:1']) self.assertEqual(response, {'message': None, 'channel': None}) - @unittest.skipIf(backend.name() == 'sqlite', 'SQLite has not channel') + @unittest.skipIf(backend.name == 'sqlite', 'SQLite has not channel') def test_subscribe_message(self): "Test subscribe with message" Bus.subscribe(DB_NAME, ['user:1']) diff --git a/trytond/tests/test_cache.py b/trytond/tests/test_cache.py index 0ec712a116..0064e25468 100644 --- a/trytond/tests/test_cache.py +++ b/trytond/tests/test_cache.py @@ -157,7 +157,7 @@ class MemoryCacheTestCase(unittest.TestCase): self.assertEqual(cache_expire.get('foo'), None) -@unittest.skipIf(backend.name() == 'sqlite', "SQLite has not channel") +@unittest.skipIf(backend.name == 'sqlite', "SQLite has not channel") class MemoryCacheChannelTestCase(MemoryCacheTestCase): "Test Cache with channel" diff --git a/trytond/tests/test_field_char.py b/trytond/tests/test_field_char.py index c751ef6795..2aad8c5bfa 100644 --- a/trytond/tests/test_field_char.py +++ b/trytond/tests/test_field_char.py @@ -514,11 +514,10 @@ class UnaccentedTestCase(unittest.TestCase): @classmethod def _clear_unaccent_cache(cls): - Database = backend.get('Database') - Database._has_unaccent.clear() + backend.Database._has_unaccent.clear() -@unittest.skipUnless(backend.name() == 'postgresql', +@unittest.skipUnless(backend.name == 'postgresql', "unaccent works only on postgresql") class FieldCharUnaccentedTestCase(UnaccentedTestCase): "Test Field Char with unaccented searches" diff --git a/trytond/tests/test_field_dict.py b/trytond/tests/test_field_dict.py index f861b6a7f4..d8c28e46d4 100644 --- a/trytond/tests/test_field_dict.py +++ b/trytond/tests/test_field_dict.py @@ -146,12 +146,11 @@ class FieldDictTestCase(unittest.TestCase): @with_transaction() @unittest.skipIf( - backend.name() != 'postgresql', 'jsonb only supported by postgresql') + backend.name != 'postgresql', 'jsonb only supported by postgresql') def test_create_jsonb(self): "Test create dict as jsonb" connection = Transaction().connection - Database = backend.get('Database') - if Database().get_version(connection) < (9, 2): + if backend.Database().get_version(connection) < (9, 2): return Dict = Pool().get('test.dict_jsonb') @@ -194,12 +193,11 @@ class FieldDictTestCase(unittest.TestCase): @with_transaction() @unittest.skipIf( - backend.name() != 'postgresql', 'jsonb only supported by postgresql') + backend.name != 'postgresql', 'jsonb only supported by postgresql') def test_write_jsonb(self): "Test write dict as jsonb" connection = Transaction().connection - Database = backend.get('Database') - if Database().get_version(connection) < (9, 2): + if backend.Database().get_version(connection) < (9, 2): return Dict = Pool().get('test.dict_jsonb') @@ -690,12 +688,11 @@ class FieldDictTestCase(unittest.TestCase): @with_transaction() @unittest.skipIf( - backend.name() != 'postgresql', 'jsonb only supported by postgresql') + backend.name != 'postgresql', 'jsonb only supported by postgresql') def test_search_element_jsonb(self): "Test search dict element on jsonb" connection = Transaction().connection - Database = backend.get('Database') - if Database().get_version(connection) < (9, 2): + if backend.Database().get_version(connection) < (9, 2): return pool = Pool() @@ -750,7 +747,7 @@ class FieldDictTestCase(unittest.TestCase): dict_.dico_string_keys, {'a': 'A', 'type': "Type"}) -@unittest.skipUnless(backend.name() == 'postgresql', +@unittest.skipUnless(backend.name == 'postgresql', "unaccent works only on postgresql") class FieldDictUnaccentedTestCase(UnaccentedTestCase): "Test Field Dict with unaccented searched" diff --git a/trytond/tests/test_field_multiselection.py b/trytond/tests/test_field_multiselection.py index 76c27466ff..dbd7cad224 100644 --- a/trytond/tests/test_field_multiselection.py +++ b/trytond/tests/test_field_multiselection.py @@ -321,7 +321,7 @@ class FieldMultiSelectionTestCase(unittest.TestCase): @unittest.skipIf( - backend.name() != 'postgresql', 'jsonb only supported by postgresql') + backend.name != 'postgresql', 'jsonb only supported by postgresql') class FieldMultiSelectionJSONBTestCase(FieldMultiSelectionTestCase): @classmethod @@ -333,8 +333,7 @@ class FieldMultiSelectionJSONBTestCase(FieldMultiSelectionTestCase): @with_transaction() def setup_model(cls): connection = Transaction().connection - Database = backend.get('Database') - if Database().get_version(connection) < (9, 2): + if backend.Database().get_version(connection) < (9, 2): return pool = Pool() for model in ['test.multi_selection', 'test.multi_selection_required']: diff --git a/trytond/tests/test_history.py b/trytond/tests/test_history.py index 39cacb49f2..4f5e0c296d 100644 --- a/trytond/tests/test_history.py +++ b/trytond/tests/test_history.py @@ -76,7 +76,7 @@ class HistoryTestCase(unittest.TestCase): with self.assertRaises(AccessError): History.read([history_id], ['value']) - @unittest.skipUnless(backend.name() == 'postgresql', + @unittest.skipUnless(backend.name == 'postgresql', 'CURRENT_TIMESTAMP as transaction_timestamp is specific to postgresql') @with_transaction() def test_read_same_timestamp(self): @@ -218,7 +218,7 @@ class HistoryTestCase(unittest.TestCase): history = History(history_id) self.assertEqual(history.value, 1) - @unittest.skipUnless(backend.name() == 'postgresql', + @unittest.skipUnless(backend.name == 'postgresql', 'CURRENT_TIMESTAMP as transaction_timestamp is specific to postgresql') @with_transaction() def test_restore_history_same_timestamp(self): @@ -314,7 +314,7 @@ class HistoryTestCase(unittest.TestCase): self.assertEqual(records, instances) transaction.rollback() - @unittest.skipUnless(backend.name() == 'postgresql', + @unittest.skipUnless(backend.name == 'postgresql', 'CURRENT_TIMESTAMP as transaction_timestamp is specific to postgresql') @with_transaction() def test_ordered_search_same_timestamp(self): diff --git a/trytond/tests/test_modelsql.py b/trytond/tests/test_modelsql.py index 2e73b85f72..423d88dc23 100644 --- a/trytond/tests/test_modelsql.py +++ b/trytond/tests/test_modelsql.py @@ -248,7 +248,7 @@ class ModelSQLTestCase(unittest.TestCase): }], }]) - @unittest.skipIf(backend.name() == 'sqlite', + @unittest.skipIf(backend.name == 'sqlite', 'SQLite not concerned because tryton don\'t set "NOT NULL"' 'constraint: "ALTER TABLE" don\'t support NOT NULL constraint' 'without default value') @@ -289,7 +289,7 @@ class ModelSQLTestCase(unittest.TestCase): timestamp = ModelsqlTimestamp.read([record.id], ['_timestamp'])[0]['_timestamp'] - if backend.name() == 'sqlite': + if backend.name == 'sqlite': # timestamp precision of sqlite is the second time.sleep(1) @@ -491,14 +491,13 @@ class ModelSQLTestCase(unittest.TestCase): with self.assertRaises(SQLConstraintError): Model.create([{'value': 42}, {'value': 42}]) - @unittest.skipIf(backend.name() == 'sqlite', + @unittest.skipIf(backend.name == 'sqlite', 'SQLite does not have lock at table level but on file') @with_transaction() def test_lock(self): "Test lock" pool = Pool() Model = pool.get('test.modelsql.lock') - DatabaseOperationalError = backend.get('DatabaseOperationalError') transaction = Transaction() record_id = Model.create([{}])[0].id transaction.commit() @@ -508,7 +507,7 @@ class ModelSQLTestCase(unittest.TestCase): record.lock() with transaction.new_transaction(): record = Model(record_id) - with self.assertRaises(DatabaseOperationalError): + with self.assertRaises(backend.DatabaseOperationalError): record.lock() diff --git a/trytond/tests/test_tryton.py b/trytond/tests/test_tryton.py index 39333a670b..9301ca6850 100644 --- a/trytond/tests/test_tryton.py +++ b/trytond/tests/test_tryton.py @@ -86,12 +86,11 @@ def activate_module(modules): def restore_db_cache(name): result = False if DB_CACHE: - backend_name = backend.name() - cache_file = _db_cache_file(DB_CACHE, name, backend_name) + cache_file = _db_cache_file(DB_CACHE, name) if os.path.exists(cache_file): - if backend_name == 'sqlite': + if backend.name == 'sqlite': result = _sqlite_copy(cache_file, restore=True) - elif backend_name == 'postgresql': + elif backend.name == 'postgresql': result = _pg_restore(cache_file) if result: Pool(DB_NAME).init() @@ -102,17 +101,16 @@ def backup_db_cache(name): if DB_CACHE: if not os.path.exists(DB_CACHE): os.makedirs(DB_CACHE) - backend_name = backend.name() - cache_file = _db_cache_file(DB_CACHE, name, backend_name) + cache_file = _db_cache_file(DB_CACHE, name) if not os.path.exists(cache_file): - if backend_name == 'sqlite': + if backend.name == 'sqlite': _sqlite_copy(cache_file) - elif backend_name == 'postgresql': + elif backend.name == 'postgresql': _pg_dump(cache_file) -def _db_cache_file(path, name, backend_name): - return os.path.join(path, '%s-%s.dump' % (name, backend_name)) +def _db_cache_file(path, name): + return os.path.join(path, '%s-%s.dump' % (name, backend.name)) def _sqlite_copy(file_, restore=False): @@ -164,7 +162,7 @@ def _pg_restore(cache_file): return not subprocess.call(cmd, env=env) except OSError: cache_name, _ = os.path.splitext(os.path.basename(cache_file)) - cache_name = backend.get('TableHandler').convert_name(cache_name) + cache_name = backend.TableHandler.convert_name(cache_name) with Transaction().start( None, 0, close=True, autocommit=True) as transaction: transaction.database.drop(transaction.connection, DB_NAME) @@ -182,9 +180,9 @@ def _pg_dump(cache_file): return not subprocess.call(cmd, env=env) except OSError: cache_name, _ = os.path.splitext(os.path.basename(cache_file)) - cache_name = backend.get('TableHandler').convert_name(cache_name) + cache_name = backend.TableHandler.convert_name(cache_name) # Ensure any connection is left open - backend.get('Database')(DB_NAME).close() + backend.Database(DB_NAME).close() with Transaction().start( None, 0, close=True, autocommit=True) as transaction: transaction.database.create( @@ -698,15 +696,13 @@ class ModuleTestCase(unittest.TestCase): def db_exist(name=DB_NAME): - Database = backend.get('Database') - database = Database().connect() + database = backend.Database().connect() return name in database.list() def create_db(name=DB_NAME, lang='en'): - Database = backend.get('Database') if not db_exist(name): - database = Database() + database = backend.Database() database.connect() connection = database.get_connection(autocommit=True) try: @@ -714,7 +710,7 @@ def create_db(name=DB_NAME, lang='en'): finally: database.put_connection(connection, True) - database = Database(name) + database = backend.Database(name) connection = database.get_connection() try: with connection.cursor() as cursor: @@ -744,8 +740,7 @@ def create_db(name=DB_NAME, lang='en'): def drop_db(name=DB_NAME): if db_exist(name): - Database = backend.get('Database') - database = Database(name) + database = backend.Database(name) database.close() with Transaction().start( @@ -774,12 +769,11 @@ doctest_checker = doctest.OutputChecker() class TestSuite(unittest.TestSuite): def run(self, *args, **kwargs): - DatabaseOperationalError = backend.get('DatabaseOperationalError') while True: try: exist = db_exist() break - except DatabaseOperationalError as err: + except backend.DatabaseOperationalError as err: # Retry on connection error sys.stderr.write(str(err)) time.sleep(1) diff --git a/trytond/tools/multivalue.py b/trytond/tools/multivalue.py index 3a201daf24..3e1d0d2e1f 100644 --- a/trytond/tools/multivalue.py +++ b/trytond/tools/multivalue.py @@ -17,8 +17,7 @@ def migrate_property( pool = Pool() Field = pool.get('ir.model.field') Model = pool.get('ir.model') - TableHandler = backend.get('TableHandler') - if not TableHandler.table_exist('ir_property'): + if not backend.TableHandler.table_exist('ir_property'): return cursor = Transaction().connection.cursor() field = Field.__table__() diff --git a/trytond/transaction.py b/trytond/transaction.py index 27d79424d4..a2ba6ed812 100644 --- a/trytond/transaction.py +++ b/trytond/transaction.py @@ -91,7 +91,6 @@ class Transaction(object): ''' Start transaction ''' - Database = backend.get('Database') assert self.user is None assert self.database is None assert self.close is None @@ -101,10 +100,10 @@ class Transaction(object): # but it may be also before transactions started before self.started_at = self.monotonic_time() if not database_name: - database = Database().connect() + database = backend.Database().connect() else: - database = Database(database_name).connect() - Flavor.set(Database.flavor) + database = backend.Database(database_name).connect() + Flavor.set(backend.Database.flavor) self.connection = database.get_connection(readonly=readonly, autocommit=autocommit) self.user = user diff --git a/trytond/worker.py b/trytond/worker.py index b34a67565f..1524594358 100644 --- a/trytond/worker.py +++ b/trytond/worker.py @@ -15,13 +15,11 @@ from trytond.transaction import Transaction __all__ = ['work'] logger = logging.getLogger(__name__) -Database = backend.get('Database') -DatabaseOperationalError = backend.get('DatabaseOperationalError') class Queue(object): def __init__(self, pool, mpool): - self.database = Database(pool.database_name).connect() + self.database = backend.Database(pool.database_name).connect() self.connection = self.database.get_connection(autocommit=True) self.pool = pool self.mpool = mpool @@ -44,7 +42,7 @@ class TaskList(list): def work(options): - Flavor.set(Database.flavor) + Flavor.set(backend.Database.flavor) if not config.getboolean('queue', 'worker', default=False): return try: @@ -113,7 +111,7 @@ def run_task(pool, task_id): break task.run() break - except DatabaseOperationalError: + except backend.DatabaseOperationalError: if count: transaction.rollback() continue