|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2003-2004 Jaroslaw Staniek <js@iidea.pl>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library 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
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef KEXIDB_RELATIONSHIP_H
|
|
|
|
#define KEXIDB_RELATIONSHIP_H
|
|
|
|
|
|
|
|
#include <kexidb/field.h>
|
|
|
|
|
|
|
|
namespace KexiDB {
|
|
|
|
|
|
|
|
/*! KexiDB::Relationship provides information about one-to-many relationship between two tables.
|
|
|
|
Relationship is defined by a pair of (potentially multi-field) indices:
|
|
|
|
- "one" or "master" side: unique key
|
|
|
|
- "many" or "details" side: referenced foreign key
|
|
|
|
<pre>
|
|
|
|
[unique key, master] ----< [foreign key, details]
|
|
|
|
</pre>
|
|
|
|
|
|
|
|
In this documentation, we will call table that owns fields of "one" side as
|
|
|
|
"master side of the relationship", and the table that owns foreign key fields of
|
|
|
|
as "details side of the relationship".
|
|
|
|
Use masterTable(), and detailsTable() to get one-side table and many-side table, respectively.
|
|
|
|
|
|
|
|
Note: some engines (e.g. MySQL with InnoDB) requires that indices at both sides
|
|
|
|
have to be explicitly created.
|
|
|
|
|
|
|
|
\todo (js) It is planned that this will be handled by KexiDB internally and transparently.
|
|
|
|
|
|
|
|
Each (of the two) key can be defined (just like index) as list of fields owned by one table.
|
|
|
|
Indeed, relationship info can retrieved from Relationship object in two ways:
|
|
|
|
-# pair of indices; use masterIndex(), detailsIndex() for that
|
|
|
|
-# ordered list of field pairs (<master-side-field, details-side-field>); use fieldPairs() for that
|
|
|
|
|
|
|
|
No assigned objects (like fields, indices) are owned by Relationship object. The exception is that
|
|
|
|
list of field-pairs is internally created (on demand) and owned.
|
|
|
|
|
|
|
|
Relationship object is owned by IndexSchema object (the one that is defined at master-side of the
|
|
|
|
relationship).
|
|
|
|
Note also that IndexSchema objects are owned by appropriate tables, so thus
|
|
|
|
there is implicit ownership between TableSchema and Relationship.
|
|
|
|
|
|
|
|
If Relationship object is not attached to IndexSchema object,
|
|
|
|
you should care about destroying it by hand.
|
|
|
|
|
|
|
|
Example:
|
|
|
|
<pre>
|
|
|
|
----------
|
|
|
|
---r1--<| |
|
|
|
|
| Table A [uk]----r3---<
|
|
|
|
---r2--<| |
|
|
|
|
----------
|
|
|
|
</pre>
|
|
|
|
Table A has two relationships (r1, r2) at details side and one (r3) at master side.
|
|
|
|
[uk] stands for unique key.
|
|
|
|
*/
|
|
|
|
|
|
|
|
class IndexSchema;
|
|
|
|
class TableSchema;
|
|
|
|
class QuerySchema;
|
|
|
|
|
|
|
|
class KEXI_DB_EXPORT Relationship
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
typedef TQPtrList<Relationship> List;
|
|
|
|
typedef TQPtrListIterator<Relationship> ListIterator;
|
|
|
|
|
|
|
|
/*! Creates uninitialized Relationship object.
|
|
|
|
setIndices() will be required to call.
|
|
|
|
*/
|
|
|
|
Relationship();
|
|
|
|
|
|
|
|
/*! Creates Relationship object and initialises it just by
|
|
|
|
calling setIndices(). If setIndices() failed, object is still uninitialised.
|
|
|
|
*/
|
|
|
|
Relationship(IndexSchema* masterIndex, IndexSchema* detailsIndex);
|
|
|
|
|
|
|
|
virtual ~Relationship();
|
|
|
|
|
|
|
|
/*! \return index defining master side of this relationship
|
|
|
|
or null if there is no information defined. */
|
|
|
|
IndexSchema* masterIndex() const { return m_masterIndex; }
|
|
|
|
|
|
|
|
/*! \return index defining referenced side of this relationship.
|
|
|
|
or null if there is no information defined. */
|
|
|
|
IndexSchema* detailsIndex() const { return m_detailsIndex; }
|
|
|
|
|
|
|
|
/*! \return ordered list of field pairs -- alternative form
|
|
|
|
for representation of relationship or null if there is no information defined.
|
|
|
|
Each pair has a form of <master-side-field, details-side-field>. */
|
|
|
|
Field::PairList* fieldPairs() { return &m_pairs; }
|
|
|
|
|
|
|
|
bool isEmpty() const { return m_pairs.isEmpty(); }
|
|
|
|
|
|
|
|
/*! \return table assigned at "master / one" side of this relationship.
|
|
|
|
or null if there is no information defined. */
|
|
|
|
TableSchema* masterTable() const;
|
|
|
|
|
|
|
|
/*! \return table assigned at "details / many / foreign" side of this relationship.
|
|
|
|
or null if there is no information defined. */
|
|
|
|
TableSchema* detailsTable() const;
|
|
|
|
|
|
|
|
/*! Sets \a masterIndex and \a detailsIndex indices for this relationship.
|
|
|
|
This also sets information about tables for master- and details- sides.
|
|
|
|
Notes:
|
|
|
|
- both indices must contain the same number of fields
|
|
|
|
- both indices must not be owned by the same table, and table (owner) must be not null.
|
|
|
|
- corresponding field types must be the same
|
|
|
|
- corresponding field types' signedness must be the same
|
|
|
|
If above rules are not fulfilled, information about this relationship is cleared.
|
|
|
|
On success, this Relationship object is detached from previous IndexSchema objects that were
|
|
|
|
assigned before, and new are attached.
|
|
|
|
*/
|
|
|
|
void setIndices(IndexSchema* masterIndex, IndexSchema* detailsIndex);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
Relationship( QuerySchema *query, Field *field1, Field *field2 );
|
|
|
|
|
|
|
|
void createIndices( QuerySchema *query, Field *field1, Field *field2 );
|
|
|
|
|
|
|
|
/*! Internal version of setIndices(). \a ownedByMaster parameter is passed
|
|
|
|
to IndexSchema::attachRelationship() */
|
|
|
|
void setIndices(IndexSchema* masterIndex, IndexSchema* detailsIndex, bool ownedByMaster);
|
|
|
|
|
|
|
|
IndexSchema *m_masterIndex;
|
|
|
|
IndexSchema *m_detailsIndex;
|
|
|
|
|
|
|
|
Field::PairList m_pairs;
|
|
|
|
|
|
|
|
bool m_masterIndexOwned : 1;
|
|
|
|
bool m_detailsIndexOwned : 1;
|
|
|
|
|
|
|
|
friend class Connection;
|
|
|
|
friend class TableSchema;
|
|
|
|
friend class QuerySchema;
|
|
|
|
friend class IndexSchema;
|
|
|
|
};
|
|
|
|
|
|
|
|
} //namespace KexiDB
|
|
|
|
|
|
|
|
#endif
|