[FIX] ir_sequence: do the FOR UPDATE NO WAIT only in the No-gap sequence.
bzr revid: vmt@openerp.com-20110928114229-1g6r5et5frj26wam
This commit is contained in:
parent
f2c5556b68
commit
eeaa2a7f80
|
@ -153,7 +153,7 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
"""
|
||||
# TODO there is no access rights check on the sequence itself.
|
||||
res = self._select_by_code_or_id(cr, uid, sequence_code_or_id,
|
||||
code_or_id, context)
|
||||
code_or_id, False, context)
|
||||
|
||||
if not res:
|
||||
return False
|
||||
|
@ -164,6 +164,9 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
""" % res['id'])
|
||||
res['number_next'] = cr.fetchone()
|
||||
else:
|
||||
# Read again with FOR UPDATE NO WAIT.
|
||||
res = self._select_by_code_or_id(cr, uid, sequence_code_or_id,
|
||||
code_or_id, True, context)
|
||||
cr.execute("""
|
||||
UPDATE ir_sequence
|
||||
SET number_next=number_next+number_increment
|
||||
|
@ -187,7 +190,8 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
"""
|
||||
return self.get_id(cr, uid, code, 'code', context)
|
||||
|
||||
def _select_by_code_or_id(self, cr, uid, sequence_code_or_id, code_or_id, context=None):
|
||||
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.
|
||||
|
@ -195,6 +199,7 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
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
|
||||
|
@ -203,8 +208,9 @@ class ir_sequence(openerp.osv.osv.osv):
|
|||
AND (company_id in %%s or company_id is NULL)
|
||||
ORDER BY company_id, id
|
||||
LIMIT 1
|
||||
FOR UPDATE NOWAIT
|
||||
""" % code_or_id, (sequence_code_or_id, tuple(company_ids)))
|
||||
%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):
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
# > OPENERP_ADDONS_PATH='../../../addons/trunk' OPENERP_PORT=8069 \
|
||||
# OPENERP_DATABASE=yy PYTHONPATH=../:. unit2 test_ir_sequence
|
||||
import os
|
||||
import psycopg2
|
||||
import time
|
||||
import unittest2
|
||||
import xmlrpclib
|
||||
|
@ -26,7 +27,8 @@ def registry(model):
|
|||
def cursor():
|
||||
return openerp.modules.registry.RegistryManager.get(DB).db.cursor()
|
||||
|
||||
class test_ir_sequence(unittest2.TestCase):
|
||||
class test_ir_sequence_standard(unittest2.TestCase):
|
||||
""" A few tests for a 'Standard' (i.e. PostgreSQL) sequence. """
|
||||
|
||||
def test_ir_sequence_create(self):
|
||||
""" Try to create a sequence object. """
|
||||
|
@ -52,6 +54,76 @@ class test_ir_sequence(unittest2.TestCase):
|
|||
finally:
|
||||
cr.close()
|
||||
|
||||
def test_ir_sequence_draw(self):
|
||||
""" Try to draw a number. """
|
||||
cr = cursor()
|
||||
try:
|
||||
n = registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type', {})
|
||||
assert n
|
||||
cr.commit()
|
||||
finally:
|
||||
cr.close()
|
||||
|
||||
def test_ir_sequence_draw_twice(self):
|
||||
""" Try to draw a number from two transactions. """
|
||||
cr0 = cursor()
|
||||
cr1 = cursor()
|
||||
try:
|
||||
n0 = registry('ir.sequence').get(cr0, ADMIN_USER_ID, 'test_sequence_type', {})
|
||||
assert n0
|
||||
n1 = registry('ir.sequence').get(cr1, ADMIN_USER_ID, 'test_sequence_type', {})
|
||||
assert n1
|
||||
cr0.commit()
|
||||
cr1.commit()
|
||||
finally:
|
||||
cr0.close()
|
||||
cr1.close()
|
||||
|
||||
class test_ir_sequence_no_gap(unittest2.TestCase):
|
||||
""" Copy of the previous tests for a 'No gap' sequence. """
|
||||
|
||||
def test_ir_sequence_create_no_gap(self):
|
||||
""" Try to create a sequence object. """
|
||||
cr = cursor()
|
||||
try:
|
||||
d = dict(code='test_sequence_type_2', name='Test sequence type')
|
||||
c = registry('ir.sequence.type').create(cr, ADMIN_USER_ID, d, {})
|
||||
assert c
|
||||
d = dict(code='test_sequence_type_2', name='Test sequence',
|
||||
implementation='no_gap')
|
||||
c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
|
||||
assert c
|
||||
cr.commit()
|
||||
finally:
|
||||
cr.close()
|
||||
|
||||
def test_ir_sequence_draw_no_gap(self):
|
||||
""" Try to draw a number. """
|
||||
cr = cursor()
|
||||
try:
|
||||
n = registry('ir.sequence').get(cr, ADMIN_USER_ID, 'test_sequence_type_2', {})
|
||||
assert n
|
||||
cr.commit()
|
||||
finally:
|
||||
cr.close()
|
||||
|
||||
def test_ir_sequence_draw_twice_no_gap(self):
|
||||
""" Try to draw a number from two transactions.
|
||||
This is expected to not work.
|
||||
"""
|
||||
cr0 = cursor()
|
||||
cr1 = cursor()
|
||||
try:
|
||||
msg_re = '^could not obtain lock on row in relation "ir_sequence"$'
|
||||
with self.assertRaisesRegexp(psycopg2.OperationalError, msg_re):
|
||||
n0 = registry('ir.sequence').get(cr0, ADMIN_USER_ID, 'test_sequence_type_2', {})
|
||||
assert n0
|
||||
n1 = registry('ir.sequence').get(cr1, ADMIN_USER_ID, 'test_sequence_type_2', {})
|
||||
finally:
|
||||
cr0.close()
|
||||
cr1.close()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest2.main()
|
||||
|
||||
|
|
Loading…
Reference in New Issue