32 from threading import Lock |
32 from threading import Lock |
33 from datetime import datetime |
33 from datetime import datetime |
34 from base64 import b64decode, b64encode |
34 from base64 import b64decode, b64encode |
35 from contextlib import contextmanager |
35 from contextlib import contextmanager |
36 from os.path import abspath |
36 from os.path import abspath |
|
37 import re |
37 |
38 |
38 from logilab.common.compat import any |
39 from logilab.common.compat import any |
39 from logilab.common.cache import Cache |
40 from logilab.common.cache import Cache |
40 from logilab.common.decorators import cached, clear_cache |
41 from logilab.common.decorators import cached, clear_cache |
41 from logilab.common.configuration import Method |
42 from logilab.common.configuration import Method |
42 from logilab.common.shellutils import getlogin |
43 from logilab.common.shellutils import getlogin |
43 from logilab.database import get_db_helper |
44 from logilab.database import get_db_helper |
44 |
45 |
45 from yams import schema2sql as y2sql |
46 from yams import schema2sql as y2sql |
46 |
47 |
47 from cubicweb import UnknownEid, AuthenticationError, ValidationError, Binary |
48 from cubicweb import UnknownEid, AuthenticationError, ValidationError, Binary, UniqueTogetherError |
48 from cubicweb import transaction as tx, server, neg_role |
49 from cubicweb import transaction as tx, server, neg_role |
49 from cubicweb.schema import VIRTUAL_RTYPES |
50 from cubicweb.schema import VIRTUAL_RTYPES |
50 from cubicweb.cwconfig import CubicWebNoAppConfiguration |
51 from cubicweb.cwconfig import CubicWebNoAppConfiguration |
51 from cubicweb.server import hook |
52 from cubicweb.server import hook |
52 from cubicweb.server.utils import crypt_password, eschema_eid |
53 from cubicweb.server.utils import crypt_password, eschema_eid |
664 session.pool.connection(self.uri).rollback() |
665 session.pool.connection(self.uri).rollback() |
665 if self.repo.config.mode != 'test': |
666 if self.repo.config.mode != 'test': |
666 self.critical('transaction has been rollbacked') |
667 self.critical('transaction has been rollbacked') |
667 except: |
668 except: |
668 pass |
669 pass |
|
670 if ex.__class__.__name__ == 'IntegrityError': |
|
671 # need string comparison because of various backends |
|
672 for arg in ex.args: |
|
673 mo = re.search('unique_cw_[^ ]+_idx', arg) |
|
674 if mo is not None: |
|
675 index_name = mo.group(0) |
|
676 elements = index_name.rstrip('_idx').split('_cw_')[1:] |
|
677 etype = elements[0] |
|
678 rtypes = elements[1:] |
|
679 raise UniqueTogetherError(etype, rtypes) |
669 raise |
680 raise |
670 return cursor |
681 return cursor |
671 |
682 |
672 def doexecmany(self, session, query, args): |
683 def doexecmany(self, session, query, args): |
673 """Execute a query. |
684 """Execute a query. |