# HG changeset patch # User Sylvain Thénault # Date 1301663087 -7200 # Node ID dde161937d3e991ef8d77112883c404ba846acac # Parent b817d44cb606ff68e75865c8ddab74f55f69bc1b [time zone] support for TZDatetime and TZTime data type Should be usable and cause no crash, though some stuff may still be refined (test value generation, display in views/forms...) Proprify some data structures dealing with yams base types along the way and adding warning when some were missing (eg Interval usually). diff -r b817d44cb606 -r dde161937d3e __pkginfo__.py --- a/__pkginfo__.py Fri Apr 01 14:38:16 2011 +0200 +++ b/__pkginfo__.py Fri Apr 01 15:04:47 2011 +0200 @@ -43,7 +43,7 @@ 'logilab-common': '>= 0.55.2', 'logilab-mtconverter': '>= 0.8.0', 'rql': '>= 0.28.0', - 'yams': '>= 0.30.4', + 'yams': '>= 0.32.0', 'docutils': '>= 0.6', #gettext # for xgettext, msgcat, etc... # web dependancies @@ -52,7 +52,7 @@ 'Twisted': '', # XXX graphviz # server dependencies - 'logilab-database': '>= 1.4.0', + 'logilab-database': '>= 1.5.0', 'pysqlite': '>= 2.5.5', # XXX install pysqlite2 } diff -r b817d44cb606 -r dde161937d3e cwvreg.py --- a/cwvreg.py Fri Apr 01 14:38:16 2011 +0200 +++ b/cwvreg.py Fri Apr 01 15:04:47 2011 +0200 @@ -839,18 +839,24 @@ return self['views'].select(__vid, req, rset=rset, **kwargs) +import decimal from datetime import datetime, date, time, timedelta -YAMS_TO_PY = { - 'Boolean': bool, +YAMS_TO_PY = { # XXX unify with yams.constraints.BASE_CONVERTERS? 'String' : unicode, + 'Bytes': Binary, 'Password': str, - 'Bytes': Binary, + + 'Boolean': bool, 'Int': int, 'Float': float, - 'Date': date, - 'Datetime': datetime, - 'Time': time, - 'Interval': timedelta, + 'Decimal': decimal.Decimal, + + 'Date': date, + 'Datetime': datetime, + 'TZDatetime': datetime, + 'Time': time, + 'TZTime': time, + 'Interval': timedelta, } diff -r b817d44cb606 -r dde161937d3e debian/control --- a/debian/control Fri Apr 01 14:38:16 2011 +0200 +++ b/debian/control Fri Apr 01 15:04:47 2011 +0200 @@ -33,7 +33,7 @@ Conflicts: cubicweb-multisources Replaces: cubicweb-multisources Provides: cubicweb-multisources -Depends: ${misc:Depends}, ${python:Depends}, cubicweb-common (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-logilab-database (>= 1.4.0), cubicweb-postgresql-support | cubicweb-mysql-support | python-pysqlite2 +Depends: ${misc:Depends}, ${python:Depends}, cubicweb-common (= ${source:Version}), cubicweb-ctl (= ${source:Version}), python-logilab-database (>= 1.5.0), cubicweb-postgresql-support | cubicweb-mysql-support | python-pysqlite2 Recommends: pyro (<< 4.0.0), cubicweb-documentation (= ${source:Version}) Description: server part of the CubicWeb framework CubicWeb is a semantic web application framework. @@ -97,7 +97,7 @@ Package: cubicweb-common Architecture: all XB-Python-Version: ${python:Versions} -Depends: ${misc:Depends}, ${python:Depends}, graphviz, gettext, python-logilab-mtconverter (>= 0.8.0), python-logilab-common (>= 0.55.2), python-yams (>= 0.30.4), python-rql (>= 0.28.0), python-lxml +Depends: ${misc:Depends}, ${python:Depends}, graphviz, gettext, python-logilab-mtconverter (>= 0.8.0), python-logilab-common (>= 0.55.2), python-yams (>= 0.32.0), python-rql (>= 0.28.0), python-lxml Recommends: python-simpletal (>= 4.0), python-crypto Conflicts: cubicweb-core Replaces: cubicweb-core diff -r b817d44cb606 -r dde161937d3e devtools/fill.py --- a/devtools/fill.py Fri Apr 01 14:38:16 2011 +0200 +++ b/devtools/fill.py Fri Apr 01 15:04:47 2011 +0200 @@ -152,6 +152,8 @@ base = datetime(randint(2000, 2004), randint(1, 12), randint(1, 28), 11, index%60) return self._constrained_generate(entity, attrname, base, timedelta(hours=1), index) + generate_tzdatetime = generate_datetime # XXX implementation should add a timezone + def generate_date(self, entity, attrname, index): """generates a random date (format is 'yyyy-mm-dd')""" base = date(randint(2000, 2010), 1, 1) + timedelta(randint(1, 365)) @@ -166,6 +168,8 @@ """generates a random time (format is ' HH:MM')""" return time(11, index%60) #'11:%02d' % (index % 60) + generate_tztime = generate_time # XXX implementation should add a timezone + def generate_bytes(self, entity, attrname, index, format=None): fakefile = Binary("%s%s" % (attrname, index)) fakefile.filename = u"file_%s" % attrname diff -r b817d44cb606 -r dde161937d3e misc/migration/3.12.0_Any.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/migration/3.12.0_Any.py Fri Apr 01 15:04:47 2011 +0200 @@ -0,0 +1,2 @@ +add_entity_type('TZDatetime') +add_entity_type('TZTime') diff -r b817d44cb606 -r dde161937d3e server/migractions.py --- a/server/migractions.py Fri Apr 01 14:38:16 2011 +0200 +++ b/server/migractions.py Fri Apr 01 15:04:47 2011 +0200 @@ -758,9 +758,9 @@ targeted type is known """ instschema = self.repo.schema - assert not etype in instschema, \ + eschema = self.fs_schema.eschema(etype) + assert eschema.final or not etype in instschema, \ '%s already defined in the instance schema' % etype - eschema = self.fs_schema.eschema(etype) confirm = self.verbosity >= 2 groupmap = self.group_mapping() cstrtypemap = self.cstrtype_mapping() diff -r b817d44cb606 -r dde161937d3e server/sources/rql2sql.py --- a/server/sources/rql2sql.py Fri Apr 01 14:38:16 2011 +0200 +++ b/server/sources/rql2sql.py Fri Apr 01 15:04:47 2011 +0200 @@ -50,7 +50,9 @@ __docformat__ = "restructuredtext en" import threading +from datetime import datetime, time +from logilab.common.date import utcdatetime, utctime from logilab.database import FunctionDescr, SQL_FUNCTIONS_REGISTRY from rql import BadRQLQuery, CoercionError @@ -1171,6 +1173,14 @@ _id = value if isinstance(_id, unicode): _id = _id.encode() + # convert timestamp to utc. + # expect SET TiME ZONE to UTC at connection opening time. + # This shouldn't change anything for datetime without TZ. + value = self._args[_id] + if isinstance(value, datetime) and value.tzinfo is not None: + self._query_attrs[_id] = utcdatetime(value) + elif isinstance(value, time) and value.tzinfo is not None: + self._query_attrs[_id] = utctime(value) else: _id = str(id(constant)).replace('-', '', 1) self._query_attrs[_id] = value diff -r b817d44cb606 -r dde161937d3e server/sqlutils.py --- a/server/sqlutils.py Fri Apr 01 14:38:16 2011 +0200 +++ b/server/sqlutils.py Fri Apr 01 15:04:47 2011 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -25,7 +25,7 @@ from logilab import database as db, common as lgc from logilab.common.shellutils import ProgressBar -from logilab.common.date import todate, todatetime +from logilab.common.date import todate, todatetime, utcdatetime, utctime from logilab.database.sqlgen import SQLGenerator from cubicweb import Binary, ConfigurationError @@ -274,10 +274,15 @@ value = crypt_password(value) value = self._binary(value) # XXX needed for sqlite but I don't think it is for other backends - elif atype == 'Datetime' and isinstance(value, date): + # Note: use is __class__ since issubclass(datetime, date) + elif atype in ('Datetime', 'TZDatetime') and value.__class__ is date: value = todatetime(value) elif atype == 'Date' and isinstance(value, datetime): value = todate(value) + elif atype == 'TZDatetime' and getattr(value, 'tzinfo', None): + value = utcdatetime(value) + elif atype == 'TZTime' and getattr(value, 'tzinfo', None): + value = utctime(value) elif isinstance(value, Binary): value = self._binary(value.getvalue()) attrs[SQL_PREFIX+str(attr)] = value @@ -326,3 +331,10 @@ sqlite_hooks = SQL_CONNECT_HOOKS.setdefault('sqlite', []) sqlite_hooks.append(init_sqlite_connexion) + + +def init_postgres_connexion(cnx): + cnx.cursor().execute('SET TIME ZONE UTC') + +postgres_hooks = SQL_CONNECT_HOOKS.setdefault('postgres', []) +postgres_hooks.append(init_postgres_connexion) diff -r b817d44cb606 -r dde161937d3e server/test/data/schema.py --- a/server/test/data/schema.py Fri Apr 01 14:38:16 2011 +0200 +++ b/server/test/data/schema.py Fri Apr 01 15:04:47 2011 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -18,7 +18,7 @@ from yams.buildobjs import (EntityType, RelationType, RelationDefinition, SubjectRelation, RichString, String, Int, Float, - Boolean, Datetime) + Boolean, Datetime, TZDatetime) from yams.constraints import SizeConstraint from cubicweb.schema import (WorkflowableEntityType, RQLConstraint, RQLUniqueConstraint, @@ -114,6 +114,7 @@ tel = Int() fax = Int() datenaiss = Datetime() + tzdatenaiss = TZDatetime() test = Boolean(__permissions__={ 'read': ('managers', 'users', 'guests'), 'update': ('managers',), diff -r b817d44cb606 -r dde161937d3e server/test/data/sources_fti --- a/server/test/data/sources_fti Fri Apr 01 14:38:16 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,14 +0,0 @@ -[system] - -db-driver = postgres -db-host = localhost -db-port = -adapter = native -db-name = cw_fti_test -db-encoding = UTF-8 -db-user = syt -db-password = syt - -[admin] -login = admin -password = gingkow diff -r b817d44cb606 -r dde161937d3e server/test/data/sources_postgres --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/test/data/sources_postgres Fri Apr 01 15:04:47 2011 +0200 @@ -0,0 +1,14 @@ +[system] + +db-driver = postgres +db-host = localhost +db-port = 5433 +adapter = native +db-name = cw_fti_test +db-encoding = UTF-8 +db-user = syt +db-password = syt + +[admin] +login = admin +password = gingkow diff -r b817d44cb606 -r dde161937d3e server/test/unittest_fti.py --- a/server/test/unittest_fti.py Fri Apr 01 14:38:16 2011 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,68 +0,0 @@ -from __future__ import with_statement - -import socket - -from logilab.common.testlib import SkipTest - -from cubicweb.devtools import ApptestConfiguration -from cubicweb.devtools.testlib import CubicWebTC -from cubicweb.selectors import is_instance -from cubicweb.entities.adapters import IFTIndexableAdapter - -AT_LOGILAB = socket.gethostname().endswith('.logilab.fr') - - -class PostgresFTITC(CubicWebTC): - config = ApptestConfiguration('data', sourcefile='sources_fti') - - @classmethod - def setUpClass(cls): - if not AT_LOGILAB: - raise SkipTest('XXX %s: require logilab configuration' % cls.__name__) - - def test_occurence_count(self): - req = self.request() - c1 = req.create_entity('Card', title=u'c1', - content=u'cubicweb cubicweb cubicweb') - c2 = req.create_entity('Card', title=u'c3', - content=u'cubicweb') - c3 = req.create_entity('Card', title=u'c2', - content=u'cubicweb cubicweb') - self.commit() - self.assertEqual(req.execute('Card X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows, - [[c1.eid], [c3.eid], [c2.eid]]) - - - def test_attr_weight(self): - class CardIFTIndexableAdapter(IFTIndexableAdapter): - __select__ = is_instance('Card') - attr_weight = {'title': 'A'} - with self.temporary_appobjects(CardIFTIndexableAdapter): - req = self.request() - c1 = req.create_entity('Card', title=u'c1', - content=u'cubicweb cubicweb cubicweb') - c2 = req.create_entity('Card', title=u'c2', - content=u'cubicweb cubicweb') - c3 = req.create_entity('Card', title=u'cubicweb', - content=u'autre chose') - self.commit() - self.assertEqual(req.execute('Card X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows, - [[c3.eid], [c1.eid], [c2.eid]]) - - def test_entity_weight(self): - class PersonneIFTIndexableAdapter(IFTIndexableAdapter): - __select__ = is_instance('Personne') - entity_weight = 2.0 - with self.temporary_appobjects(PersonneIFTIndexableAdapter): - req = self.request() - c1 = req.create_entity('Personne', nom=u'c1', prenom=u'cubicweb') - c2 = req.create_entity('Comment', content=u'cubicweb cubicweb', comments=c1) - c3 = req.create_entity('Comment', content=u'cubicweb cubicweb cubicweb', comments=c1) - self.commit() - self.assertEqual(req.execute('Any X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows, - [[c1.eid], [c3.eid], [c2.eid]]) - - -if __name__ == '__main__': - from logilab.common.testlib import unittest_main - unittest_main() diff -r b817d44cb606 -r dde161937d3e server/test/unittest_postgres.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/server/test/unittest_postgres.py Fri Apr 01 15:04:47 2011 +0200 @@ -0,0 +1,77 @@ +from __future__ import with_statement + +import socket +from datetime import datetime + +from logilab.common.testlib import SkipTest + +from cubicweb.devtools import ApptestConfiguration +from cubicweb.devtools.testlib import CubicWebTC +from cubicweb.selectors import is_instance +from cubicweb.entities.adapters import IFTIndexableAdapter + +AT_LOGILAB = socket.gethostname().endswith('.logilab.fr') # XXX + +from unittest_querier import FixedOffset + +class PostgresFTITC(CubicWebTC): + config = ApptestConfiguration('data', sourcefile='sources_postgres') + + @classmethod + def setUpClass(cls): + if not AT_LOGILAB: # XXX here until we can raise SkipTest in setUp to detect we can't connect to the db + raise SkipTest('XXX %s: require logilab configuration' % cls.__name__) + + def test_occurence_count(self): + req = self.request() + c1 = req.create_entity('Card', title=u'c1', + content=u'cubicweb cubicweb cubicweb') + c2 = req.create_entity('Card', title=u'c3', + content=u'cubicweb') + c3 = req.create_entity('Card', title=u'c2', + content=u'cubicweb cubicweb') + self.commit() + self.assertEqual(req.execute('Card X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows, + [[c1.eid], [c3.eid], [c2.eid]]) + + + def test_attr_weight(self): + class CardIFTIndexableAdapter(IFTIndexableAdapter): + __select__ = is_instance('Card') + attr_weight = {'title': 'A'} + with self.temporary_appobjects(CardIFTIndexableAdapter): + req = self.request() + c1 = req.create_entity('Card', title=u'c1', + content=u'cubicweb cubicweb cubicweb') + c2 = req.create_entity('Card', title=u'c2', + content=u'cubicweb cubicweb') + c3 = req.create_entity('Card', title=u'cubicweb', + content=u'autre chose') + self.commit() + self.assertEqual(req.execute('Card X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows, + [[c3.eid], [c1.eid], [c2.eid]]) + + def test_entity_weight(self): + class PersonneIFTIndexableAdapter(IFTIndexableAdapter): + __select__ = is_instance('Personne') + entity_weight = 2.0 + with self.temporary_appobjects(PersonneIFTIndexableAdapter): + req = self.request() + c1 = req.create_entity('Personne', nom=u'c1', prenom=u'cubicweb') + c2 = req.create_entity('Comment', content=u'cubicweb cubicweb', comments=c1) + c3 = req.create_entity('Comment', content=u'cubicweb cubicweb cubicweb', comments=c1) + self.commit() + self.assertEqual(req.execute('Any X ORDERBY FTIRANK(X) DESC WHERE X has_text "cubicweb"').rows, + [[c1.eid], [c3.eid], [c2.eid]]) + + + def test_tz_datetime(self): + self.execute("INSERT Personne X: X nom 'bob', X tzdatenaiss %(date)s", + {'date': datetime(1977, 6, 7, 2, 0, tzinfo=FixedOffset(1))}) + datenaiss = self.execute("Any XD WHERE X nom 'bob', X tzdatenaiss XD")[0][0] + self.assertEqual(datenaiss.utctimetuple()[:5], (1977, 6, 7, 1, 0)) + + +if __name__ == '__main__': + from logilab.common.testlib import unittest_main + unittest_main() diff -r b817d44cb606 -r dde161937d3e server/test/unittest_querier.py --- a/server/test/unittest_querier.py Fri Apr 01 14:38:16 2011 +0200 +++ b/server/test/unittest_querier.py Fri Apr 01 15:04:47 2011 +0200 @@ -18,7 +18,7 @@ # with CubicWeb. If not, see . """unit tests for modules cubicweb.server.querier and cubicweb.server.ssplanner """ -from datetime import date, datetime +from datetime import date, datetime, timedelta, tzinfo from logilab.common.testlib import TestCase, unittest_main from rql import BadRQLQuery, RQLSyntaxError @@ -32,6 +32,14 @@ from cubicweb.devtools.repotest import tuplify, BaseQuerierTC from unittest_session import Variable +class FixedOffset(tzinfo): + def __init__(self, hours=0): + self.hours = hours + def utcoffset(self, dt): + return timedelta(hours=self.hours) + def dst(self, dt): + return timedelta(0) + # register priority/severity sorting registered procedure from rql.utils import register_function, FunctionDescr @@ -1215,11 +1223,11 @@ self.assertEqual(rset.description, [('CWUser',)]) def test_update_upassword(self): - cursor = self.pool['system'] rset = self.execute("INSERT CWUser X: X login 'bob', X upassword %(pwd)s", {'pwd': 'toto'}) self.assertEqual(rset.description[0][0], 'CWUser') rset = self.execute("SET X upassword %(pwd)s WHERE X is CWUser, X login 'bob'", {'pwd': 'tutu'}) + cursor = self.pool['system'] cursor.execute("SELECT %supassword from %sCWUser WHERE %slogin='bob'" % (SQL_PREFIX, SQL_PREFIX, SQL_PREFIX)) passwd = str(cursor.fetchone()[0]) @@ -1229,7 +1237,15 @@ self.assertEqual(len(rset.rows), 1) self.assertEqual(rset.description, [('CWUser',)]) - # non regression tests #################################################### + # ZT datetime tests ######################################################## + + def test_tz_datetime(self): + self.execute("INSERT Personne X: X nom 'bob', X tzdatenaiss %(date)s", + {'date': datetime(1977, 6, 7, 2, 0, tzinfo=FixedOffset(1))}) + datenaiss = self.execute("Any XD WHERE X nom 'bob', X tzdatenaiss XD")[0][0] + self.assertEqual(datenaiss.utctimetuple()[:5], (1977, 6, 7, 1, 0)) + + # non regression tests ##################################################### def test_nonregr_1(self): teid = self.execute("INSERT Tag X: X name 'tag'")[0][0] diff -r b817d44cb606 -r dde161937d3e server/test/unittest_rql2sql.py --- a/server/test/unittest_rql2sql.py Fri Apr 01 14:38:16 2011 +0200 +++ b/server/test/unittest_rql2sql.py Fri Apr 01 15:04:47 2011 +0200 @@ -1219,9 +1219,13 @@ yield self._check, rql, sql def _checkall(self, rql, sql): + if isinstance(rql, tuple): + rql, args = rql + else: + args = None try: rqlst = self._prepare(rql) - r, args, cbs = self.o.generate(rqlst) + r, args, cbs = self.o.generate(rqlst, args) self.assertEqual((r.strip(), args), sql) except Exception, ex: print rql @@ -1233,7 +1237,7 @@ return def test1(self): - self._checkall('Any count(RDEF) WHERE RDEF relation_type X, X eid %(x)s', + self._checkall(('Any count(RDEF) WHERE RDEF relation_type X, X eid %(x)s', {'x': None}), ("""SELECT COUNT(T1.C0) FROM (SELECT _RDEF.cw_eid AS C0 FROM cw_CWAttribute AS _RDEF WHERE _RDEF.cw_relation_type=%(x)s @@ -1244,7 +1248,7 @@ ) def test2(self): - self._checkall('Any X WHERE C comments X, C eid %(x)s', + self._checkall(('Any X WHERE C comments X, C eid %(x)s', {'x': None}), ('''SELECT rel_comments0.eid_to FROM comments_relation AS rel_comments0 WHERE rel_comments0.eid_from=%(x)s''', {}) diff -r b817d44cb606 -r dde161937d3e test/unittest_schema.py --- a/test/unittest_schema.py Fri Apr 01 14:38:16 2011 +0200 +++ b/test/unittest_schema.py Fri Apr 01 15:04:47 2011 +0200 @@ -169,7 +169,7 @@ 'Password', 'Personne', 'RQLExpression', 'Societe', 'State', 'StateFull', 'String', 'SubNote', 'SubWorkflowExitPoint', - 'TZDatetime', 'TZTime', 'Tag', 'Time', 'Transition', 'TrInfo', + 'Tag', 'TZDatetime', 'TZTime', 'Time', 'Transition', 'TrInfo', 'Workflow', 'WorkflowTransition'] self.assertListEqual(sorted(expected_entities), entities) relations = sorted([str(r) for r in schema.relations()]) diff -r b817d44cb606 -r dde161937d3e uilib.py --- a/uilib.py Fri Apr 01 14:38:16 2011 +0200 +++ b/uilib.py Fri Apr 01 15:04:47 2011 +0200 @@ -62,9 +62,9 @@ return value if attrtype == 'Date': return ustrftime(value, req.property_value('ui.date-format')) - if attrtype == 'Time': + if attrtype in ('Time', 'TZTime'): return ustrftime(value, req.property_value('ui.time-format')) - if attrtype == 'Datetime': + if attrtype in ('Datetime', 'TZDatetime'): if displaytime: return ustrftime(value, req.property_value('ui.datetime-format')) return ustrftime(value, req.property_value('ui.date-format')) @@ -72,8 +72,9 @@ if value: return req._('yes') return req._('no') - if attrtype == 'Float': + if attrtype in ('Float', 'Decimal'): value = req.property_value('ui.float-format') % value + # XXX Interval return unicode(value) diff -r b817d44cb606 -r dde161937d3e web/formfields.py --- a/web/formfields.py Fri Apr 01 14:38:16 2011 +0200 +++ b/web/formfields.py Fri Apr 01 15:04:47 2011 +0200 @@ -1200,14 +1200,19 @@ FIELDS = { - 'Boolean': BooleanField, + 'String' : StringField, 'Bytes': FileField, - 'Date': DateField, - 'Datetime': DateTimeField, + 'Password': PasswordField, + + 'Boolean': BooleanField, 'Int': IntField, 'Float': FloatField, 'Decimal': StringField, - 'Password': PasswordField, - 'String' : StringField, - 'Time': TimeField, + + 'Date': DateField, + 'Datetime': DateTimeField, + 'TZDatetime': DateTimeField, + 'Time': TimeField, + 'TZTime': TimeField, + # XXX implement 'Interval': TimeIntervalField, } diff -r b817d44cb606 -r dde161937d3e web/test/unittest_application.py --- a/web/test/unittest_application.py Fri Apr 01 14:38:16 2011 +0200 +++ b/web/test/unittest_application.py Fri Apr 01 15:04:47 2011 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. diff -r b817d44cb606 -r dde161937d3e web/views/owl.py --- a/web/views/owl.py Fri Apr 01 14:38:16 2011 +0200 +++ b/web/views/owl.py Fri Apr 01 15:04:47 2011 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -35,15 +35,19 @@ } OWL_TYPE_MAP = {'String': 'xsd:string', - 'Datetime': 'xsd:dateTime', 'Bytes': 'xsd:byte', - 'Float': 'xsd:float', + 'Password': 'xsd:byte', + 'Boolean': 'xsd:boolean', 'Int': 'xsd:int', + 'Float': 'xsd:float', + 'Decimal' : 'xsd:decimal', + 'Date':'xsd:date', + 'Datetime': 'xsd:dateTime', + 'TZDatetime': 'xsd:dateTime', 'Time': 'xsd:time', - 'Password': 'xsd:byte', - 'Decimal' : 'xsd:decimal', + 'TZTime': 'xsd:time', 'Interval': 'xsd:duration' } diff -r b817d44cb606 -r dde161937d3e web/views/plots.py --- a/web/views/plots.py Fri Apr 01 14:38:16 2011 +0200 +++ b/web/views/plots.py Fri Apr 01 15:04:47 2011 +0200 @@ -47,7 +47,7 @@ @objectify_selector def columns_are_date_then_numbers(cls, req, rset=None, *args, **kwargs): etypes = rset.description[0] - if etypes[0] not in ('Date', 'Datetime'): + if etypes[0] not in ('Date', 'Datetime', 'TZDatetime'): return 0 for etype in etypes[1:]: if etype not in ('Int', 'Float'): diff -r b817d44cb606 -r dde161937d3e web/views/sparql.py --- a/web/views/sparql.py Fri Apr 01 14:38:16 2011 +0200 +++ b/web/views/sparql.py Fri Apr 01 15:04:47 2011 +0200 @@ -1,4 +1,4 @@ -# copyright 2003-2010 LOGILAB S.A. (Paris, FRANCE), all rights reserved. +# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved. # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr # # This file is part of CubicWeb. @@ -77,17 +77,22 @@ YAMS_XMLSCHEMA_MAPPING = { 'String': 'string', + + 'Boolean': 'boolean', 'Int': 'integer', 'Float': 'float', - 'Boolean': 'boolean', + 'Datetime': 'dateTime', + 'TZDatetime': 'dateTime', 'Date': 'date', 'Time': 'time', + 'TZTime': 'time', + # XXX the following types don't have direct mapping 'Decimal': 'string', 'Interval': 'duration', + 'Bytes': 'base64Binary', 'Password': 'string', - 'Bytes': 'base64Binary', } def xmlschema(yamstype): diff -r b817d44cb606 -r dde161937d3e web/views/xmlrss.py --- a/web/views/xmlrss.py Fri Apr 01 14:38:16 2011 +0200 +++ b/web/views/xmlrss.py Fri Apr 01 15:04:47 2011 +0200 @@ -42,6 +42,8 @@ 'Date': lambda x: x.strftime('%Y-%m-%d'), 'Datetime': lambda x: x.strftime('%Y-%m-%d %H:%M:%S'), 'Time': lambda x: x.strftime('%H:%M:%S'), + 'TZDatetime': lambda x: x.strftime('%Y-%m-%d %H:%M:%S'), # XXX TZ + 'TZTime': lambda x: x.strftime('%H:%M:%S'), 'Interval': lambda x: x.days * 60*60*24 + x.seconds, }