docs: def _prepareSQL(cls, operation="SELECT", where=None, selectfields=None, orderBy=None):
          """Return a sql for the given operation.
  
          Possible operations:
              SELECT         read data for this id
              SELECTALL    read data for all ids
              INSERT         insert data, create new id
              UPDATE         update data for this id
              DELETE         remove data for this id
  
          SQL will be built by data from _sqlFields, and will
          contain 0 or several %s for you to sprintf-format in later:
  
              SELECT --> len(cls._sqlPrimary)
              SELECTALL --> 0 %s
              INSERT --> len(cls._sqlFields) %s (including id)
              UPDATE --> len(cls._sqlFields) %s (including id)
              DELETE --> len(cls._sqlPrimary)
  
          (Note: INSERT and UPDATE will only change values in _sqlTable, so
          the actual number of fields for substitutions might be lower
          than len(cls._sqlFields) )
  
          For INSERT you should use cls._nextSequence() to retrieve
          a new 'id' number. Note that if your sequences are not named
          tablename_primarykey_seq    (ie. for table 'blapp' with primary key
          'john_id', sequence name blapp_john_id_seq) you must give the sequence
          name as an optional argument to _nextSequence)
  
          Additional note: cls._nextSequence() MUST be overloaded
          for multi _sqlPrimary classes. Return a tuple.
  
          Return values will always be tuples:
              SELECT --> (sql, fields)
              SELECTALL -> sql, fields)
              INSERT -> (sql, fields)
              UPDATE -> (sql, fields)
              DELETE -> (sql,)    -- for consistency
  
          fields will be object properties as a list, ie. the keys from
          cls._sqlFields. The purpose of this list is to give the programmer
          an idea of which order the keys are inserted in the SQL, giving
          help for retreiving (SELECT, SELECTALL) or inserting for %s
          (INSERT, DELETE).
  
          Why? Well, the keys are stored in a hash, and we cannot be sure
          about the order of hash.keys() from time to time, not even with
          the same instance.
  
          Optional where-parameter applies to SELECT, SELECTALL and DELETE.
          where should be a list or string of where clauses.
  
          """
          # Normalize parameter for later comparissions
          operation = operation.upper()
          # Convert where to a list if it is a string
          if type(where) in (types.StringType, types.UnicodeType):
              where = (where,)
          if orderBy is None:
              orderBy = cls._orderBy
  
          if operation in ('SELECT', 'SELECTALL'):
              # Get the object fields and sql fields in the same
              # order to be able to reconstruct later.
              fields = []
              sqlfields = []
              for (field, sqlfield) in cls._sqlFields.items():
                  if selectfields is None or field in selectfields:
                      fields.append(field)
                      sqlfields.append(sqlfield)
              if not fields:
                  # dirrrrrty!
                  raise """ERROR: No fields defined, cannot create SQL.
  Maybe sqlPrimary is invalid?
  Fields asked: %s
  My fields: %s""" % (selectfields, cls._sqlFields)
  
              sql = "SELECT\n    "
              sql += ', '.join(sqlfields)
              sql += "\nFROM\n    "
              tables = cls._tables.keys()
              if not tables:
                  raise "REALITY ERROR: No tables defined"
              sql += ', '.join(tables)
              tempWhere = ["%s=%s" % linkPair for linkPair in cls._sqlLinks]
              # this MUST be here.
              if operation <> 'SELECTALL':
                  for key in cls._sqlPrimary:
                      tempWhere.append(cls._sqlFields[key] + "=%s")
              if where:
                  tempWhere += where
              if(tempWhere):
                  # Make sure to use paranteses in case someone has used
                  # ORs in the WHERE-list..
                  sql += "\nWHERE\n ("
                  sql += ') AND\n    ('.join(tempWhere)
                  sql += ')'
              if operation == 'SELECTALL' and orderBy:
                  sql += '\nORDER BY\n    '
                  if type(orderBy) in (types.TupleType, types.ListType):
                      orderBy = [cls._sqlFields[x] for x in orderBy]
                      orderBy = ',\n     '.join(orderBy)
                  else:
                      orderBy = cls._sqlFields[orderBy]
                  sql += orderBy
              return (sql, fields)
  
          elif operation in ('INSERT', 'UPDATE'):
              if operation == 'UPDATE':
                  sql = 'UPDATE %s SET\n    ' % cls._sqlTable
              else:
                  sql = 'INSERT INTO %s (\n    ' % cls._sqlTable
  
              set = []
              fields = []
              sqlfields = []
              for (field, sqlfield) in cls._sqlFields.items():
                  if operation == 'UPDATE' and field in cls._sqlPrimary:
                      continue
                  if sqlfield.find(cls._sqlTable + '.') == 0:
                      # It's a local field, chop of the table part
                      sqlfield = sqlfield[len(cls._sqlTable)+1:]
                      fields.append(field)
                      sqlfields.append(sqlfield)
                      set.append(sqlfield + '=%s')
              if operation == 'UPDATE':
                  sql += ',\n    '.join(set)
                  sql += '\nWHERE\n    '
                  tempWhere = []
                  for key in cls._sqlPrimary:
                      tempWhere.append(cls._sqlFields[key] + "=%s")
                      fields.append(key)
                  sql += ' AND\n    '.join(tempWhere)
              else:
                  sql += ',\n    '.join(sqlfields)
                  sql += ')\nVALUES (\n    '
                  sql += ',\n    '.join(('%s',) * len(sqlfields))
                  sql += ')'
  
              return (sql, fields)
  
          elif operation == 'DELETE':
              sql = 'DELETE FROM ' + cls._sqlTable + ' WHERE '
              if where:
                  sql += " AND\n    ".join(where)
              else:
                  for key in cls._sqlPrimary:
                      tempWhere = []
                      for key in cls._sqlPrimary:
                          tempWhere.append(cls._sqlFields[key] + "=%s")
                  sql += ' AND\n    '.join(tempWhere)
              return (sql, )
          else:
              raise "Unknown operation", operation