SimpleQuery.py 5.44 KB
Newer Older
1
from __future__ import absolute_import
Ivan Tyagov's avatar
Ivan Tyagov committed
2 3
##############################################################################
#
4 5 6 7
# Copyright (c) 2002-2006 Nexedi SARL and Contributors. All Rights Reserved.
# Copyright (c) 2007-2009 Nexedi SA and Contributors. All Rights Reserved.
#                    Jean-Paul Smets-Solanes <jp@nexedi.com>
#                    Vincent Pelletier <vincent@nexedi.com>
Ivan Tyagov's avatar
Ivan Tyagov committed
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
##############################################################################

32
from .Query import Query
33
from Products.ZSQLCatalog.interfaces.query import IQuery
34
from zope.interface.verify import verifyClass
35
from Products.ZSQLCatalog.SQLCatalog import list_type_list
36
from zLOG import LOG, WARNING
Ivan Tyagov's avatar
Ivan Tyagov committed
37

38 39 40 41
NULL_SEARCH_TEXT_OPERATOR_DICT = {
  '=': 'is',
  '!=': 'is not',
}
Arnaud Fontaine's avatar
WIP  
Arnaud Fontaine committed
42
for value in list(NULL_SEARCH_TEXT_OPERATOR_DICT.values()):
43 44
  NULL_SEARCH_TEXT_OPERATOR_DICT[value] = value

45
class SimpleQuery(Query):
Ivan Tyagov's avatar
Ivan Tyagov committed
46
  """
47 48
    A SimpleQuery represents a single comparison between a single column and
    one or more values.
Ivan Tyagov's avatar
Ivan Tyagov committed
49
  """
50
  def __init__(self, search_key=None, comparison_operator='=', group=None, **kw):
51 52 53 54
    """
      search_key (None, SearchKey instance)
        If given, the instance of SearchKey which is responsible for column
        map registration and rendering (SQL and SearchText).
55
      comparison_operator (string)
56 57 58 59 60 61 62 63 64 65 66 67 68 69
        The comparison operator which will be applied between column and
        values.
        See Operator/ComparisonOperator.py for possible values.
      group
        See ColumnMap.
      **kw
        Must contain exactly one item.
        item key (string)
          column name
        item value
          one or more values
    """
    self.search_key = search_key
    if len(kw) != 1:
70
      raise ValueError('SimpleQuery can support one and one only column. Got %r.' % kw)
71
    self.column, value = kw.popitem()
72
    # Usability improvement code (those changes should not be needed when
73 74
    # this Query is instanciated by a SearchKey, as operator should be correct
    # already).
75 76
    comparison_operator = comparison_operator.lower()
    if comparison_operator == 'in':
77
      if isinstance(value, list_type_list):
78
        if len(value) == 0:
79
          raise ValueError('Empty lists are not allowed.')
80
        elif len(value) == 1:
81
          value, = value
82
          comparison_operator = '='
83
      else:
84 85
        comparison_operator = '='
    elif comparison_operator == '=':
86
      if isinstance(value, list_type_list):
87
        if len(value) == 0:
88
          raise ValueError('Empty lists are not allowed.')
89
        elif len(value) == 1:
90
          value, = value
91
        else:
92
          comparison_operator = 'in'
93
    if value is None:
94 95 96 97 98 99
      try:
        comparison_operator = NULL_SEARCH_TEXT_OPERATOR_DICT[
          comparison_operator]
      except KeyError:
        raise ValueError('Unexpected comparison_operator %r for None value.'
          % (comparison_operator, ))
100
    elif comparison_operator == 'is':
101
      raise ValueError('Non-None value (%r) with "is" comparison_operator. Not sure what to do.' % (value, ))
102
    self.value = value
103
    self.comparison_operator = comparison_operator
104
    self.group = group
Ivan Tyagov's avatar
Ivan Tyagov committed
105

106 107
  def _asSearchTextExpression(self, sql_catalog, column=None):
    return False, self.getSearchKey(sql_catalog).buildSearchTextExpression(self.getOperator(sql_catalog), self.getValue(), column=column)
Ivan Tyagov's avatar
Ivan Tyagov committed
108

109 110 111 112
  def asSQLExpression(self, sql_catalog, column_map, only_group_columns):
    return self.getSearchKey(sql_catalog).buildSQLExpression(
      self.getOperator(sql_catalog), self.getValue(),
      column_map, only_group_columns, group=self.group)
Ivan Tyagov's avatar
Ivan Tyagov committed
113

114 115
  def registerColumnMap(self, sql_catalog, column_map):
    self.group = self.getSearchKey(sql_catalog).registerColumnMap(column_map, group=self.group, simple_query=self)
Ivan Tyagov's avatar
Ivan Tyagov committed
116

117
  def getOperator(self, sql_catalog):
Ivan Tyagov's avatar
Ivan Tyagov committed
118
    """
119
      Return an instance of OperatorBase class.
Ivan Tyagov's avatar
Ivan Tyagov committed
120
    """
121
    return sql_catalog.getComparisonOperator(self.comparison_operator)
Ivan Tyagov's avatar
Ivan Tyagov committed
122

123
  def getSearchKey(self, sql_catalog):
Ivan Tyagov's avatar
Ivan Tyagov committed
124
    """
125
      Return an instance of SearchKey class.
Ivan Tyagov's avatar
Ivan Tyagov committed
126
    """
127 128 129
    if self.search_key is None:
      self.search_key = sql_catalog.getSearchKey(self.getColumn())
    return self.search_key
Ivan Tyagov's avatar
Ivan Tyagov committed
130

131 132
  def getColumn(self):
    return self.column
133

134 135
  def getValue(self):
    return self.value
Ivan Tyagov's avatar
Ivan Tyagov committed
136

137
  def __repr__(self):
138
    return '<%s %r %s %r>' % (self.__class__.__name__, self.getColumn(), self.comparison_operator, self.getValue())
139 140 141

  def setGroup(self, group):
    self.group = group
Ivan Tyagov's avatar
Ivan Tyagov committed
142

143
verifyClass(IQuery, SimpleQuery)
Ivan Tyagov's avatar
Ivan Tyagov committed
144