server/sqlutils.py
changeset 11030 c1fdd22232d1
parent 10824 fbefdaa56d2b
child 11031 780939fc06da
equal deleted inserted replaced
11029:c9d12d1d3081 11030:c1fdd22232d1
     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):