ISearchKey.py 6.79 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
##############################################################################
#
# Copyright (c) 2002-2009 Nexedi SA and Contributors. All Rights Reserved.
#                    Jean-Paul Smets-Solanes <jp@nexedi.com>
#                    Vincent Pelletier <vincent@nexedi.com>
#
# 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.
#
##############################################################################

from Interface import Interface

class ISearchKey(Interface):
  """
    A SearchKey generates Query instances.
    It is responsible for parsing (or not) input value and generating the
    appropriate Query structure to match the intended search.

    This class is designed as a "singleton per column".
  """

  def __init__(column):
    """
      column (string)
        The column this SearchKey is instanciated for.
    """

  def getColumn():
    """
      Returns: string
        The column this SearchKey is instanciated for.
    """

  def buildSQLExpression(operator, value, column_map, only_group_columns, group):
    """
      This method passes on SQLExpression creation to operator, giving it the
      resolved column of this RelatedKey.

      operator (Operator)
        A comparison operator. It is used to render value, column and itself
        as valid SQL.
      value (anything)
      column_map (ColumnMap)
        The (built) column map to render our column.
      group (string)
        The group our column was part of.

      Returns: SQLExpression
        SQLExpression build by operator for current Query.
    """

  def buildSearchTextExpression(operator, value, column=None):
    """
      Render comparison using operator between value and our column as
      SearchText.

      operator (Operator)
        A comparison operator. It is used to render value as value SearchText.
      value (anything)
      column (string)
        If given, it overrides our column in SearchText rendering. This is
        useful when SearchText rendering is done for a virtual column,
        because the name of the virtual column must appear when rendered as
        SearchText.
    """

  def registerColumnMap(column_map, group, simple_query):
    """
      Register the column of this SearchKey to given column map.

      column_map (ColumnMap)
        The ColumnMap instance to register to.
      group (string)
        The group registration will be part of.
      simple_query (SimpleQuery)
        The SimpleQuery being registered.

      Returns: string
        The group assigned to caller. See ColumnMap for methods redefining
        caller's group.
    """

  def buildQuery(search_value, group=None, logical_operator=None, comparison_operator=None):
    """
      Generate queries from given search_value.
      logical_operator ('and', 'or', 'not', None)
        If no logical operator can be found in search_value, it will use given
        default operator.
      comparison_operator (string, None)
        If given, expresses the comparison between column and value.
    """

112
  def parseSearchText(value, is_column):
113 114 115 116 117 118 119 120
    """
      Parse given value to generate an Abstract Syntax Tree representing its
      logical structure, or None if there is no obvious structure in given
      value.
      See SearchText for parsing code.

      value (string)
        The string to parse.
121 122 123 124 125 126
      is_column (function taking one parameter)
        This function will be called with a single parameter, being a column
        name candidate.
        It must return a boolean:
        True: value is a valid column name
        False: value is not a valid column name
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

      Returns: (None, AbstratSyntaxNode)
        AbstratSyntaxNode complies with the IAbstractSyntaxNode interface.
    """

class IRelatedKey(ISearchKey):
  """
    A RelatedKey is a special variation of a SearchKey.
    Only a small set of methods differ. They are defined in this class.
  """

  def registerColumnMap(column_map, table_alias_list=None):
    """
      This is slightly different for regular registerColumnMap in that it must
      register multiple tables (and not columns, since RelatedKeys do not
      provide this information).
      Also, it must register namely "catalog" table and resolve its alias,
      angain since it's hardcoded in RelatedKey ZSQLMethods and not provided
      by their definitions.

      column_map (ColumnMap)

      Deprecated:
        table_alias_list (None, list of 2-tuples of strings)
          This list must have the exact same length as the list of tables 
    """

  def buildSQLExpression(sql_catalog, column_map, only_group_columns, group):
    """
      operator and value parameters are useless, since this type of SearhKey
      does not compare a value to any column, but uses a ZSQLMethod.
      To reach that ZSQLMethod, it also required a new sql_catalog parameter.

      sql_catalog (SQLCatalog)
        Used to retrieve related key's ZSQLMethod.
    """

164
  def buildQuery(sql_catalog, related_key_definition, search_value=None):
165 166 167 168 169 170 171 172 173 174 175 176 177 178 179
    """
      group is useless here, since group is determined by ColumnMap at
      registration time. search_value becomes optional.

      sql_catalog (SQLCatalog)
        Used to retrieve real column's SearchKey. For example, a RelatedKey
        used to compare with a "title" column will retrieve title's default
        SearchKey (which should be a KeywordKey).
      related_key_definition (string)
        Describes parameters of a RelatedKey. It is composed of 3 mains parts,
        separated by '/':
        - a list of table names
          Table names are separated by ','
        - a column name
        - the name of the related key ZSQLMethod
180
      search_value (None or Query)
181 182
        If given, a condition on real column will be generated.
        Otherwise, only the SQL required to reach that column will be
Vincent Pelletier's avatar
Vincent Pelletier committed
183
        generated. This is useful when sorting on a virtual column, for
184 185 186
        example.
    """