1 # copyright 2003-2014 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
1 # copyright 2003-2015 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
2 # contact http://www.logilab.fr/ -- mailto:contact@logilab.fr |
3 # |
3 # |
4 # This file is part of CubicWeb. |
4 # This file is part of CubicWeb. |
5 # |
5 # |
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
6 # CubicWeb is free software: you can redistribute it and/or modify it under the |
23 import sys |
23 import sys |
24 import re |
24 import re |
25 import subprocess |
25 import subprocess |
26 from os.path import abspath |
26 from os.path import abspath |
27 from logging import getLogger |
27 from logging import getLogger |
28 from datetime import time, datetime |
28 from datetime import time, datetime, timedelta |
29 |
29 |
30 from six import string_types, text_type |
30 from six import string_types, text_type |
31 from six.moves import filter |
31 from six.moves import filter |
32 |
32 |
33 from logilab import database as db, common as lgc |
33 from logilab import database as db, common as lgc |
34 from logilab.common.shellutils import ProgressBar, DummyProgressBar |
34 from logilab.common.shellutils import ProgressBar, DummyProgressBar |
35 from logilab.common.deprecation import deprecated |
35 from logilab.common.deprecation import deprecated |
36 from logilab.common.logging_ext import set_log_methods |
36 from logilab.common.logging_ext import set_log_methods |
37 from logilab.common.date import utctime, utcdatetime |
37 from logilab.common.date import utctime, utcdatetime, strptime |
38 from logilab.database.sqlgen import SQLGenerator |
38 from logilab.database.sqlgen import SQLGenerator |
39 |
39 |
40 from cubicweb import Binary, ConfigurationError |
40 from cubicweb import Binary, ConfigurationError |
41 from cubicweb.uilib import remove_html_tags |
41 from cubicweb.uilib import remove_html_tags |
42 from cubicweb.schema import PURE_VIRTUAL_RTYPES |
42 from cubicweb.schema import PURE_VIRTUAL_RTYPES |
477 set_log_methods(SQLAdapterMixIn, getLogger('cubicweb.sqladapter')) |
477 set_log_methods(SQLAdapterMixIn, getLogger('cubicweb.sqladapter')) |
478 |
478 |
479 |
479 |
480 # connection initialization functions ########################################## |
480 # connection initialization functions ########################################## |
481 |
481 |
|
482 def _install_sqlite_querier_patch(): |
|
483 """This monkey-patch hotfixes a bug sqlite causing some dates to be returned as strings rather than |
|
484 date objects (http://www.sqlite.org/cvstrac/tktview?tn=1327,33) |
|
485 """ |
|
486 from cubicweb.server.querier import QuerierHelper |
|
487 |
|
488 if hasattr(QuerierHelper, '_sqlite_patched'): |
|
489 return # already monkey patched |
|
490 |
|
491 def wrap_execute(base_execute): |
|
492 def new_execute(*args, **kwargs): |
|
493 rset = base_execute(*args, **kwargs) |
|
494 if rset.description: |
|
495 found_date = False |
|
496 for row, rowdesc in zip(rset, rset.description): |
|
497 for cellindex, (value, vtype) in enumerate(zip(row, rowdesc)): |
|
498 if vtype in ('Date', 'Datetime') and isinstance(value, text_type): |
|
499 found_date = True |
|
500 value = value.rsplit('.', 1)[0] |
|
501 try: |
|
502 row[cellindex] = strptime(value, '%Y-%m-%d %H:%M:%S') |
|
503 except Exception: |
|
504 row[cellindex] = strptime(value, '%Y-%m-%d') |
|
505 if vtype == 'Time' and isinstance(value, text_type): |
|
506 found_date = True |
|
507 try: |
|
508 row[cellindex] = strptime(value, '%H:%M:%S') |
|
509 except Exception: |
|
510 # DateTime used as Time? |
|
511 row[cellindex] = strptime(value, '%Y-%m-%d %H:%M:%S') |
|
512 if vtype == 'Interval' and isinstance(value, int): |
|
513 found_date = True |
|
514 # XXX value is in number of seconds? |
|
515 row[cellindex] = timedelta(0, value, 0) |
|
516 if not found_date: |
|
517 break |
|
518 return rset |
|
519 return new_execute |
|
520 |
|
521 QuerierHelper.execute = wrap_execute(QuerierHelper.execute) |
|
522 QuerierHelper._sqlite_patched = True |
|
523 |
|
524 |
482 def init_sqlite_connexion(cnx): |
525 def init_sqlite_connexion(cnx): |
|
526 _install_sqlite_querier_patch() |
483 |
527 |
484 class group_concat(object): |
528 class group_concat(object): |
485 def __init__(self): |
529 def __init__(self): |
486 self.values = set() |
530 self.values = set() |
487 def step(self, value): |
531 def step(self, value): |