CREATE UNIQUE INDEX ir_sequence_unique_code_company_id_idx
ON ir_sequence (code, (COALESCE(company_id,-1)))""")
- def create(self, cr, uid, values, context=None):
- values = self._add_missing_default_values(cr, uid, values, context)
- go = super(ir_sequence, self).create \
- if values['implementation'] == 'no_gap' else self.create_postgres
- return go(cr, uid, values, context)
+ def _create_sequence(self, cr, id, number_increment, number_next):
+ """ Create a PostreSQL sequence.
+
+ There is no access rights check.
+ """
+ assert isinstance(id, (int, long))
+ sql = "CREATE SEQUENCE ir_sequence_%03d INCREMENT BY %%s START WITH %%s" % id
+ cr.execute(sql, (number_increment, number_next))
+
+ def _drop_sequence(self, cr, ids):
+ """ Drop the PostreSQL sequence if it exists.
+
+ There is no access rights check.
+ """
+
+ ids = ids if isinstance(ids, (list, tuple)) else [ids]
+ assert all(isinstance(i, (int, long)) for i in ids), \
+ "Only ids in (int, long) allowed."
+ names = ','.join('ir_sequence_%03d' % i for i in ids)
- def create_postgres(self, cr, uid, values, context=None):
- """ Create a fast, gaps-allowed PostgreSQL sequence.
+ # RESTRICT is the default; it prevents dropping the sequence if an
+ # object depends on it.
+ cr.execute("DROP SEQUENCE IF EXISTS %s RESTRICT " % names)
+
+ def _alter_sequence(self, cr, id, number_increment, number_next):
+ """ Alter a PostreSQL sequence.
+
+ There is no access rights check.
+ """
+ assert isinstance(id, (int, long))
+ cr.execute("""
+ ALTER SEQUENCE ir_sequence_%03d INCREMENT BY %%s RESTART WITH %%s
+ """ % id, (number_increment, number_next))
- :param values: same argument than for ``create()`` but the keys
- ``number_increment`` and ``number_next`` must be present.
- ``_add_missing_default_values()`` can be used to this effect.
- :return: id of the newly created record
+ def create(self, cr, uid, values, context=None):
+ """ Create a sequence, in implementation == standard a fast gaps-allowed PostgreSQL sequence is used.
"""
- id = super(ir_sequence, self).create(cr, uid, values, context)
- self._create_sequence(cr, id,
- values['number_increment'], values['number_next'])
- return id
+ values = self._add_missing_default_values(cr, uid, values, context)
+ values['id'] = super(ir_sequence, self).create(cr, uid, values, context)
+ if values['implementation'] == 'standard':
+ f = self._create_sequence(cr, values['id'], values['number_increment'], values['number_next'])
+ return values['id']
def unlink(self, cr, uid, ids, context=None):
super(ir_sequence, self).unlink(cr, uid, ids, context)
return True
def write(self, cr, uid, ids, values, context=None):
- ids = ids if isinstance(ids, (list, tuple)) else [ids]
+ if not isinstance(ids, (list, tuple)):
+ ids = [ids]
new_implementation = values.get('implementation')
- rows = self.read(cr, uid, ids, ['implementation',
- 'number_increment', 'number_next'], context)
+ rows = self.read(cr, uid, ids, ['implementation', 'number_increment', 'number_next'], context)
super(ir_sequence, self).write(cr, uid, ids, values, context)
-
+
for row in rows:
# 4 cases: we test the previous impl. against the new one.
if row['implementation'] == 'standard':
return True
def _interpolate(self, s, d):
- return s % d if s else ''
+ if s:
+ return s % d
+ return ''
def _interpolation_dict(self):
t = time.localtime() # Actually, the server is always in UTC.
'sec': time.strftime('%S', t),
}
- def next_by_id(self, cr, uid, sequence_id, context=None):
- """ Draw an interpolated string using the specified sequence."""
- self.check_read(cr, uid)
- res = self._select_by_code_or_id(cr, uid, sequence_id,
- 'id', False, context)
- return self._next(cr, uid, res, context)
-
- def next_by_code(self, cr, uid, sequence_code, context=None):
- """ Draw an interpolated string using the specified sequence."""
- self.check_read(cr, uid)
- res = self._select_by_code_or_id(cr, uid, sequence_code,
- 'code', False, context)
- return self._next(cr, uid, res, context)
-
- def get_id(self, cr, uid, sequence_code_or_id, code_or_id='id', context=None):
- """ Draw an interpolated string using the specified sequence.
-
- The sequence to use is specified by the ``sequence_code_or_id``
- argument, which can be a code or an id (as controlled by the
- ``code_or_id`` argument. This method is deprecated.
- """
- _logger.warning("ir_sequence.get() and ir_sequence.get_id() are deprecated. "
- "Please use ir_sequence.next_by_code() or ir_sequence.next_by_id().")
- if code_or_id == 'id':
- return self.next_by_id(cr, uid, sequence_code_or_id, context)
- else:
- return self.next_by_code(cr, uid, sequence_code_or_id, context)
-
- def get(self, cr, uid, code, context=None):
- """ Draw an interpolated string using the specified sequence.
+ def _select_by_code_or_id(self, cr, uid, sequence_code_or_id, code_or_id, for_update_no_wait, context=None):
+ """ Read a sequence object.
- The sequence to use is specified by its code. This method is
- deprecated.
+ There is no access rights check on the sequence itself.
"""
- return self.get_id(cr, uid, code, 'code', context)
+ assert code_or_id in ('code', 'id')
+ res_company = self.pool.get('res.company')
+ company_ids = res_company.search(cr, uid, [], context=context)
+ sql = """
+ SELECT id, number_next, prefix, suffix, padding, implementation
+ FROM ir_sequence
+ WHERE %s=%%s
+ AND active=true
+ AND (company_id in %%s or company_id is NULL)
+ """ % code_or_id
+ if for_update_no_wait:
+ sql += 'FOR UPDATE NOWAIT'
+ cr.execute(sql, (sequence_code_or_id, tuple(company_ids)))
+ return cr.dictfetchone()
def _next(self, cr, uid, sequence, context=None):
if not sequence:
return False
if sequence['implementation'] == 'standard':
- cr.execute("""
- SELECT nextval('ir_sequence_%03d')
- """ % sequence['id'])
+ cr.execute("SELECT nextval('ir_sequence_%03d')" % sequence['id'])
sequence['number_next'] = cr.fetchone()
else:
# Read again with FOR UPDATE NO WAIT.
- sequence = self._select_by_code_or_id(cr, uid, sequence['id'],
- 'id', True, context)
+ sequence = self._select_by_code_or_id(cr, uid, sequence['id'], 'id', True, context)
cr.execute("""
UPDATE ir_sequence
SET number_next=number_next+number_increment
# TODO what is this case used for ?
return interpolated_prefix + interpolated_suffix
- def _select_by_code_or_id(self, cr, uid, sequence_code_or_id, code_or_id,
- for_update_no_wait, context=None):
- """ Read a sequence object.
-
- There is no access rights check on the sequence itself.
- """
- assert code_or_id in ('code', 'id')
- res_company = self.pool.get('res.company')
- company_ids = res_company.search(cr, uid, [], context=context)
- funw = 'FOR UPDATE NOWAIT' if for_update_no_wait else ''
- cr.execute("""
- SELECT id, number_next, prefix, suffix, padding, implementation
- FROM ir_sequence
- WHERE %s=%%s
- AND active=true
- AND (company_id in %%s or company_id is NULL)
- %s
- """ % (code_or_id, funw),
- (sequence_code_or_id, tuple(company_ids)))
- return cr.dictfetchone()
-
- def _create_sequence(self, cr, id, number_increment, number_next):
- """ Create a PostreSQL sequence.
+ def next_by_id(self, cr, uid, sequence_id, context=None):
+ """ Draw an interpolated string using the specified sequence."""
+ self.check_read(cr, uid)
+ res = self._select_by_code_or_id(cr, uid, sequence_id, 'id', False, context)
+ return self._next(cr, uid, res, context)
- There is no access rights check.
- """
- assert isinstance(id, (int, long))
- cr.execute("""
- CREATE SEQUENCE ir_sequence_%03d INCREMENT BY %%s START WITH %%s
- """ % id, (number_increment, number_next))
+ def next_by_code(self, cr, uid, sequence_code, context=None):
+ """ Draw an interpolated string using the specified sequence."""
+ self.check_read(cr, uid)
+ res = self._select_by_code_or_id(cr, uid, sequence_code, 'code', False, context)
+ return self._next(cr, uid, res, context)
- def _drop_sequence(self, cr, ids):
- """ Drop the PostreSQL sequence if it exists.
+ def get_id(self, cr, uid, sequence_code_or_id, code_or_id='id', context=None):
+ """ Draw an interpolated string using the specified sequence.
- There is no access rights check.
+ The sequence to use is specified by the ``sequence_code_or_id``
+ argument, which can be a code or an id (as controlled by the
+ ``code_or_id`` argument. This method is deprecated.
"""
+ _logger.warning("ir_sequence.get() and ir_sequence.get_id() are deprecated. "
+ "Please use ir_sequence.next_by_code() or ir_sequence.next_by_id().")
+ if code_or_id == 'id':
+ return self.next_by_id(cr, uid, sequence_code_or_id, context)
+ else:
+ return self.next_by_code(cr, uid, sequence_code_or_id, context)
- ids = ids if isinstance(ids, (list, tuple)) else [ids]
- assert all(isinstance(i, (int, long)) for i in ids), \
- "Only ids in (int, long) allowed."
- names = ','.join('ir_sequence_%03d' % i for i in ids)
-
- # RESTRICT is the default; it prevents dropping the sequence if an
- # object depends on it.
- cr.execute("""
- DROP SEQUENCE IF EXISTS %s RESTRICT
- """ % names)
-
- def _alter_sequence(self, cr, id, number_increment, number_next):
- """ Alter a PostreSQL sequence.
+ def get(self, cr, uid, code, context=None):
+ """ Draw an interpolated string using the specified sequence.
- There is no access rights check.
+ The sequence to use is specified by its code. This method is
+ deprecated.
"""
- assert isinstance(id, (int, long))
- cr.execute("""
- ALTER SEQUENCE ir_sequence_%03d INCREMENT BY %%s RESTART WITH %%s
- """ % id, (number_increment, number_next))
+ return self.get_id(cr, uid, code, 'code', context)
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: