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

0001 /* This file is part of the KDE project
0002    Copyright (C) 2003-2017 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_RELATIONSHIP_H
0021 #define KDB_RELATIONSHIP_H
0022 
0023 #include "KDbField.h"
0024 
0025 /*! KDbRelationship provides information about one-to-many relationship between two tables.
0026  Relationship is defined by a pair of (potentially multi-field) indices:
0027  - "one" or "master" side: unique key
0028  - "many" or "details" side: referenced foreign key
0029  <pre>
0030  [unique key, master] ----< [foreign key, details]
0031  </pre>
0032 
0033  In this documentation, we will call table that owns fields of "one" side as
0034  "master side of the relationship", and the table that owns foreign key fields of
0035  as "details side of the relationship".
0036  Use masterTable(), and detailsTable() to get one-side table and many-side table, respectively.
0037 
0038  Note: some engines (e.g. MySQL with InnoDB) requires that indices at both sides
0039  have to be explicitly created.
0040 
0041  @todo (js) It is planned that this will be handled by KDb internally and transparently.
0042 
0043  Each (of the two) key can be defined (just like index) as list of fields owned by one table.
0044  Indeed, relationship info can retrieved from KDbRelationship object in two ways:
0045  -# pair of indices; use masterIndex(), detailsIndex() for that
0046  -# ordered list of field pairs (<master-side-field, details-side-field>); use fieldPairs() for that
0047 
0048  No assigned objects (like fields, indices) are owned by KDbRelationship object. The exception is that
0049  list of field-pairs is internally created (on demand) and owned.
0050 
0051  KDbRelationship object is owned by KDbIndexSchema object (the one that is defined at master-side of the
0052  relationship).
0053  Note also that KDbIndexSchema objects are owned by appropriate tables, so thus
0054  there is implicit ownership between KDbTableSchema and KDbRelationship.
0055 
0056  If KDbRelationship object is not attached to KDbIndexSchema object,
0057  you should care about destroying it by hand.
0058 
0059   Example:
0060   <pre>
0061             ----------
0062    ---r1--<|          |
0063            | Table A [uk]----r3---<
0064    ---r2--<|          |
0065             ----------
0066   </pre>
0067   Table A has two relationships (r1, r2) at details side and one (r3) at master side.
0068   [uk] stands for unique key.
0069 */
0070 
0071 class KDbIndexSchema;
0072 class KDbTableSchema;
0073 class KDbQuerySchema;
0074 
0075 class KDB_EXPORT KDbRelationship
0076 {
0077 public:
0078     typedef QList<KDbRelationship*> List;
0079     typedef QList<KDbRelationship*>::ConstIterator ListIterator;
0080 
0081     /**
0082      * @brief Creates a new uninitialized KDbRelationship object
0083      */
0084     KDbRelationship();
0085 
0086     /**
0087      * @brief Creates a new KDbRelationship object and initialises it using setIndices()
0088      *
0089      * If setIndices() failed, object is still uninitialised. Check this using isEmpty().
0090      */
0091     KDbRelationship(KDbIndexSchema* masterIndex, KDbIndexSchema* detailsIndex);
0092 
0093     virtual ~KDbRelationship();
0094 
0095     //! Assigns @a other to this object returns a reference to this object.
0096     //! @since 3.1
0097     KDbRelationship& operator=(KDbRelationship &other);
0098 
0099     //! @return true if this relationship is the same as @a other
0100     //! Relationships are equal if they have the same details and master indices are equal
0101     //! @since 3.1
0102     bool operator==(const KDbRelationship& other) const;
0103 
0104     //! @return @c true if this object is not equal to @a other; otherwise returns @c false.
0105     //! @since 3.1
0106     inline bool operator!=(const KDbRelationship &other) const { return !operator==(other); }
0107 
0108     /*! @return index defining master side of this relationship
0109      or @c nullptr if there is no information defined. */
0110     KDbIndexSchema* masterIndex();
0111 
0112     //! @overload
0113     const KDbIndexSchema* masterIndex() const;
0114 
0115     /*! @return index defining referenced side of this relationship.
0116      or @c nullptr if there is no information defined. */
0117     KDbIndexSchema* detailsIndex();
0118 
0119     //! @overload
0120     const KDbIndexSchema* detailsIndex() const;
0121 
0122     /**
0123      * Returns ordered list of field pairs, alternative representation of relationship
0124      *
0125      * @c nullptr is returned if there is no information defined.
0126      * Each pair has a form of <master-side-field, details-side-field>.
0127      */
0128     KDbField::PairList* fieldPairs();
0129 
0130     //! @overload
0131     const KDbField::PairList* fieldPairs() const;
0132 
0133     //! @return true if there are no master-details pairs in this relationship object
0134     //! @see fieldPairs()
0135     bool isEmpty() const;
0136 
0137     /*! @return table assigned at "master / one" side of this relationship.
0138      or @c nullptr if there is no information defined. */
0139     KDbTableSchema* masterTable();
0140 
0141     //! @overload
0142     const KDbTableSchema* masterTable() const;
0143 
0144     /*! @return table assigned at "details / many / foreign" side of this relationship.
0145      or @c nullptr if there is no information defined. */
0146     KDbTableSchema* detailsTable();
0147 
0148     //! @overload
0149     const KDbTableSchema* detailsTable() const;
0150 
0151     /*! Sets @a masterIndex and @a detailsIndex indices for this relationship.
0152      This also sets information about tables for master- and details- sides.
0153      Notes:
0154      - both indices must contain the same number of fields
0155      - both indices must not be owned by the same table, and table (owner) must be not null.
0156      - corresponding field types must be the same
0157      - corresponding field types' signedness must be the same
0158      If above rules are not fulfilled, information about this relationship is cleared.
0159      On success, this KDbRelationship object is detached from previous KDbIndexSchema objects that were
0160      assigned before, and new are attached.
0161      */
0162     bool setIndices(KDbIndexSchema* masterIndex, KDbIndexSchema* detailsIndex);
0163 
0164 protected:
0165     KDbRelationship(KDbQuerySchema *query, KDbField *field1, KDbField *field2);
0166 
0167     friend class KDbConnection;
0168     friend class KDbTableSchema;
0169     friend class KDbQuerySchema;
0170     friend class KDbIndexSchema;
0171 
0172 private:
0173     class Private;
0174     Private * const d;
0175 };
0176 
0177 #endif