File indexing completed on 2024-11-10 10:15:28

0001 /* This file is part of the KDE project
0002    Copyright (C) 2003-2010 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_FIELDLIST_H
0021 #define KDB_FIELDLIST_H
0022 
0023 #include <QList>
0024 #include <QHash>
0025 
0026 #include "KDbGlobal.h"
0027 #include "KDbField.h"
0028 #include "KDbEscapedString.h"
0029 
0030 class KDbConnection;
0031 
0032 /*! Helper class that stores list of fields. */
0033 class KDB_EXPORT KDbFieldList
0034 {
0035 public:
0036     /*! Creates empty list of fields. If @a owner is true, the list will be
0037      owner of any added field, what means that these field
0038      will be removed on the list destruction. Otherwise, the list
0039      just points any field that was added.
0040      @see isOwner()
0041     */
0042     explicit KDbFieldList(bool owner = false);
0043 
0044     /*! Copy constructor.
0045      If @a deepCopyFields is true, all fields are deeply copied, else only pointer are copied.
0046      Reimplemented in KDbQuerySchema constructor. */
0047     explicit KDbFieldList(const KDbFieldList& fl, bool deepCopyFields = true);
0048 
0049     /*! Destroys the list. If the list owns fields (see constructor),
0050      these are also deleted. */
0051     virtual ~KDbFieldList();
0052 
0053     /*! @return number of fields in the list. */
0054     int fieldCount() const;
0055 
0056     /*! @return true if the list is empty. */
0057     bool isEmpty() const;
0058 
0059     /*! Adds @a field at the and of field list. */
0060     bool addField(KDbField *field);
0061 
0062     /*! Inserts @a field into a specified @a index position.
0063 
0064      @c false is returned if @a field is @c nullptr or @a index is invalid.
0065 
0066      Note: You can reimplement this method but you should still call
0067      this implementation in your subclass. */
0068     virtual bool insertField(int index, KDbField *field);
0069 
0070     /*! Removes field from the field list and deletes it. Use with care.
0071 
0072      Note: You can reimplement this method but you should still call
0073      this implementation in your subclass.
0074      @return false if this field does not belong to this list. */
0075     virtual bool removeField(KDbField *field);
0076 
0077     /*! Moves fiels @a field from its current position to new position @a newIndex.
0078      If @a newIndex value is greater than fieldCount()-1, it is appended.
0079      @return @c false if this field does not belong to this list or is @c nullptr. */
0080     virtual bool moveField(KDbField *field, int newIndex);
0081 
0082     /*! @return field id or @c nullptr if there is no such a field. */
0083     virtual KDbField* field(int id);
0084 
0085     /*! @overload KDbField* field(int id) */
0086     virtual const KDbField* field(int id) const;
0087 
0088     /*! @return field with name @a name or @c nullptr if there is no such a field. */
0089     virtual KDbField* field(const QString& name);
0090 
0091     /*! @overload . DbField* field(const QString& name) const */
0092     virtual const KDbField* field(const QString& name) const;
0093 
0094     /*! @return true if this list contains given @a field. */
0095     bool hasField(const KDbField& field) const;
0096 
0097     /*! @return first occurrence of @a field in the list
0098      or -1 if this list does not contain this field. */
0099     int indexOf(const KDbField& field) const;
0100 
0101     /*! @return list of field names for this list. */
0102     QStringList names() const;
0103 
0104     //! @return iterator for fields
0105     KDbField::ListIterator fieldsIterator() const;
0106 
0107     //! @return iterator for fields
0108     KDbField::ListIterator fieldsIteratorConstEnd() const;
0109 
0110     //! @return list of fields
0111     KDbField::List *fields();
0112 
0113     //! @overload
0114     const KDbField::List* fields() const;
0115 
0116     /*! @return list of autoincremented fields. The list is owned by this KDbFieldList object. */
0117     KDbField::List* autoIncrementFields() const;
0118 
0119     /*! @return true if fields in the list are owned by this list. */
0120     bool isOwner() const;
0121 
0122     /*! Removes all fields from the list. */
0123     virtual void clear();
0124 
0125     /*! Creates and returns a list that contain fields selected by name.
0126      At least one field (exising on this list) should be selected, otherwise 0 is
0127      returned. Returned KDbFieldList object is not owned by any parent (so you need
0128      to destroy yourself) and KDbField objects included in it are not owned by it
0129      (but still as before, by 'this' object).
0130      Returned list can be usable e.g. as argument for KDbConnection::insertRecord().
0131      0 is returned if at least one name cannot be found.
0132     */
0133     Q_REQUIRED_RESULT KDbFieldList *subList(const QString& n1, const QString& n2 = QString(),
0134                        const QString& n3 = QString(), const QString& n4 = QString(),
0135                        const QString& n5 = QString(), const QString& n6 = QString(),
0136                        const QString& n7 = QString(), const QString& n8 = QString(),
0137                        const QString& n9 = QString(), const QString& n10 = QString(),
0138                        const QString& n11 = QString(), const QString& n12 = QString(),
0139                        const QString& n13 = QString(), const QString& n14 = QString(),
0140                        const QString& n15 = QString(), const QString& n16 = QString(),
0141                        const QString& n17 = QString(), const QString& n18 = QString()
0142                       );
0143 
0144     /*! Like above, but for QStringList. */
0145     Q_REQUIRED_RESULT KDbFieldList *subList(const QStringList &list);
0146 
0147     /*! @overload subList(const QStringList&) */
0148     Q_REQUIRED_RESULT KDbFieldList *subList(const QList<QByteArray> &list);
0149 
0150     /*! Like above, but with a list of field indices */
0151     Q_REQUIRED_RESULT KDbFieldList *subList(const QList<int> &list);
0152 
0153     /*! @return a string that is a result of all field names concatenated
0154      and with @a separator. This is usable e.g. as argument like "field1,field2"
0155      for "INSERT INTO (xxx) ..". The result of this method is effectively cached,
0156      and it is invalidated when set of fields changes (e.g. using clear()
0157      or addField()).
0158 
0159      @a tableOrAlias, if provided is prepended to each field, so the resulting
0160      names will be in form tableOrAlias.fieldName. This option is used for building
0161      queries with joins, where fields have to be spicified without ambiguity.
0162      See @ref KDbConnection::selectStatement() for example use.
0163 
0164      @a escapingType can be used to alter default escaping type.
0165      If @a conn is not provided for DriverEscaping, no escaping is performed.
0166     */
0167     KDbEscapedString sqlFieldsList(KDbConnection *conn, const QString& separator = QLatin1String(","),
0168                                 const QString& tableOrAlias = QString(),
0169                                 KDb::IdentifierEscapingType escapingType = KDb::DriverEscaping) const;
0170 
0171     /*! Like above, but this is convenient static function, so you can pass any @a list here. */
0172     static KDbEscapedString sqlFieldsList(const KDbField::List& list, KDbConnection *conn,
0173                                        const QString& separator = QLatin1String(","),
0174                                        const QString& tableOrAlias = QString(),
0175                                        KDb::IdentifierEscapingType escapingType = KDb::DriverEscaping);
0176 
0177     /*! Renames field @a oldName to @a newName.
0178 
0179      @c false is returned if field with @a oldName name does not exist or field with @a newName name
0180      already exists.
0181 
0182      @note Do not use this for physical renaming columns. Use KDbAlterTableHandler instead.
0183     */
0184     bool renameField(const QString& oldName, const QString& newName);
0185 
0186     //! @overload
0187     bool renameField(KDbField *field, const QString& newName);
0188 
0189 private:
0190     class Private;
0191     Private * const d;
0192 };
0193 
0194 //! Sends information about field list  @a list to debug output @a dbg.
0195 KDB_EXPORT QDebug operator<<(QDebug dbg, const KDbFieldList& list);
0196 
0197 #endif