server/test/unittest_storage.py
author Sylvain Thénault <sylvain.thenault@logilab.fr>
Thu, 25 Mar 2010 13:59:47 +0100
branchstable
changeset 5013 ad91f93bbb93
parent 5008 385bf22e3c12
child 5109 5cf83b9356d5
permissions -rw-r--r--
[source storage] refactor source sql generation and results handling to allow repository side callbacks for instance with the BytesFileSystemStorage, before this change: * fspath, _fsopen function were stored procedures executed on the database -> files had to be available both on the repository *and* the database host * we needed implementation for each handled database Now, those function are python callbacks executed when necessary on the repository side, on data comming from the database. The litle cons are: * you can't do anymore restriction on mapped attributes * you can't write queries which will return in the same rset column some mapped attributes (or not mapped the same way) / some not This seems much acceptable since: * it's much more easy to handle when you start having the db on another host than the repo * BFSS works seemlessly on any backend now * you don't bother that much about the cons (at least in the bfss case): you usually don't do any restriction on Bytes... Bonus points: BFSS is more efficient (no queries under the cover as it was done in the registered procedure) and we have a much nicer/efficient fspath implementation. IMO, that rocks :D
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     1
"""unit tests for module cubicweb.server.sources.storages
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     2
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     3
:organization: Logilab
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     4
:copyright: 2010 LOGILAB S.A. (Paris, FRANCE), license is LGPL v2.
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     5
:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     6
:license: GNU Lesser General Public License, v2.1 - http://www.gnu.org/licenses
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     7
"""
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     8
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
     9
from logilab.common.testlib import unittest_main
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    10
from cubicweb.devtools.testlib import CubicWebTC
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    11
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    12
import os.path as osp
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    13
import shutil
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    14
import tempfile
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    15
5013
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
    16
from cubicweb import Binary, QueryError
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    17
from cubicweb.selectors import implements
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    18
from cubicweb.server.sources import storages
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    19
from cubicweb.server.hook import Hook, Operation
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    20
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    21
class DummyBeforeHook(Hook):
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    22
    __regid__ = 'dummy-before-hook'
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    23
    __select__ = Hook.__select__ & implements('File')
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    24
    events = ('before_add_entity',)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    25
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    26
    def __call__(self):
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    27
        self._cw.transaction_data['orig_file_value'] = self.entity.data.getvalue()
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    28
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    29
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    30
class DummyAfterHook(Hook):
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    31
    __regid__ = 'dummy-after-hook'
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    32
    __select__ = Hook.__select__ & implements('File')
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    33
    events = ('after_add_entity',)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    34
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    35
    def __call__(self):
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    36
        # new value of entity.data should be the same as before
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    37
        oldvalue = self._cw.transaction_data['orig_file_value']
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    38
        assert oldvalue == self.entity.data.getvalue()
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    39
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    40
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    41
class StorageTC(CubicWebTC):
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    42
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    43
    def setup_database(self):
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    44
        self.tempdir = tempfile.mkdtemp()
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    45
        bfs_storage = storages.BytesFileSystemStorage(self.tempdir)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    46
        storages.set_attribute_storage(self.repo, 'File', 'data', bfs_storage)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    47
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    48
    def tearDown(self):
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    49
        super(CubicWebTC, self).tearDown()
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    50
        storages.unset_attribute_storage(self.repo, 'File', 'data')
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    51
        shutil.rmtree(self.tempdir)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    52
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    53
5008
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    54
    def create_file(self, content='the-data'):
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    55
        req = self.request()
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    56
        return req.create_entity('File', data=Binary(content),
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    57
                                 data_format=u'text/plain', data_name=u'foo')
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    58
5008
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    59
    def test_bfss_storage(self):
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    60
        f1 = self.create_file()
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    61
        expected_filepath = osp.join(self.tempdir, '%s_data' % f1.eid)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    62
        self.failUnless(osp.isfile(expected_filepath))
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    63
        self.assertEquals(file(expected_filepath).read(), 'the-data')
5008
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    64
        self.rollback()
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    65
        self.failIf(osp.isfile(expected_filepath))
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    66
        f1 = self.create_file()
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    67
        self.commit()
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    68
        self.assertEquals(file(expected_filepath).read(), 'the-data')
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    69
        f1.set_attributes(data=Binary('the new data'))
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    70
        self.rollback()
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    71
        self.assertEquals(file(expected_filepath).read(), 'the-data')
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    72
        f1.delete()
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    73
        self.failUnless(osp.isfile(expected_filepath))
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    74
        self.rollback()
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    75
        self.failUnless(osp.isfile(expected_filepath))
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    76
        f1.delete()
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    77
        self.commit()
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    78
        self.failIf(osp.isfile(expected_filepath))
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    79
5008
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    80
    def test_bfss_sqlite_fspath(self):
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    81
        f1 = self.create_file()
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    82
        expected_filepath = osp.join(self.tempdir, '%s_data' % f1.eid)
5013
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
    83
        fspath = self.execute('Any fspath(D) WHERE F eid %(f)s, F data D',
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    84
                              {'f': f1.eid})[0][0]
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    85
        self.assertEquals(fspath.getvalue(), expected_filepath)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    86
5008
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    87
    def test_bfss_fs_importing_doesnt_touch_path(self):
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    88
        self.session.transaction_data['fs_importing'] = True
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    89
        f1 = self.session.create_entity('File', data=Binary('/the/path'),
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    90
                                        data_format=u'text/plain', data_name=u'foo')
5013
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
    91
        fspath = self.execute('Any fspath(D) WHERE F eid %(f)s, F data D',
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    92
                              {'f': f1.eid})[0][0]
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    93
        self.assertEquals(fspath.getvalue(), '/the/path')
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    94
5008
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
    95
    def test_source_storage_transparency(self):
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    96
        self.vreg._loadedmods[__name__] = {}
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    97
        self.vreg.register(DummyBeforeHook)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    98
        self.vreg.register(DummyAfterHook)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
    99
        try:
5008
385bf22e3c12 [bfss test] some minor refactoring. Test deletion + creation/update/deletion rollback
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 4967
diff changeset
   100
            self.create_file()
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   101
        finally:
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   102
            self.vreg.unregister(DummyBeforeHook)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   103
            self.vreg.unregister(DummyAfterHook)
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   104
5013
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   105
    def test_source_mapped_attribute_error_cases(self):
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   106
        ex = self.assertRaises(QueryError, self.execute,
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   107
                               'Any X WHERE X data ~= "hop", X is File')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   108
        self.assertEquals(str(ex), 'can\'t use File.data (X data ILIKE "hop") in restriction')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   109
        ex = self.assertRaises(QueryError, self.execute,
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   110
                               'Any X, Y WHERE X data D, Y data D, '
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   111
                               'NOT X identity Y, X is File, Y is File')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   112
        self.assertEquals(str(ex), "can't use D as a restriction variable")
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   113
        # query returning mix of mapped / regular attributes (only file.data
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   114
        # mapped, not image.data for instance)
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   115
        ex = self.assertRaises(QueryError, self.execute,
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   116
                               'Any X WITH X BEING ('
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   117
                               ' (Any NULL)'
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   118
                               '  UNION '
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   119
                               ' (Any D WHERE X data D, X is File)'
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   120
                               ')')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   121
        self.assertEquals(str(ex), 'query fetch some source mapped attribute, some not')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   122
        ex = self.assertRaises(QueryError, self.execute,
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   123
                               '(Any D WHERE X data D, X is File)'
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   124
                               ' UNION '
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   125
                               '(Any D WHERE X data D, X is Image)')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   126
        self.assertEquals(str(ex), 'query fetch some source mapped attribute, some not')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   127
        ex = self.assertRaises(QueryError,
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   128
                               self.execute, 'Any D WHERE X data D')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   129
        self.assertEquals(str(ex), 'query fetch some source mapped attribute, some not')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   130
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   131
    def test_source_mapped_attribute_advanced(self):
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   132
        f1 = self.create_file()
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   133
        rset = self.execute('Any X,D WITH D,X BEING ('
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   134
                            ' (Any D, X WHERE X eid %(x)s, X data D)'
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   135
                            '  UNION '
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   136
                            ' (Any D, X WHERE X eid %(x)s, X data D)'
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   137
                            ')', {'x': f1.eid}, 'x')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   138
        self.assertEquals(len(rset), 2)
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   139
        self.assertEquals(rset[0][0], f1.eid)
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   140
        self.assertEquals(rset[1][0], f1.eid)
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   141
        self.assertEquals(rset[0][1].getvalue(), 'the-data')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   142
        self.assertEquals(rset[1][1].getvalue(), 'the-data')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   143
        rset = self.execute('Any X,LENGTH(D) WHERE X eid %(x)s, X data D',
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   144
                            {'x': f1.eid}, 'x')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   145
        self.assertEquals(len(rset), 1)
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   146
        self.assertEquals(rset[0][0], f1.eid)
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   147
        self.assertEquals(rset[0][1], len('the-data'))
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   148
        rset = self.execute('Any X,LENGTH(D) WITH D,X BEING ('
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   149
                            ' (Any D, X WHERE X eid %(x)s, X data D)'
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   150
                            '  UNION '
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   151
                            ' (Any D, X WHERE X eid %(x)s, X data D)'
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   152
                            ')', {'x': f1.eid}, 'x')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   153
        self.assertEquals(len(rset), 2)
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   154
        self.assertEquals(rset[0][0], f1.eid)
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   155
        self.assertEquals(rset[1][0], f1.eid)
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   156
        self.assertEquals(rset[0][1], len('the-data'))
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   157
        self.assertEquals(rset[1][1], len('the-data'))
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   158
        ex = self.assertRaises(QueryError, self.execute,
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   159
                               'Any X,UPPER(D) WHERE X eid %(x)s, X data D',
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   160
                               {'x': f1.eid}, 'x')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   161
        self.assertEquals(str(ex), 'UPPER can not be called on mapped attribute')
ad91f93bbb93 [source storage] refactor source sql generation and results handling to allow repository side callbacks
Sylvain Thénault <sylvain.thenault@logilab.fr>
parents: 5008
diff changeset
   162
4967
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   163
if __name__ == '__main__':
236f1fde6dd0 [server] add unit tests for storages
Adrien Di Mascio <Adrien.DiMascio@logilab.fr>
parents:
diff changeset
   164
    unittest_main()