File indexing completed on 2024-12-08 10:15:24

0001 /* This file is part of the KDE project
0002    Copyright (C) 2003-2018 Jarosław Staniek <staniek@kde.org>
0003 
0004    This library is free software; you can redistribute it and/or
0005    modify it under the terms of the GNU Library General Public
0006    License as published by the Free Software Foundation; either
0007    version 2 of the License, or (at your option) any later version.
0008 
0009    This library is distributed in the hope that it will be useful,
0010    but WITHOUT ANY WARRANTY; without even the implied warranty of
0011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0012    Library General Public License for more details.
0013 
0014    You should have received a copy of the GNU Library General Public License
0015    along with this library; see the file COPYING.LIB.  If not, write to
0016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0017  * Boston, MA 02110-1301, USA.
0018 */
0019 
0020 #ifndef KDB_ORDERBYCOLUMN_H
0021 #define KDB_ORDERBYCOLUMN_H
0022 
0023 #include "KDbEscapedString.h"
0024 #include "KDbGlobal.h"
0025 
0026 class KDbConnection;
0027 class KDbField;
0028 class KDbQueryColumnInfo;
0029 class KDbQuerySchema;
0030 
0031 //! @short KDbOrderByColumn provides information about a single query column used for sorting
0032 /*! The column can be expression or table field. */
0033 class KDB_EXPORT KDbOrderByColumn
0034 {
0035 public:
0036     //! Column sort order
0037     //! @since 3.1
0038     enum class SortOrder {
0039         Ascending = Qt::AscendingOrder,
0040         Descending = Qt::DescendingOrder
0041     };
0042 
0043     //! Creates an empty information about a single query column.
0044     KDbOrderByColumn();
0045 
0046     //! Creates a copy of the @a other
0047     //! @since 3.1
0048     KDbOrderByColumn(const KDbOrderByColumn &other);
0049 
0050     //! Creates information about a single query column @a column used for sorting.
0051     explicit KDbOrderByColumn(KDbQueryColumnInfo* column,
0052                               SortOrder order = SortOrder::Ascending, int pos = -1);
0053 
0054     //! Like above but used when the field @a field is not present on the list of columns.
0055     //! (e.g. SELECT a FROM t ORDER BY b; where T is a table with fields (a,b)).
0056     explicit KDbOrderByColumn(KDbField* field, SortOrder order = SortOrder::Ascending);
0057 
0058     ~KDbOrderByColumn();
0059 
0060     /*! @return copy of this KDbOrderByColumn object.
0061      @a fromQuery and @a toQuery is needed if column() is assigned to this info.
0062      Then, column info within @a toQuery will be assigned to the new KDbOrderByColumn object,
0063      corresponding to column() from "this" KDbOrderByColumn object. */
0064     Q_REQUIRED_RESULT KDbOrderByColumn *copy(KDbConnection *conn, KDbQuerySchema *fromQuery,
0065                                              KDbQuerySchema *toQuery) const;
0066 
0067     //! A column to sort.
0068     KDbQueryColumnInfo* column() const;
0069 
0070     /*! A helper for column() that allows you to know that sorting column
0071      was defined by providing its position. -1 by default.
0072      Example query: SELECT a, b FROM T ORDER BY 2 */
0073     int position() const;
0074 
0075     //! A field to sort, used only in case when the second constructor was used.
0076     KDbField *field() const;
0077 
0078     //! @return sort order for the column
0079     KDbOrderByColumn::SortOrder sortOrder() const;
0080 
0081     //! Assigns @a other to this object returns a reference to this object.
0082     //! @since 3.1
0083     KDbOrderByColumn& operator=(const KDbOrderByColumn &other);
0084 
0085     //! @return true if this column is the same as @a col
0086     bool operator==(const KDbOrderByColumn& col) const;
0087 
0088     //! @return @c true if this object is not equal to @a other; otherwise returns @c false.
0089     //! @since 3.1
0090     inline bool operator!=(const KDbOrderByColumn &other) const { return !operator==(other); }
0091 
0092     /** Return an SQL string like "name ASC" or "2 DESC" usable for building an SQL statement
0093      *
0094      * If @a includeTableNames is @c true fields that are related to a table are
0095      * printed as "tablename.fieldname".
0096      *
0097      * @a escapingType can be used to alter default escaping type.
0098      * If @a conn is not provided for DriverEscaping, no escaping is performed.
0099      * If @a query is provided, it can be used to obtain alias information.
0100      *
0101      * @since 3.2
0102      */
0103     KDbEscapedString toSqlString(bool includeTableName,
0104                                  KDbConnection *conn, KDbQuerySchema *query,
0105                                  KDb::IdentifierEscapingType escapingType = KDb::DriverEscaping) const;
0106 
0107     /*! @overload
0108 
0109      @deprecated since 3.2, use overload that also takes query schema
0110     */
0111     KDB_DEPRECATED KDbEscapedString toSqlString(bool includeTableName = true,
0112                                  KDbConnection *conn = nullptr,
0113                                  KDb::IdentifierEscapingType escapingType = KDb::DriverEscaping) const;
0114 
0115     //! Converts @a order to Qt::SortOrder type
0116     inline static Qt::SortOrder toQt(SortOrder order) { return static_cast<Qt::SortOrder>(order); }
0117 
0118     //! Converts @a order to SortOrder type
0119     inline static SortOrder fromQt(Qt::SortOrder order) { return static_cast<SortOrder>(order); }
0120 
0121 private:
0122     class Private;
0123     Private * const d;
0124 };
0125 
0126 //! @short KDbOrderByColumnList provides list of sorted columns for a query schema
0127 class KDB_EXPORT KDbOrderByColumnList
0128 {
0129 public:
0130     /*! Constructs empty list of ordered columns. */
0131     KDbOrderByColumnList();
0132 
0133     /*! A copy constructor. */
0134     KDbOrderByColumnList(const KDbOrderByColumnList& other, KDbConnection *conn,
0135                          KDbQuerySchema* fromQuery, KDbQuerySchema* toQuery);
0136 
0137     ~KDbOrderByColumnList();
0138 
0139     //! @return @c true if this object is equal to @a other; otherwise returns @c false.
0140     //! @since 3.1
0141     bool operator==(const KDbOrderByColumnList &other) const;
0142 
0143     //! @return @c true if this object is not equal to @a other; otherwise returns @c false.
0144     //! @since 3.1
0145     inline bool operator!=(const KDbOrderByColumnList &other) const { return !operator==(other); }
0146 
0147     //! Returns column with given index.
0148     //! @since 3.1
0149     const KDbOrderByColumn* value(int index) const;
0150 
0151     //! @overload
0152     KDbOrderByColumn* value(int index);
0153 
0154     /*! Appends multiple fields for sorting. @a querySchema
0155      is used to find appropriate field or alias name.
0156      @return false if there is at least one name for which a field or alias name does not exist
0157      (all the newly appended fields are removed in this case)
0158      Returns @c false if @a querySchema is @c nullptr. */
0159     bool appendFields(KDbConnection *conn, KDbQuerySchema* querySchema,
0160                       const QString& field1, KDbOrderByColumn::SortOrder order1 = KDbOrderByColumn::SortOrder::Ascending,
0161                       const QString& field2 = QString(), KDbOrderByColumn::SortOrder order2 = KDbOrderByColumn::SortOrder::Ascending,
0162                       const QString& field3 = QString(), KDbOrderByColumn::SortOrder order3 = KDbOrderByColumn::SortOrder::Ascending,
0163                       const QString& field4 = QString(), KDbOrderByColumn::SortOrder order4 = KDbOrderByColumn::SortOrder::Ascending,
0164                       const QString& field5 = QString(), KDbOrderByColumn::SortOrder order5 = KDbOrderByColumn::SortOrder::Ascending);
0165 
0166     /*! Appends column @a columnInfo.
0167      Does nothing if @a columnInfo is @c nullptr. */
0168     void appendColumn(KDbQueryColumnInfo* columnInfo,
0169                       KDbOrderByColumn::SortOrder order = KDbOrderByColumn::SortOrder::Ascending);
0170 
0171     /*! Appends a field @a field.
0172      Read documentation of @ref KDbOrderByColumn(KDbField* field, SortOrder order)
0173      for more info.
0174      Does nothing if @a field is @c nullptr. */
0175     void appendField(KDbField* field,
0176                      KDbOrderByColumn::SortOrder order = KDbOrderByColumn::SortOrder::Ascending);
0177 
0178     /*! Appends field with a name @a field.
0179      @return @c true on successful appending, and @c false if there is no such field or alias
0180      name in the @a querySchema.
0181      Returns @c false if @a querySchema is @c nullptr. */
0182     bool appendField(KDbConnection *conn, KDbQuerySchema* querySchema, const QString& fieldName,
0183                      KDbOrderByColumn::SortOrder order = KDbOrderByColumn::SortOrder::Ascending);
0184 
0185     /*! Appends a column that is at position @a pos (counted from 0).
0186      @return true on successful adding and false if there is no such position @a pos.
0187      Returns @c false if @a querySchema is @c nullptr. */
0188     bool appendColumn(KDbConnection *conn, KDbQuerySchema* querySchema,
0189                       KDbOrderByColumn::SortOrder order = KDbOrderByColumn::SortOrder::Ascending,
0190                       int pos = -1);
0191 
0192     /*! @return true if the list is empty. */
0193     bool isEmpty() const;
0194 
0195     /*! @return number of elements of the list. */
0196     int count() const;
0197 
0198     /*! Removes all elements from the list (deletes them). */
0199     void clear();
0200 
0201     /*! Returns an STL-style iterator pointing to the first column in the list. */
0202     QList<KDbOrderByColumn*>::Iterator begin();
0203 
0204     /*! Returns an STL-style iterator pointing to the imaginary item after the last column
0205      * in the list.
0206      */
0207     QList<KDbOrderByColumn*>::Iterator end();
0208 
0209     /*! Returns an const STL-style iterator pointing to the first column in the list. */
0210     QList<KDbOrderByColumn*>::ConstIterator constBegin() const;
0211 
0212     /*! Returns a const STL-style iterator pointing to the imaginary item after the last column
0213      * in the list.
0214      */
0215     QList<KDbOrderByColumn*>::ConstIterator constEnd() const;
0216 
0217     /** Return an SQL string like "name ASC, 2 DESC" usable for building an SQL statement
0218      *
0219      * If @a includeTableNames is @c true (the default) fields that are related to a table are
0220      * printed as "tablename.fieldname".
0221      *
0222      * @a escapingType can be used to alter default escaping type.
0223      * If @a conn is not provided for DriverEscaping, no escaping is performed.
0224      * If @a query is provided, it can be used to obtain alias information.
0225      *
0226      * @since 3.2
0227      */
0228     KDbEscapedString toSqlString(bool includeTableNames,
0229                                  KDbConnection *conn, KDbQuerySchema *query,
0230                                  KDb::IdentifierEscapingType escapingType = KDb::DriverEscaping) const;
0231 
0232     /*! @overload
0233 
0234      @deprecated since 3.2, use overload that also takes query schema
0235     */
0236     KDB_DEPRECATED KDbEscapedString toSqlString(bool includeTableNames = true,
0237                                  KDbConnection *conn = nullptr,
0238                                  KDb::IdentifierEscapingType escapingType = KDb::DriverEscaping) const;
0239 
0240 private:
0241     class Private;
0242     Private * const d;
0243     Q_DISABLE_COPY(KDbOrderByColumnList)
0244 };
0245 
0246 //! Sends order-by-column information @a order to debug output @a dbg.
0247 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbOrderByColumn& order);
0248 
0249 //! Sends order-by-column-list information @a list to debug output @a dbg.
0250 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbOrderByColumnList& list);
0251 
0252 #endif