goa/test/unittest_rql.py
changeset 0 b97547f5f1fa
child 1398 5fe84a5f7035
equal deleted inserted replaced
-1:000000000000 0:b97547f5f1fa
       
     1 from cubicweb.goa.testlib import *
       
     2 
       
     3 from cubicweb import Binary
       
     4 
       
     5 from logilab.common.testlib import unittest_main
       
     6 from mx.DateTime import now, today, DateTimeType
       
     7 import rql
       
     8 
       
     9 from google.appengine.api.datastore_types import Blob, Text
       
    10 
       
    11 # stored procedure definition #################################################
       
    12 
       
    13 from rql.utils import register_function, FunctionDescr
       
    14 
       
    15 class itemtype_sort_value(FunctionDescr):
       
    16     supported_backends = ('sqlite',)
       
    17     rtype = 'Int'
       
    18 
       
    19 try:
       
    20     register_function(itemtype_sort_value)
       
    21 except AssertionError:
       
    22     pass
       
    23 
       
    24 def init_sqlite_connexion(cnx):
       
    25     def itemtype_sort_value(text):
       
    26         return {"personal":2, "business":1}[text]
       
    27     cnx.create_function("ITEMTYPE_SORT_VALUE", 1, itemtype_sort_value)
       
    28 
       
    29 from cubicweb.server import SQL_CONNECT_HOOKS
       
    30 sqlite_hooks = SQL_CONNECT_HOOKS.setdefault('sqlite', [])
       
    31 sqlite_hooks.append(init_sqlite_connexion)
       
    32 
       
    33 # end stored procedure definition #############################################
       
    34 
       
    35 class Article(db.Model):        
       
    36     content = db.TextProperty()
       
    37     synopsis = db.StringProperty(default=u'hello')
       
    38 
       
    39 class Blog(db.Model):
       
    40     diem = db.DateProperty(required=True, auto_now_add=True)
       
    41     content = db.TextProperty()
       
    42     itemtype = db.StringProperty(required=True, choices=(u'personal', u'business'))
       
    43     talks_about = db.ReferenceProperty(Article) 
       
    44     cites = db.SelfReferenceProperty() 
       
    45     data = db.BlobProperty()
       
    46 
       
    47     
       
    48 class RQLTest(GAEBasedTC):
       
    49     MODEL_CLASSES = (Article, Blog)
       
    50     
       
    51     def setUp(self):
       
    52         GAEBasedTC.setUp(self)
       
    53         # hack to make talks_about cardinality to ** instead of ?*
       
    54         self.schema.rschema('talks_about').set_rproperty('Blog', 'Article',
       
    55                                                          'cardinality', '**')
       
    56         self.req = self.request()
       
    57         self.article = self.add_entity('Article', content=u'very interesting')
       
    58         self.blog = self.add_entity('Blog', itemtype=u'personal', content=u'hop')
       
    59         self.execute('SET X talks_about Y WHERE X eid %(x)s, Y eid %(y)s',
       
    60                      {'x': self.blog.eid, 'y': self.article.eid})
       
    61         self.commit()
       
    62         
       
    63     def _check_rset_size(self, rset, row, col):
       
    64         self.assertEquals(len(rset), row)
       
    65         self.assertEquals(len(rset[0]), col)
       
    66         self.assertEquals(len(rset.description), row)
       
    67         self.assertEquals(len(rset.description[0]), col)
       
    68         
       
    69     def _check_blog_rset(self, rset):
       
    70         self._check_rset_size(rset, 1, 1)
       
    71         self.assertEquals(rset.description[0][0], 'Blog')
       
    72         self.assertEquals(rset[0][0], self.blog.eid)
       
    73         self.assertEquals(rset.get_entity(0, 0).eid, self.blog.eid)
       
    74 
       
    75     def test_0_const(self):
       
    76         rset = self.req.execute('Any 1')
       
    77         self._check_rset_size(rset, 1, 1)
       
    78         self.assertEquals(rset[0][0], 1)
       
    79         self.assertEquals(rset.description[0][0], 'Int')
       
    80 
       
    81     def test_0_now_const(self):
       
    82         rset = self.req.execute('Any NOW')
       
    83         self._check_rset_size(rset, 1, 1)
       
    84         self.assertIsInstance(rset[0][0], DateTimeType)
       
    85         self.assertEquals(rset.description[0][0], 'Datetime')
       
    86 
       
    87     def test_0_today_const(self):
       
    88         rset = self.req.execute('Any TODAY')
       
    89         self._check_rset_size(rset, 1, 1)
       
    90         self.assertIsInstance(rset[0][0], DateTimeType)
       
    91         self.assertEquals(rset[0][0], today())
       
    92         self.assertEquals(rset.description[0][0], 'Date')
       
    93 
       
    94 
       
    95     def test_1_eid(self):
       
    96         rset = self.req.execute('Any X WHERE X eid %(x)s', {'x': self.blog.eid})
       
    97         self._check_blog_rset(rset)
       
    98         rset = self.req.execute('Any X WHERE X eid "%s"' % self.blog.eid)
       
    99         self._check_blog_rset(rset)
       
   100 
       
   101     def test_1_eid_eid(self):
       
   102         rset = self.req.execute('Any X,Y WHERE X eid %(x)s, Y eid %(y)s', {'x': self.blog.eid,
       
   103                                                                            'y': self.article.eid})
       
   104         self._check_rset_size(rset, 1, 2)
       
   105         self.assertEquals(rset.description[0], ('Blog', 'Article'))
       
   106         self.assertEquals(rset[0][0], self.blog.eid)
       
   107         self.assertEquals(rset[0][1], self.article.eid)
       
   108 
       
   109     def test_1_eid_with_is(self):
       
   110         self.assertRaises(rql.TypeResolverException,
       
   111                           self.req.execute, 'Any X WHERE X eid %(x)s, X is Article', {'x': self.blog.eid})
       
   112         rset = self.req.execute('Any X WHERE X eid %(x)s, X is Blog', {'x': self.blog.eid})
       
   113         self._check_blog_rset(rset)
       
   114 
       
   115     def test_1_is(self):
       
   116         rset = self.req.execute('Any X WHERE X is Blog')
       
   117         self._check_blog_rset(rset)
       
   118         blog2 = Blog(itemtype=u'personal', content=u'hop')
       
   119         blog2.put()
       
   120         rset = self.req.execute('Any X WHERE X is Blog')
       
   121         self.assertEquals(len(rset), 2)
       
   122         self.assertEquals(rset.description, [('Blog',), ('Blog',)])
       
   123 
       
   124         
       
   125     def test_2_attribute_selection_1(self):
       
   126         rset = self.req.execute('Any X,D,C WHERE X is Blog, X diem D, X content C')
       
   127         self._check_rset_size(rset, 1, 3)
       
   128         self.assertEquals(rset[0], [self.blog.eid, today(), u'hop'])
       
   129         self.assertEquals(rset.description[0], ('Blog', 'Date', 'String'))
       
   130         self.assertIsInstance(rset[0][1], DateTimeType)
       
   131         
       
   132     def test_2_attribute_selection_2(self):
       
   133         rset = self.req.execute('Any D,C WHERE X is Blog, X diem D, X content C')
       
   134         self._check_rset_size(rset, 1, 2)
       
   135         self.assertEquals(rset[0], [today(), u'hop'])
       
   136         self.assertEquals(rset.description[0], ('Date', 'String'))
       
   137         
       
   138     def test_2_attribute_selection_binary(self):
       
   139         rset = self.req.execute('Any D WHERE X is Blog, X data D')
       
   140         self._check_rset_size(rset, 1, 1)
       
   141         self.assertEquals(rset[0], [None])
       
   142         self.assertEquals(rset.description[0], ('Bytes',))
       
   143         self.blog['data'] = Binary('raw data')
       
   144         self.blog.put()
       
   145         rset = self.req.execute('Any D WHERE X is Blog, X data D')
       
   146         self._check_rset_size(rset, 1, 1)
       
   147         self.assertIsInstance(rset[0][0], Binary)
       
   148         value = rset[0][0].getvalue()
       
   149         self.assertIsInstance(value, str)
       
   150         self.failIf(isinstance(value, Blob)) 
       
   151         self.assertEquals(value, 'raw data')
       
   152         self.assertEquals(rset.description[0], ('Bytes',))
       
   153         
       
   154     def test_2_attribute_selection_long_text(self):
       
   155         self.blog['content'] = text = 'a'*501
       
   156         self.blog.put()
       
   157         rset = self.req.execute('Any C WHERE X is Blog, X content C')
       
   158         self._check_rset_size(rset, 1, 1)
       
   159         self.assertIsInstance(rset[0][0], unicode)
       
   160         self.failIf(isinstance(rset[0][0], Text)) 
       
   161         self.assertEquals(rset[0][0], text)
       
   162         
       
   163     def test_2_attribute_selection_transformation(self):
       
   164         rset = self.req.execute('Any X,UPPER(C) WHERE X is Blog, X content C')
       
   165         self._check_rset_size(rset, 1, 2)
       
   166         self.assertEquals(rset[0], [self.blog.eid, u'HOP'])
       
   167         self.assertEquals(rset.description[0], ('Blog', 'String',))
       
   168 
       
   169 
       
   170     def test_3_attribute_restriction(self):
       
   171         rset = self.req.execute('Any X WHERE X itemtype "personal"')
       
   172         self._check_blog_rset(rset)
       
   173         rset = self.req.execute('Any X WHERE X itemtype "business"')
       
   174         self.assertEquals(len(rset), 0)
       
   175         
       
   176     def test_3_ambigous_attribute_restriction_1(self):
       
   177         rset = self.req.execute('Any X WHERE X content "hello"')
       
   178         self.assertEquals(len(rset), 0)
       
   179         
       
   180     def test_3_ambigous_attribute_restriction_2(self):
       
   181         rset = self.req.execute('Any X WHERE X content "hop"')
       
   182         self._check_blog_rset(rset)
       
   183         
       
   184     def test_3_ambigous_attribute_restriction_3(self):
       
   185         article = Article(content=u'hop')
       
   186         article.put()
       
   187         rset = self.req.execute('Any X WHERE X content "hop"')
       
   188         self._check_rset_size(rset, 2, 1)
       
   189         self.assertUnorderedIterableEquals([r[0] for r in rset], [self.blog.eid, article.eid])
       
   190         self.assertUnorderedIterableEquals([r[0] for r in rset.description], ['Blog', 'Article'])
       
   191 
       
   192     def test_3_incoherant_attribute_restriction(self):
       
   193         rset = self.req.execute('Any X WHERE X eid %(x)s, X content "hola"',
       
   194                                 {'x': self.blog.eid})
       
   195         self.assertEquals(len(rset), 0)
       
   196         
       
   197     def test_3_multiple_attribute_restriction(self):
       
   198         rset = self.req.execute('Any X WHERE X content "hop", X itemtype "personal"')
       
   199         self._check_blog_rset(rset)
       
   200         
       
   201     def test_3_incoherant_multiple_attribute_restriction(self):
       
   202         rset = self.req.execute('Any X WHERE X content "hip", X itemtype "personal"')
       
   203         self.assertEquals(len(rset), 0)
       
   204 
       
   205     def test_3_today_attribute_restriction(self):
       
   206         rset = self.req.execute('Any X WHERE X diem < TODAY')
       
   207         self.assertEquals(len(rset), 0)
       
   208         rset = self.req.execute('Any X WHERE X diem <= TODAY')
       
   209         self._check_blog_rset(rset)
       
   210         rset = self.req.execute('Any X WHERE X diem > TODAY')
       
   211         self.assertEquals(len(rset), 0)
       
   212         rset = self.req.execute('Any X WHERE X diem >= TODAY')
       
   213         self._check_blog_rset(rset)
       
   214 
       
   215     def test_3_now_attribute_restriction(self):
       
   216         rset = self.req.execute('Any X WHERE X diem < NOW')
       
   217         self._check_blog_rset(rset)
       
   218         rset = self.req.execute('Any X WHERE X diem <= NOW')
       
   219         self._check_blog_rset(rset)
       
   220         rset = self.req.execute('Any X WHERE X diem > NOW')
       
   221         self.assertEquals(len(rset), 0)
       
   222         rset = self.req.execute('Any X WHERE X diem >= NOW')
       
   223         self.assertEquals(len(rset), 0)
       
   224 
       
   225     def test_3_in_attribute_restriction(self):
       
   226         self.skip('missing actual gae support, retry latter')
       
   227         article2 = Article(content=u'hip')
       
   228         rset = self.req.execute('Any X WHERE X content IN ("hop", "hip")')
       
   229         self._check_rset_size(rset, 2, 1)
       
   230         self.assertUnorderedIterableEquals([r[0] for r in rset], [self.blog.eid, article.eid])
       
   231         self.assertUnorderedIterableEquals([r[0] for r in rset.description], ['Blog', 'Article'])
       
   232 
       
   233     def test_3_like(self):
       
   234         repo = self.config.repository()
       
   235         versions = repo.get_versions()
       
   236         self.assertEquals(versions.keys(), ['cubicweb'])
       
   237     
       
   238     def _setup_relation_description(self):
       
   239         self.article2 = self.add_entity('Article', content=u'hop')
       
   240         self.blog2 = self.add_entity('Blog', itemtype=u'personal', content=u'hip')
       
   241         self.execute('SET X talks_about Y WHERE X eid %(x)s, Y eid %(y)s',
       
   242                      {'x': self.blog2.eid, 'y': self.article2.eid})
       
   243         self.blog3 = self.add_entity('Blog', itemtype=u'business', content=u'hep')
       
   244         self.commit()
       
   245         
       
   246     def test_4_relation_restriction_1(self):
       
   247         self._setup_relation_description()
       
   248         rset = self.req.execute('Any X WHERE X talks_about Y')
       
   249         self._check_rset_size(rset, 2, 1)
       
   250         self.assertUnorderedIterableEquals([r[0] for r in rset],
       
   251                              [self.blog.eid, self.blog2.eid])
       
   252         self.assertUnorderedIterableEquals([r[0] for r in rset.description], ['Blog', 'Blog'])
       
   253         
       
   254     def test_4_relation_restriction_2(self):
       
   255         self._setup_relation_description()
       
   256         rset = self.req.execute('Any Y WHERE X talks_about Y')
       
   257         self._check_rset_size(rset, 2, 1)
       
   258         self.assertUnorderedIterableEquals([r[0] for r in rset],
       
   259                              [self.article.eid, self.article2.eid])
       
   260         self.assertUnorderedIterableEquals([r[0] for r in rset.description],
       
   261                              ['Article', 'Article'])
       
   262         
       
   263     def test_4_relation_restriction_3(self):
       
   264         self._setup_relation_description()
       
   265         rset = self.req.execute('Any X,Y WHERE X talks_about Y')
       
   266         self._check_rset_size(rset, 2, 2)
       
   267         self.assertUnorderedIterableEquals([tuple(r) for r in rset],
       
   268                              [(self.blog.eid, self.article.eid),
       
   269                               (self.blog2.eid, self.article2.eid)])
       
   270         self.assertUnorderedIterableEquals([tuple(r) for r in rset.description],
       
   271                              [('Blog', 'Article'),
       
   272                               ('Blog', 'Article')])
       
   273         
       
   274     def test_4_relation_restriction_4(self):
       
   275         self._setup_relation_description()
       
   276         rset = self.req.execute('Any X,Y WHERE X talks_about Y, X eid %(x)s',
       
   277                                 {'x': self.blog.eid})
       
   278         self._check_rset_size(rset, 1, 2)
       
   279         self.assertEquals(rset[0], [self.blog.eid, self.article.eid])
       
   280         self.assertUnorderedIterableEquals(rset.description[0], ['Blog', 'Article'])
       
   281         
       
   282     def test_4_relation_restriction_5(self):
       
   283         self._setup_relation_description()
       
   284         rset = self.req.execute('Any X,Y WHERE X talks_about Y, Y eid %(x)s',
       
   285                                 {'x': self.article.eid})
       
   286         self._check_rset_size(rset, 1, 2)
       
   287         self.assertEquals(rset[0], [self.blog.eid, self.article.eid])
       
   288         self.assertUnorderedIterableEquals(rset.description[0], ['Blog', 'Article'])
       
   289         
       
   290     def test_4_relation_subject_restriction(self):
       
   291         self._setup_relation_description()
       
   292         rset = self.req.execute('Any X,Y WHERE X talks_about Y, X content %(c)s',
       
   293                                 {'c': 'hop'})
       
   294         self._check_rset_size(rset, 1, 2)
       
   295         self.assertEquals(rset[0], [self.blog.eid, self.article.eid])
       
   296         self.assertUnorderedIterableEquals(rset.description[0], ['Blog', 'Article'])
       
   297         
       
   298     def test_4_relation_object_restriction(self):
       
   299         self._setup_relation_description()
       
   300         rset = self.req.execute('Any X WHERE X is Blog, X talks_about Y, Y content %(c)s',
       
   301                                 {'c': 'very interesting'})
       
   302         self._check_rset_size(rset, 1, 1)
       
   303         self.assertEquals(rset[0], [self.blog.eid])
       
   304         self.assertUnorderedIterableEquals(rset.description[0], ['Blog'])
       
   305         
       
   306     def test_4_relation_subject_object_restriction(self):
       
   307         article2 = self.add_entity('Article', content=u'very interesting')
       
   308         rset = self.req.execute('Any X,XC WHERE X is Blog, X content XC, X content %(xc)s, '
       
   309                                 'X talks_about Y, Y content %(c)s',
       
   310                                 {'xc': 'hop', 'c': 'very interesting'})
       
   311         self._check_rset_size(rset, 1, 2)
       
   312         self.assertEquals(rset[0], [self.blog.eid, self.blog.content])
       
   313         self.assertUnorderedIterableEquals(rset.description[0], ['Blog', 'String'])
       
   314         
       
   315     def test_4_relation_subject_object_restriction_no_res(self):
       
   316         article2 = self.add_entity('Article', content=u'very interesting')
       
   317         rset = self.req.execute('Any X,XC WHERE X is Blog, X content XC, X content %(xc)s, '
       
   318                                 'X talks_about Y, Y content %(c)s',
       
   319                                 {'xc': 'hip', 'c': 'very interesting'})
       
   320         self.assertEquals(len(rset), 0)
       
   321         
       
   322     def test_4_relation_subject_object_restriction_no_res_2(self):
       
   323         rset = self.req.execute('Any X,XC WHERE X is Blog, X content XC, X content %(xc)s, '
       
   324                                 'X talks_about Y, Y content %(c)s',
       
   325                                 {'xc': 'hop', 'c': 'not interesting'})
       
   326         self.assertEquals(len(rset), 0)
       
   327         
       
   328     def test_4_relation_restriction_7(self):
       
   329         self._setup_relation_description()
       
   330         rset = self.req.execute('Any XC,XD,YC WHERE X talks_about Y, Y eid %(x)s,'
       
   331                                 'X content XC, X diem XD, Y content YC',
       
   332                                 {'x': self.article.eid})
       
   333         self._check_rset_size(rset, 1, 3)
       
   334         self.assertEquals(rset[0], [self.blog.content, self.blog.diem, self.article.content])
       
   335         self.assertUnorderedIterableEquals(rset.description[0], ['String', 'Date', 'String'])
       
   336         
       
   337     def test_4_relation_restriction_8(self):
       
   338         self._setup_relation_description()
       
   339         rset = self.req.execute('Any X,Y WHERE X cites Y, Y eid %(x)s', {'x': self.blog.eid})
       
   340         self.assertEquals(len(rset), 0)
       
   341 
       
   342     def test_4_relation_restriction_9(self):
       
   343         article2 = self.add_entity('Article', content=u'hop')
       
   344         self.req.execute('SET X talks_about Y WHERE X eid %(x)s, Y eid %(y)s',
       
   345                          {'x': self.blog.eid, 'y': article2.eid})
       
   346         rset = self.req.execute('Any X,Y WHERE X talks_about Y, X eid %(x)s, Y eid %(y)s',
       
   347                                 {'x': self.blog.eid, 'y': article2.eid})
       
   348         self._check_rset_size(rset, 1, 2)
       
   349         
       
   350     def test_4_ambiguous_subject_relation(self):
       
   351         ye = self.add_entity('YamsEntity')
       
   352         self.req.execute('SET X ambiguous_relation Y WHERE X eid %(x)s, Y eid %(y)s',
       
   353                          {'x': ye.eid, 'y': self.blog.eid})
       
   354         self.req.execute('SET X ambiguous_relation Y WHERE X eid %(x)s, Y eid %(y)s',
       
   355                          {'x': ye.eid, 'y': self.article.eid})
       
   356         self.commit()
       
   357         #ye = self.vreg.etype_class('YamsEntity ')(req, None)
       
   358         #ye.to_gae_model()['s_ambiguous_relation'] = [self.blog.key(), self.article.key()]
       
   359         #ye.put()
       
   360         rset = self.req.execute('Any X WHERE Y ambiguous_relation X')
       
   361         self._check_rset_size(rset, 2, 1)
       
   362         self.assertUnorderedIterableEquals([r[0] for r in rset], [self.blog.eid, self.article.eid])
       
   363         self.assertUnorderedIterableEquals([r[0] for r in rset.description], ['Blog', 'Article'])
       
   364         rset = self.req.execute('Any X WHERE Y ambiguous_relation X, Y eid %(x)s', {'x': ye.eid})
       
   365         self._check_rset_size(rset, 2, 1)
       
   366         self.assertUnorderedIterableEquals([r[0] for r in rset], [self.blog.eid, self.article.eid])
       
   367         self.assertUnorderedIterableEquals([r[0] for r in rset.description], ['Blog', 'Article'])
       
   368         
       
   369     def test_4_relation_selection(self):
       
   370         req = self.request()
       
   371         rset = req.execute('Any N WHERE G content N, U talks_about G, U eid %(u)s', {'u': self.blog.eid})
       
   372         self._check_rset_size(rset, 1, 1)
       
   373         self.assertEquals(rset[0][0], 'very interesting')
       
   374 
       
   375 
       
   376     def test_5_orderby(self):
       
   377         self._setup_relation_description()
       
   378         rset = self.req.execute('Any X,XC ORDERBY XC WHERE X is Blog, X content XC')
       
   379         self._check_rset_size(rset, 3, 2)
       
   380         self.assertEquals(rset.rows,
       
   381                           [[self.blog3.eid, 'hep'],
       
   382                            [self.blog2.eid, 'hip'],
       
   383                            [self.blog.eid, 'hop']])
       
   384                            
       
   385     def test_5_orderby_desc(self):
       
   386         self._setup_relation_description()
       
   387         rset = self.req.execute('Any X,XC ORDERBY XC DESC WHERE X is Blog, X content XC')
       
   388         self._check_rset_size(rset, 3, 2)
       
   389         self.assertEquals(rset.rows,
       
   390                           [[self.blog.eid, 'hop'],
       
   391                            [self.blog2.eid, 'hip'],
       
   392                            [self.blog3.eid, 'hep']])
       
   393 
       
   394     def test_5_orderby_several_terms(self):
       
   395         self._setup_relation_description()
       
   396         rset = self.req.execute('Any X,XC,XI ORDERBY XI,XC WHERE X is Blog, X content XC, X itemtype XI')
       
   397         self._check_rset_size(rset, 3, 3)
       
   398         self.assertEquals(rset.rows,
       
   399                           [[self.blog3.eid, 'hep', 'business'],
       
   400                            [self.blog2.eid, 'hip', 'personal'],
       
   401                            [self.blog.eid, 'hop', 'personal']])
       
   402 
       
   403     def test_5_orderby_several_terms_mixed_implicit(self):
       
   404         self._setup_relation_description()
       
   405         rset = self.req.execute('Any X,XC,XI ORDERBY XI,XC DESC WHERE X is Blog, X content XC, X itemtype XI')
       
   406         self._check_rset_size(rset, 3, 3)
       
   407         self.assertEquals(rset.rows,
       
   408                           [[self.blog3.eid, 'hep', 'business'],
       
   409                            [self.blog.eid, 'hop', 'personal'],
       
   410                            [self.blog2.eid, 'hip', 'personal']])
       
   411 
       
   412     def test_5_orderby_several_terms_explicit_order(self):
       
   413         self._setup_relation_description()
       
   414         rset = self.req.execute('Any X,XC,XI ORDERBY XI DESC,XC DESC WHERE X is Blog, X content XC, X itemtype XI')
       
   415         self._check_rset_size(rset, 3, 3)
       
   416         self.assertEquals(rset.rows,
       
   417                           [[self.blog.eid, 'hop', 'personal'],
       
   418                            [self.blog2.eid, 'hip', 'personal'],
       
   419                            [self.blog3.eid, 'hep', 'business']])
       
   420         
       
   421     def test_5_orderby_several_terms_mixed_order(self):
       
   422         self._setup_relation_description()
       
   423         rset = self.req.execute('Any X,XC,XI ORDERBY XI ASC,XC DESC WHERE X is Blog, X content XC, X itemtype XI')
       
   424         self._check_rset_size(rset, 3, 3)
       
   425         self.assertEquals(rset.rows,
       
   426                           [[self.blog3.eid, 'hep', 'business'],
       
   427                            [self.blog.eid, 'hop', 'personal'],
       
   428                            [self.blog2.eid, 'hip', 'personal']])
       
   429 
       
   430 
       
   431     def test_5_orderby_lower(self):
       
   432         blog2 = self.add_entity('Blog', itemtype=u'business', content=u'Hup')
       
   433         rset = self.req.execute('Any X ORDERBY LOWER(XC) '
       
   434                                 'WHERE X is Blog, X content XC')
       
   435         self._check_rset_size(rset, 2, 1)
       
   436         self.assertEquals(rset.rows, [[self.blog.eid], [blog2.eid]])
       
   437         rset = self.req.execute('Any X ORDERBY LOWER(XC) DESC'
       
   438                                 'WHERE X is Blog, X content XC')
       
   439         self._check_rset_size(rset, 2, 1)
       
   440         self.assertEquals(rset.rows, [[blog2.eid], [self.blog.eid]])
       
   441 
       
   442     def test_5_orderby_stored_proc(self):
       
   443         blog2 = self.add_entity('Blog', itemtype=u'business', content=u'hop')
       
   444         rset = self.req.execute('Any X ORDERBY ITEMTYPE_SORT_VALUE(XIT) '
       
   445                                 'WHERE X is Blog, X itemtype XIT')
       
   446         self._check_rset_size(rset, 2, 1)
       
   447         self.assertEquals(rset.rows, [[blog2.eid], [self.blog.eid]])
       
   448         rset = self.req.execute('Any X ORDERBY ITEMTYPE_SORT_VALUE(XIT) DESC'
       
   449                                 'WHERE X is Blog, X itemtype XIT')
       
   450         self._check_rset_size(rset, 2, 1)
       
   451         self.assertEquals(rset.rows, [[self.blog.eid], [blog2.eid]])
       
   452                           
       
   453         
       
   454     def test_6_limit(self):
       
   455         self._setup_relation_description()
       
   456         rset = self.req.execute('Any X LIMIT 2 WHERE X is Blog')
       
   457         self._check_rset_size(rset, 2, 1)
       
   458         
       
   459     def test_6_offset(self):
       
   460         self._setup_relation_description()
       
   461         rset = self.req.execute('Any XC ORDERBY XC DESC OFFSET 1 WHERE X is Blog, X content XC')
       
   462         self._check_rset_size(rset, 2, 1)
       
   463         self.assertEquals(rset.rows, [['hip'], ['hep']])
       
   464         
       
   465     def test_6_limit_and_orderby(self):
       
   466         self._setup_relation_description()
       
   467         rset = self.req.execute('Any XC ORDERBY XC LIMIT 2 WHERE X is Blog, X content XC')
       
   468         self._check_rset_size(rset, 2, 1)
       
   469         self.assertEquals(rset.rows, [['hep'], ['hip']])
       
   470         
       
   471     def test_6_limit_offset_and_orderby(self):
       
   472         self._setup_relation_description()
       
   473         rset = self.req.execute('Any XC ORDERBY XC LIMIT 2 OFFSET 0 WHERE X is Blog, X content XC')
       
   474         self._check_rset_size(rset, 2, 1)
       
   475         self.assertEquals(rset.rows, [['hep'], ['hip']])
       
   476         rset = self.req.execute('Any XC ORDERBY XC LIMIT 2 OFFSET 1 WHERE X is Blog, X content XC')
       
   477         self._check_rset_size(rset, 2, 1)
       
   478         self.assertEquals(rset.rows, [['hip'], ['hop']])
       
   479         rset = self.req.execute('Any XC ORDERBY XC LIMIT 2 OFFSET 2 WHERE X is Blog, X content XC')
       
   480         self._check_rset_size(rset, 1, 1)
       
   481         self.assertEquals(rset.rows, [['hop']])
       
   482         rset = self.req.execute('Any XC ORDERBY XC LIMIT 2 OFFSET 3 WHERE X is Blog, X content XC')
       
   483         self.failIf(rset)
       
   484         
       
   485 
       
   486     def test_7_simple_datetimecast(self):
       
   487         self._setup_relation_description()
       
   488         _today = today()
       
   489         _tomorrow = _today + 1
       
   490         rset = self.req.execute('Any X WHERE X is Blog, X creation_date >= "%s"'
       
   491                                 % _tomorrow.strftime('%Y-%m-%d'))
       
   492         self.failUnless(len(rset) == 0)
       
   493         rset = self.req.execute('Any X WHERE X is Blog, X creation_date >= "%s"'
       
   494                                 % _today.strftime('%Y-%m-%d'))
       
   495         self._check_rset_size(rset, 3, 1)
       
   496         rset = self.req.execute('Any X WHERE X is Blog, X creation_date <= "%s"'
       
   497                                 % _tomorrow.strftime('%Y-%m-%d'))
       
   498         self._check_rset_size(rset, 3, 1)
       
   499         
       
   500     def test_7_identity_relation(self):
       
   501         rset = self.req.execute('Any X WHERE X identity Y, X eid %(x)s, Y eid %(y)s',
       
   502                                 {'x': self.user.eid, 'y': self.user.eid})
       
   503         self._check_rset_size(rset, 1, 1)
       
   504         rset = self.req.execute('Any Y WHERE X identity Y, X eid %(x)s',
       
   505                                 {'x': self.user.eid})
       
   506         self._check_rset_size(rset, 1, 1)
       
   507         self.assertEquals(rset.rows, [[self.user.eid]])
       
   508         blog2 = self.add_entity('Blog', itemtype=u'personal', content=u'hip')
       
   509         rset = self.req.execute('Any X WHERE X identity Y, X eid %(x)s, Y eid %(y)s',
       
   510                                 {'x': self.blog.eid, 'y': blog2.eid})
       
   511         self.failIf(rset)
       
   512         
       
   513     def test_8_not_relation_1(self):
       
   514         rset = self.req.execute('Any X WHERE X identity U, NOT U in_group G, '
       
   515                                 'G name "guests", X eid %(x)s, U eid %(u)s',
       
   516                                 {'x': self.user.eid, 'u': self.user.eid})
       
   517         self._check_rset_size(rset, 1, 1)
       
   518         self.assertEquals(rset.rows, [[self.user.eid]])        
       
   519 
       
   520     def test_8_not_relation_linked_subject(self):
       
   521         rset = self.req.execute('Any X WHERE NOT X talks_about Y, Y eid %(y)s',
       
   522                                 {'y': self.article.eid})
       
   523         self.failIf(rset)
       
   524         blog2 = self.add_entity('Blog', content=u'hop', itemtype=u'personal')
       
   525         self.commit()
       
   526         rset = self.req.execute('Any X WHERE NOT X talks_about Y, Y eid %(y)s',
       
   527                                 {'y': self.article.eid})        
       
   528         self._check_rset_size(rset, 1, 1)
       
   529         self.assertEquals(rset.rows, [[blog2.eid]])
       
   530 
       
   531     def test_8_not_relation_linked_object(self):
       
   532         rset = self.req.execute('Any Y WHERE NOT X talks_about Y, X eid %(x)s',
       
   533                                 {'x': self.blog.eid})
       
   534         self.failIf(rset)
       
   535         article2 = self.add_entity('Article', content=u'hop')
       
   536         self.commit()
       
   537         rset = self.req.execute('Any Y WHERE NOT X talks_about Y, X eid %(x)s',
       
   538                                 {'x': self.blog.eid})
       
   539         self._check_rset_size(rset, 1, 1)
       
   540         self.assertEquals(rset.rows, [[article2.eid]])
       
   541 
       
   542     def test_8_not_relation_linked_attr(self):
       
   543         self.skip('not yet implemented')
       
   544         # TODO: this should generated 
       
   545         # Query(X)[s_talks_about] > "hop" || Query(X)[s_talks_about] < "hop"
       
   546         article2 = self.add_entity('Article', content=u'hop')
       
   547         self.req.execute('SET X talks_about Y WHERE X eid %(x)s, Y eid %(y)s',
       
   548                          {'x': self.blog.eid, 'y': article2.eid})
       
   549         self.commit()
       
   550         rset = self.req.execute('Any X WHERE NOT X talks_about Y, Y content "hop"')
       
   551         self._check_rset_size(rset, 1, 2)
       
   552         self.assertEquals(rset.rows, [[self.blog.eid, self.article.eid]])
       
   553 
       
   554     def test_8_not_relation_unlinked_subject(self):
       
   555         blog2 = self.add_entity('Blog', content=u'hop', itemtype=u'personal')
       
   556         self.commit()
       
   557         rset = self.req.execute('Any X WHERE NOT X talks_about Y')
       
   558         self._check_rset_size(rset, 1, 1)
       
   559         self.assertEquals(rset.rows, [[blog2.eid]])
       
   560 
       
   561     def test_8_not_relation_unlinked_object(self):
       
   562         article2 = self.add_entity('Article', content=u'hop')
       
   563         self.commit()
       
   564         rset = self.req.execute('Any Y WHERE NOT X talks_about Y')
       
   565         self._check_rset_size(rset, 1, 1)
       
   566         self.assertEquals(rset.rows, [[article2.eid]])
       
   567         
       
   568     def test_8_not_relation_final_1(self):
       
   569         rset = self.req.execute('Any G WHERE G is EGroup, NOT G name "guests"')
       
   570         self._check_rset_size(rset, 2, 1)
       
   571         self.assertUnorderedIterableEquals([g.name for g in rset.entities()],
       
   572                                            ['users', 'managers'])        
       
   573         
       
   574     def test_8_not_relation_final_2(self):
       
   575         rset = self.req.execute('Any GN WHERE G is EGroup, NOT G name "guests", G name GN')
       
   576         self._check_rset_size(rset, 2, 1)
       
   577         self.assertUnorderedIterableEquals([gn for gn, in rset.rows],
       
   578                                            ['users', 'managers'])
       
   579 
       
   580 
       
   581     def test_9_exists(self):
       
   582         blog2 = self.add_entity('Article', content=u'hop')
       
   583         article2 = self.add_entity('Article', content=u'hop')
       
   584         self.req.execute('SET X talks_about Y WHERE X eid %(x)s, Y eid %(y)s',
       
   585                          {'x': self.blog.eid, 'y': article2.eid})
       
   586         self.commit()
       
   587         rset = self.req.execute('Any X WHERE X is Blog, EXISTS(X talks_about Y)')
       
   588         self._check_rset_size(rset, 1, 1)
       
   589         self.assertEquals(rset.rows, [[self.blog.eid]])
       
   590         
       
   591         
       
   592     def test_error_unknown_eid(self):
       
   593         rset = self.req.execute('Any X WHERE X eid %(x)s', {'x': '1234'})
       
   594         self.assertEquals(len(rset), 0)
       
   595         self.blog.delete()
       
   596         rset = self.req.execute('Any X WHERE X eid %(x)s', {'x': self.blog.eid})
       
   597         self.assertEquals(len(rset), 0)
       
   598 
       
   599     def test_nonregr_inlined_relation(self):
       
   600         eid = self.execute('INSERT YamsEntity X: X inlined_relation Y WHERE Y eid %(y)s',
       
   601                            {'y': self.blog.eid})[0][0]
       
   602         self.commit()
       
   603         rset = self.execute('Any X WHERE Y inlined_relation X, Y eid %(y)s', {'y': eid})
       
   604         self._check_rset_size(rset, 1, 1)
       
   605         self.assertEquals(rset[0][0], self.blog.eid)
       
   606         
       
   607 if __name__ == '__main__':
       
   608     unittest_main()