Exemple #1
0
 def _default_values(self):
     """Return the values not stored.
     By default, the value of a field is its internal representation except:
         - for Many2One and One2One field: the id
         - for Reference field: the string model,id
         - for Many2Many: the list of ids
         - for One2Many: the list of `_default_values`
     """
     values = {}
     # JCA : preload rec names if in called from _changed_values
     add_rec_names = ServerContext().get('_default_rec_names', False)
     if self._values:
         for fname, value in self._values._items():
             field = self._fields[fname]
             rec_name = None
             if field._type in ('many2one', 'one2one', 'reference'):
                 if value:
                     if add_rec_names:
                         rec_name = getattr(value, 'rec_name', '')
                     if field._type == 'reference':
                         value = str(value)
                     else:
                         value = value.id
             elif field._type in ('one2many', 'many2many'):
                 if field._type == 'one2many':
                     value = [r._default_values for r in value]
                 else:
                     value = [r.id for r in value]
             values[fname] = value
             if rec_name is not None:
                 values['%s.' % fname] = {'rec_name': rec_name}
     return values
Exemple #2
0
    def init(self, update=None, lang=None, activatedeps=False):
        '''
        Init pool
        Set update to proceed to update
        lang is a list of language code to be updated
        '''
        # ABDC: inter-workers communication
        from trytond import iwc
        with self._lock:
            # ABDC: inter-workers communication
            iwc.start(self.database_name)
            if not self._started:
                self.start()

        with self._locks[self.database_name]:
            # Don't reset pool if already init and not to update
            if not update and self._pool.get(self.database_name):
                return
            logger.info('init pool for "%s"', self.database_name)
            self._pool.setdefault(self.database_name, {})
            # Clean the _pool before loading modules
            for type in list(self.classes.keys()):
                self._pool[self.database_name][type] = {}
            self._post_init_calls[self.database_name] = []
            with ServerContext().set_context(disable_auto_cache=True):
                restart = not load_modules(self.database_name, self,
                    update=update, lang=lang, activatedeps=activatedeps)
            if restart:
                self.init()
            # ABDC: inter-workers communication
            if update:
                iwc.broadcast_init_pool(self.database_name)
Exemple #3
0
    def init(self, update=None, lang=None, activatedeps=False):
        '''
        Init pool
        Set update to proceed to update
        lang is a list of language code to be updated
        '''
        with self._lock:
            if not self._started:
                self.start()

        with self._locks[self.database_name]:
            # Don't reset pool if already init and not to update
            if not update and self._pool.get(self.database_name):
                return
            logger.info('init pool for "%s"', self.database_name)
            self._pool.setdefault(self.database_name, {})
            self._modules = []
            # Clean the _pool before loading modules
            for type in self.classes.keys():
                self._pool[self.database_name][type] = {}
            self._post_init_calls[self.database_name] = []
            try:
                with ServerContext().set_context(disable_auto_cache=True):
                    restart = not load_modules(self.database_name,
                                               self,
                                               update=update,
                                               lang=lang,
                                               activatedeps=activatedeps)
            except Exception:
                del self._pool[self.database_name]
                self._modules = None
                raise
            if restart:
                self.init()
    def test_server_context(self):
        with ServerContext().set_context(a=1):
            self.assertEqual(ServerContext().context.get('a'), 1)
            self.assertEqual(ServerContext().context.get('b', 10), 10)
            self.assertEqual(ServerContext().get('a'), 1)
            self.assertEqual(ServerContext().get('b', 10), 10)

            with ServerContext().set_context(a=10):
                self.assertEqual(ServerContext().context.get('a'), 10)
            self.assertEqual(ServerContext().context.get('a'), 1)

            with ServerContext().set_context(c=10):
                self.assertEqual(ServerContext().context.get('a'), 1)
                self.assertEqual(ServerContext().context.get('c'), 10)
            self.assertEqual(ServerContext().context.get('c', 1), 1)

            self.assertEqual(ServerContext().context, {'a': 1})
        self.assertEqual(ServerContext().context, {})
Exemple #5
0
 def _changed_values(self):
     """Return the values changed since the instantiation.
     By default, the value of a field is its internal representation except:
         - for Many2One and One2One field: the id.
         - for Reference field: the string model,id
         - for Many2Many: the list of ids
         - for One2Many: a dictionary composed of three keys:
             - add: a list of tuple, the first element is the index where
               the new line is added, the second element is
               `_default_values`
             - update: a list of dictionary of `_changed_values` including
               the `id`
             - remove: a list of ids
     """
     from .modelstorage import ModelStorage
     changed = {}
     init_values = self._init_values or {}
     if not self._values:
         return changed
     for fname, value in self._values.iteritems():
         field = self._fields[fname]
         # Always test key presence in case value is None
         if (fname in init_values and value == init_values[fname]
                 and field._type != 'one2many'):
             continue
         if field._type in ('many2one', 'one2one', 'reference'):
             if value:
                 if value.id is None or value.id < 0:
                     # Don't consider temporary instance as a change
                     continue
                 if isinstance(value, ModelStorage):
                     changed['%s.rec_name' % fname] = value.rec_name
                 if field._type == 'reference':
                     value = str(value)
                 else:
                     value = value.id
         elif field._type == 'one2many':
             targets = value
             init_targets = list(init_values.get(fname, []))
             value = collections.defaultdict(list)
             value['remove'] = [t.id for t in init_targets if t.id]
             for i, target in enumerate(targets):
                 if target.id in value['remove']:
                     value['remove'].remove(target.id)
                     target_changed = target._changed_values
                     if target_changed:
                         target_changed['id'] = target.id
                         value['update'].append(target_changed)
                 else:
                     # JACK: redmine issue #5873
                     # automatically get a one2Many rec_name
                     # to limit number of requests
                     with ServerContext().set_context(
                             _default_rec_names=True):
                         if isinstance(target, ModelView):
                             # Ensure initial values are returned because
                             # target was instantiated on server side.
                             target_init_values = target._init_values
                             target._init_values = None
                             try:
                                 added_values = target._changed_values
                             finally:
                                 target._init_values = target_init_values
                         else:
                             added_values = target._default_values
                         value['add'].append((i, added_values))
             if not value['remove']:
                 del value['remove']
             if not value:
                 continue
             value = dict(value)
         elif field._type == 'many2many':
             value = [r.id for r in value]
         changed[fname] = value
     return changed
Exemple #6
0
 def _changed_values(self):
     """Return the values changed since the instantiation.
     By default, the value of a field is its internal representation except:
         - for Many2One and One2One field: the id.
         - for Reference field: the string model,id
         - for Many2Many: the list of ids
         - for One2Many: a dictionary composed of three keys:
             - add: a list of tuple, the first element is the index where
               the new line is added, the second element is
               `_default_values`
             - update: a list of dictionary of `_changed_values` including
               the `id`
             - remove: a list of ids
     """
     from .modelstorage import ModelStorage
     changed = {}
     init_values = self._init_values or {}
     if not self._values:
         return changed
     init_record = self.__class__(self.id)
     for fname, value in self._values.items():
         field = self._fields[fname]
         # Always test key presence in case value is None
         if (fname in init_values
                 and value == init_values[fname]
                 and field._type != 'one2many'):
             continue
         if field._type in ('many2one', 'one2one', 'reference'):
             if value:
                 if isinstance(value, ModelStorage):
                     try:
                         changed['%s.' % fname] = {
                             'rec_name': value.rec_name,
                             }
                     except AttributeError:
                         pass
                 if value.id is None:
                     # Don't consider temporary instance as a change
                     continue
                 if field._type == 'reference':
                     value = str(value)
                 else:
                     value = value.id
         elif field._type in ['one2many', 'many2many']:
             targets = value
             if fname in init_values:
                 init_targets = init_values.get(fname)
             else:
                 init_targets = getattr(init_record, fname, [])
             value = collections.defaultdict(list)
             previous = [t.id for t in init_targets if t.id]
             for i, target in enumerate(targets):
                 if (field._type == 'one2many'
                         and field.field
                         and target._values):
                     t_values = target._values.copy()
                     # Don't look at reverse field
                     target._values.pop(field.field, None)
                 else:
                     t_values = None
                 try:
                     if target.id in previous:
                         previous.remove(target.id)
                         if isinstance(target, ModelView):
                             target_changed = target._changed_values
                             if target_changed:
                                 target_changed['id'] = target.id
                                 value['update'].append(target_changed)
                     else:
                         # JACK: redmine issue #5873
                         # automatically get a one2Many rec_name
                         # to limit number of requests
                         with ServerContext().set_context(
                                 _default_rec_names=True):
                             if isinstance(target, ModelView):
                                 # Ensure initial values are returned because
                                 # target was instantiated on server side.
                                 target_init_values = target._init_values
                                 target._init_values = None
                                 try:
                                     added_values = target._changed_values
                                 finally:
                                     target._init_values = target_init_values
                             else:
                                 added_values = target._default_values
                             added_values['id'] = target.id
                             value['add'].append((i, added_values))
                 finally:
                     if t_values:
                         target._values = t_values
             if previous:
                 to_delete, to_remove = [], []
                 deleted = removed = None
                 if self._deleted:
                     deleted = self._deleted[fname]
                 if self._removed:
                     removed = self._removed[fname]
                 for id_ in previous:
                     if deleted and id_ in deleted:
                         to_delete.append(id_)
                     elif removed and id_ in removed:
                         to_remove.append(id_)
                     elif field._type == 'one2many':
                         to_delete.append(id_)
                     else:
                         to_remove.append(id_)
                 if to_delete:
                     value['delete'] = to_delete
                 if to_remove:
                     value['remove'] = to_remove
             if not value:
                 continue
             value = dict(value)
         changed[fname] = value
     return changed