Exemplo n.º 1
0
 def rollback(self):
     from trytond.cache import Cache
     for cache in self.cache.values():
         cache.clear()
     for datamanager in self._datamanagers:
         datamanager.tpc_abort(self)
     Cache.rollback(self)
     self.connection.rollback()
Exemplo n.º 2
0
def load_module_graph(graph, pool, update=None, lang=None):
    # Prevent to import backend when importing module
    from trytond.cache import Cache
    from trytond.ir.lang import get_parent_language

    if lang is None:
        lang = [config.get('database', 'language')]
    if update is None:
        update = []
    modules_todo = []
    models_to_update_history = set()

    # Load also parent languages
    lang = set(lang)
    for code in list(lang):
        while code:
            lang.add(code)
            code = get_parent_language(code)

    transaction = Transaction()
    with transaction.connection.cursor() as cursor:
        modules = [x.name for x in graph]
        module2state = dict()
        for sub_modules in tools.grouped_slice(modules):
            cursor.execute(
                *ir_module.select(ir_module.name,
                                  ir_module.state,
                                  where=ir_module.name.in_(list(sub_modules))))
            module2state.update(cursor)
        modules = set(modules)

        for node in graph:
            module = node.name
            if module not in MODULES:
                continue
            logger.info(module)
            classes = pool.fill(module, modules)
            if update:
                pool.setup(classes)
            package_state = module2state.get(module, 'not activated')
            if (is_module_to_install(module, update) or
                (update and package_state in ('to activate', 'to upgrade'))):
                if package_state not in ('to activate', 'to upgrade'):
                    if package_state == 'activated':
                        package_state = 'to upgrade'
                    elif package_state != 'to remove':
                        package_state = 'to activate'
                for child in node:
                    module2state[child.name] = package_state
                for type in list(classes.keys()):
                    for cls in classes[type]:
                        logger.info('%s:register %s', module, cls.__name__)
                        cls.__register__(module)
                for model in classes['model']:
                    if hasattr(model, '_history'):
                        models_to_update_history.add(model.__name__)

                # Instanciate a new parser for the module
                tryton_parser = convert.TrytondXmlHandler(
                    pool, module, package_state, modules, lang)

                for filename in node.info.get('xml', []):
                    filename = filename.replace('/', os.sep)
                    logger.info('%s:loading %s', module, filename)
                    # Feed the parser with xml content:
                    with tools.file_open(OPJ(module, filename), 'rb') as fp:
                        tryton_parser.parse_xmlstream(fp)

                modules_todo.append((module, list(tryton_parser.to_delete)))

                load_translations(pool, node, lang)

                if package_state == 'to remove':
                    continue
                cursor.execute(*ir_module.select(
                    ir_module.id, where=(ir_module.name == module)))
                try:
                    module_id, = cursor.fetchone()
                    cursor.execute(
                        *ir_module.update([ir_module.state], ['activated'],
                                          where=(ir_module.id == module_id)))
                except TypeError:
                    cursor.execute(*ir_module.insert([
                        ir_module.create_uid, ir_module.create_date,
                        ir_module.name, ir_module.state
                    ], [
                        [0, CurrentTimestamp(), module, 'activated'],
                    ]))
                module2state[module] = 'activated'

            # Avoid clearing cache to prevent dead lock on ir.cache table
            Cache.rollback(transaction)
            transaction.commit()
            # Clear transaction cache to update default_factory
            transaction.cache.clear()

        if not update:
            pool.setup()
        else:
            # Remove unknown models and fields
            Model = pool.get('ir.model')
            Model.clean()
            ModelField = pool.get('ir.model.field')
            ModelField.clean()
            transaction.commit()

        pool.setup_mixin(modules)

        for model_name in models_to_update_history:
            model = pool.get(model_name)
            if model._history:
                logger.info('history:update %s', model.__name__)
                model._update_history_table()

        # Vacuum :
        while modules_todo:
            (module, to_delete) = modules_todo.pop()
            convert.post_import(pool, module, to_delete)

        # Ensure cache is clear for other instances
        Cache.clear_all()
        Cache.refresh_pool(transaction)
    logger.info('all modules loaded')
Exemplo n.º 3
0
def load_module_graph(graph, pool, update=None, lang=None):
    from trytond.ir.lang import get_parent_language

    if lang is None:
        lang = [config.get('database', 'language')]
    if update is None:
        update = []
    modules_todo = []
    models_to_update_history = set()

    # Load also parent languages
    lang = set(lang)
    for code in list(lang):
        while code:
            lang.add(code)
            code = get_parent_language(code)

    transaction = Transaction()
    with transaction.connection.cursor() as cursor:
        modules = [x.name for x in graph]
        module2state = dict()
        for sub_modules in tools.grouped_slice(modules):
            cursor.execute(
                *ir_module.select(ir_module.name,
                                  ir_module.state,
                                  where=ir_module.name.in_(list(sub_modules))))
            module2state.update(cursor.fetchall())
        modules = set(modules)

        for node in graph:
            module = node.name
            if module not in MODULES:
                continue
            logger.info(module)
            classes = pool.fill(module, modules)
            if update:
                pool.setup(classes)
                pool.post_init(module)
            package_state = module2state.get(module, 'not activated')
            if (is_module_to_install(module, update) or
                (update and package_state in ('to activate', 'to upgrade'))):
                if package_state not in ('to activate', 'to upgrade'):
                    if package_state == 'activated':
                        package_state = 'to upgrade'
                    elif package_state != 'to remove':
                        package_state = 'to activate'
                for child in node:
                    module2state[child.name] = package_state
                for type in list(classes.keys()):
                    for cls in classes[type]:
                        logger.info('%s:register %s', module, cls.__name__)
                        cls.__register__(module)
                for model in classes['model']:
                    if hasattr(model, '_history'):
                        models_to_update_history.add(model.__name__)

                # Instanciate a new parser for the module
                tryton_parser = convert.TrytondXmlHandler(
                    pool, module, package_state, modules)

                for filename in node.info.get('xml', []):
                    filename = filename.replace('/', os.sep)
                    logger.info('%s:loading %s', module, filename)
                    # Feed the parser with xml content:
                    with tools.file_open(OPJ(module, filename), 'rb') as fp:
                        tryton_parser.parse_xmlstream(fp)

                modules_todo.append((module, list(tryton_parser.to_delete)))

                localedir = '%s/%s' % (node.info['directory'], 'locale')
                lang2filenames = defaultdict(list)
                for filename in itertools.chain(
                        iglob('%s/*.po' % localedir),
                        iglob('%s/override/*.po' % localedir)):
                    filename = filename.replace('/', os.sep)
                    lang2 = os.path.splitext(os.path.basename(filename))[0]
                    if lang2 not in lang:
                        continue
                    lang2filenames[lang2].append(filename)
                base_path_position = len(node.info['directory']) + 1
                for language, files in lang2filenames.items():
                    filenames = [f[base_path_position:] for f in files]
                    logger.info('%s:loading %s', module, ','.join(filenames))
                    Translation = pool.get('ir.translation')
                    Translation.translation_import(language, module, files)

                if package_state == 'to remove':
                    continue
                cursor.execute(*ir_module.select(
                    ir_module.id, where=(ir_module.name == module)))
                try:
                    module_id, = cursor.fetchone()
                    cursor.execute(
                        *ir_module.update([ir_module.state], ['activated'],
                                          where=(ir_module.id == module_id)))
                except TypeError:
                    cursor.execute(*ir_module.insert([
                        ir_module.create_uid, ir_module.create_date,
                        ir_module.name, ir_module.state
                    ], [
                        [0, CurrentTimestamp(), module, 'activated'],
                    ]))
                module2state[module] = 'activated'

            # Avoid clearing cache to prevent dead lock on ir.cache table
            Cache.rollback(transaction)
            transaction.commit()

        if not update:
            pool.setup()
        else:
            # Remove unknown models and fields
            Model = pool.get('ir.model')
            Model.clean()
            ModelField = pool.get('ir.model.field')
            ModelField.clean()
            transaction.commit()
        # JCA: Add update parameter to post init hooks
        pool.post_init(None)

        pool.setup_mixin(modules)

        for model_name in models_to_update_history:
            model = pool.get(model_name)
            if model._history:
                logger.info('history:update %s', model.__name__)
                model._update_history_table()

        # Vacuum :
        while modules_todo:
            (module, to_delete) = modules_todo.pop()
            convert.post_import(pool, module, to_delete)
    logger.info('all modules loaded')