[FIX]ir_sequence: only execute a change on postgresql sequence when really needed and add a field to get an approximation of the current next_number.
bzr revid: csn@openerp.com-20130517124328-kex5katw2tgpgdty
This commit is contained in:
parent
ce5c5557a3
commit
913a7a6e5c
|
@ -54,6 +54,34 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
"""
|
||||
_name = 'ir.sequence'
|
||||
_order = 'name'
|
||||
|
||||
def _get_number_next_actual(self, cr, user, ids, field_name, arg, context=None):
|
||||
'''Return number from ir_sequence row when no_gap implementation,
|
||||
and number from postgres sequence when standard implementation.'''
|
||||
res = dict.fromkeys(ids)
|
||||
for element in self.browse(cr, user, ids, context=context):
|
||||
if element.implementation != 'standard':
|
||||
res[element.id] = element.number_next
|
||||
else:
|
||||
# get number from postgres sequence. Cannot use
|
||||
# currval, because that might give an error when
|
||||
# not having used nextval before.
|
||||
statement = (
|
||||
"SELECT last_value, increment_by, is_called"
|
||||
" FROM ir_sequence_%03d"
|
||||
% element.id)
|
||||
cr.execute(statement)
|
||||
(last_value, increment_by, is_called) = cr.fetchone()
|
||||
if is_called:
|
||||
res[element.id] = last_value + increment_by
|
||||
else:
|
||||
res[element.id] = last_value
|
||||
return res
|
||||
|
||||
def _set_number_next_actual(self, cr, uid, id, name, value, args=None, context=None):
|
||||
return self.write(cr, uid, id, {'number_next': value or 0}, context=context)
|
||||
|
||||
|
||||
_columns = {
|
||||
'name': openerp.osv.fields.char('Name', size=64, required=True),
|
||||
'code': openerp.osv.fields.selection(_code_get, 'Code', size=64),
|
||||
|
@ -67,6 +95,7 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
'prefix': openerp.osv.fields.char('Prefix', size=64, help="Prefix value of the record for the sequence"),
|
||||
'suffix': openerp.osv.fields.char('Suffix', size=64, help="Suffix value of the record for the sequence"),
|
||||
'number_next': openerp.osv.fields.integer('Next Number', required=True, help="Next number of this sequence"),
|
||||
'number_next_actual': openerp.osv.fields.function(_get_number_next_actual, fnct_inv=_set_number_next_actual, type='integer', required=True, string='Actual Next Number', help='Next number that will be used. Number is only informative and can differ from real number'),
|
||||
'number_increment': openerp.osv.fields.integer('Increment Number', required=True, help="The next number of the sequence will be incremented by this number"),
|
||||
'padding' : openerp.osv.fields.integer('Number Padding', required=True, help="OpenERP will automatically adds some '0' on the left of the 'Next Number' to get the required padding size."),
|
||||
'company_id': openerp.osv.fields.many2one('res.company', 'Company'),
|
||||
|
@ -121,7 +150,7 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
# object depends on it.
|
||||
cr.execute("DROP SEQUENCE IF EXISTS %s RESTRICT " % names)
|
||||
|
||||
def _alter_sequence(self, cr, id, number_increment, number_next):
|
||||
def _alter_sequence(self, cr, id, number_increment, number_next=0):
|
||||
""" Alter a PostreSQL sequence.
|
||||
|
||||
There is no access rights check.
|
||||
|
@ -129,9 +158,10 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
if number_increment == 0:
|
||||
raise osv.except_osv(_('Warning!'),_("Increment number must not be zero."))
|
||||
assert isinstance(id, (int, long))
|
||||
cr.execute("""
|
||||
ALTER SEQUENCE ir_sequence_%03d INCREMENT BY %%s RESTART WITH %%s
|
||||
""" % id, (number_increment, number_next))
|
||||
statement = ("ALTER SEQUENCE ir_sequence_%03d INCREMENT BY %d" % (id, number_increment))
|
||||
if number_next:
|
||||
statement += " RESTART WITH %d" % (number_next, )
|
||||
cr.execute(statement)
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
""" Create a sequence, in implementation == standard a fast gaps-allowed PostgreSQL sequence is used.
|
||||
|
@ -160,7 +190,13 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
n = values.get('number_next', row['number_next'])
|
||||
if row['implementation'] == 'standard':
|
||||
if new_implementation in ('standard', None):
|
||||
self._alter_sequence(cr, row['id'], i, n)
|
||||
# Implementation has NOT changed.
|
||||
# Only change sequence if really requested.
|
||||
if row['number_next'] != n:
|
||||
self._alter_sequence(cr, row['id'], i, n)
|
||||
else:
|
||||
# Just in case only increment changed
|
||||
self._alter_sequence(cr, row['id'], i)
|
||||
else:
|
||||
self._drop_sequence(cr, row['id'])
|
||||
else:
|
||||
|
@ -206,7 +242,6 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
if seq['implementation'] == 'standard':
|
||||
cr.execute("SELECT nextval('ir_sequence_%03d')" % seq['id'])
|
||||
seq['number_next'] = cr.fetchone()
|
||||
cr.execute("UPDATE ir_sequence SET number_next=%s WHERE id=%s ", (seq['number_next'], seq['id'],))
|
||||
else:
|
||||
cr.execute("SELECT number_next FROM ir_sequence WHERE id=%s FOR UPDATE NOWAIT", (seq['id'],))
|
||||
cr.execute("UPDATE ir_sequence SET number_next=number_next+number_increment WHERE id=%s ", (seq['id'],))
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<field name="suffix"/>
|
||||
<field name="padding"/>
|
||||
<field name="number_increment"/>
|
||||
<field name="number_next"/>
|
||||
<field name="number_next_actual"/>
|
||||
<field name="implementation"/>
|
||||
</group>
|
||||
<group col="3" string="Legend (for prefix, suffix)">
|
||||
|
@ -57,7 +57,7 @@
|
|||
<field name="prefix"/>
|
||||
<field name="padding"/>
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
<field name="number_next"/>
|
||||
<field name="number_next_actual"/>
|
||||
<field name="number_increment"/>
|
||||
<field name="implementation"/>
|
||||
</tree>
|
||||
|
|
Loading…
Reference in New Issue